- official_formulas, official_formula_ingredients 테이블 스키마 추가 - 100처방 마스터데이터 등록 가이드 (Agent용 절차/규칙/코드 템플릿) - 한약국 첩제 vs OTC 상담 가이드 - 한약국 AI데이터 기본이해 문서 - 가미패독산 업셀링 칼럼, 입고장 수정기능 구현 문서 - CLAUDE.md에 참고 문서 경로 추가 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
35 KiB
│ Plan to implement │ │ │ │ 입고장 수정 기능 구현 계획 │ │ │ │ Context │ │ │ │ Excel로 입고 시 유효기한, 로트번호 등을 입력할 수 없음. 기존 입고장을 수동입고 모달에 불러와 부족한 정보를 채워넣는 수정 기능이 필요함. │ │ │ │ 수정 파일 (2개) │ │ │ │ 1. /root/kdrug/app.py — 백엔드 (기존 PUT API 확장) │ │ │ │ 기존 PUT /api/purchase-receipts/<receipt_id>/lines/<line_id> 확장 (line 1171) │ │ - lot_number, expiry_date 필드를 purchase_receipt_lines UPDATE에 추가 │ │ - inventory_lots에도 lot_number, expiry_date UPDATE 추가 │ │ - 수량/단가 변경 없이 유효기한/로트번호만 추가하는 경우도 처리 가능하게 │ │ │ │ 새 엔드포인트: PUT /api/purchase-receipts/<receipt_id> │ │ - 입고장 헤더(receipt_date, supplier_id, notes) 수정 │ │ - 전체 라인을 일괄 수정하는 것은 복잡하므로, 헤더만 처리 │ │ - 라인 수정은 기존 라인별 PUT API를 활용 │ │ │ │ → 대안: 전체 일괄 수정 엔드포인트 PUT /api/purchase-receipts/<receipt_id>/bulk │ │ - 모달에서 전체 라인을 한번에 보내서 일괄 업데이트 │ │ - 각 라인의 line_id + 수정 필드를 배열로 받음 │ │ - 헤더(notes) + 라인(origin_country, lot_number, expiry_date, quantity_g, unit_price_per_g) 일괄 처리 │ │ - 이 방식 채택 — 모달에서 "저장" 한 번으로 끝나므로 UX가 좋음 │ │ │ │ 2. /root/kdrug/static/app.js — 프론트엔드 │ │ │ │ A. 입고장 목록에 "수정" 버튼 추가 (loadPurchaseReceipts 함수 내) │ │ - 기존 상세 버튼 옆에 수정 버튼 추가 │ │ - 클릭 시 editReceipt(receiptId) 호출 │ │ │ │ B. editReceipt(receiptId) 함수 추가 │ │ - GET /api/purchase-receipts/<receipt_id> 로 기존 데이터 로드 │ │ - 수동입고 모달을 "수정 모드"로 열기: │ │ - 모달 제목: "입고장 수정" │ │ - 입고일, 도매상: 기존 값 세팅 (도매상은 변경 불가 — 재고 참조 때문) │ │ - 비고: 기존 값 세팅 │ │ - 품목 테이블: 기존 라인 데이터로 행 채우기 (약재 select에 기존 값 세팅, 수량/단가/원산지/로트번호/유효기한 채우기) │ │ - 약재 select: 수정 모드에서는 disabled (약재 변경은 위험) │ │ - "품목 추가" 버튼, "삭제" 버튼: 수정 모드에서는 숨김 (라인 추가/삭제는 불가) │ │ - 저장 버튼 텍스트: "수정 저장" │ │ │ │ C. 저장 로직 분기 │ │ - 모달에 data-edit-mode, data-receipt-id 속성 관리 │ │ - 저장 시: edit mode이면 PUT /api/purchase-receipts/<receipt_id>/bulk 호출 │ │ - 성공 시 모달 닫기 + 입고장 목록 새로고침 │ │ │ │ 데이터 흐름 │ │ │ │ [입고장 목록 "수정" 클릭] → GET /api/purchase-receipts/:id │ │ → 수동입고 모달에 기존 데이터 로드 (수정 모드) │ │ → 유효기한/로트번호/원산지 등 수정 │ │ → [수정 저장] → PUT /api/purchase-receipts/:id/bulk │ │ → purchase_receipt_lines UPDATE (각 라인) │ │ → inventory_lots UPDATE (lot_number, expiry_date) │ │ → purchase_receipts UPDATE (notes, total_amount) │ │ │ │ 주의사항 │ │ │ │ - 약재 변경 불가 (재고 추적 무결성) │ │ - 이미 사용된 재고의 수량 변경은 기존 validation 유지 │ │ - 라인 추가/삭제는 지원하지 않음 (수정만) │ │ │ │ 검증 │ │ │ │ 1. Excel로 입고한 입고장에서 "수정" 클릭 │ │ 2. 모달에 기존 데이터가 채워져 있는지 확인 │ │ 3. 유효기한, 로트번호 입력 후 저장 │ │ 4. 상세보기에서 변경 확인 │ │ 5. 재고 상세에서 lot_number, expiry_date 표시 확인
데이터 흐름상 이게 어디 어디 테이블에 업데이트가 되는거야?
● bulk 수정 API의 데이터 흐름을 정리하면:
PUT /api/purchase-receipts/<receipt_id>/bulk
업데이트되는 테이블 3개 (+ 조건부 1개)
┌──────┬────────────────────────┬───────────────────────────────────────────────────────────────────────────────────────────────┬──────────────────────┐ │ 순서 │ 테이블 │ 업데이트 필드 │ 조건 │ ├──────┼────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────┤ │ 1 │ purchase_receipt_lines │ quantity_g, unit_price_per_g, origin_country, lot_number, expiry_date, line_total │ 항상 (변경된 필드만) │ ├──────┼────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────┤ │ 2 │ inventory_lots │ lot_number, expiry_date, origin_country, unit_price_per_g, quantity_received, quantity_onhand │ lot_id가 있을 때 │ ├──────┼────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────┤ │ 3 │ stock_ledger │ INSERT (ADJUST 이벤트) │ 수량 변경 시에만 │ ├──────┼────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────┼──────────────────────┤ │ 4 │ purchase_receipts │ notes, total_amount, updated_at │ 항상 (헤더) │ └──────┴────────────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────┴──────────────────────┘
흐름도
모달에서 "수정 저장" 클릭 │ ├─ 각 라인 반복 ──┐ │ ├─① purchase_receipt_lines UPDATE (수량/단가/원산지/로트/유효기한) │ ├─② inventory_lots UPDATE (로트번호/유효기한/원산지/단가/수량) │ └─③ stock_ledger INSERT (수량 변경 시만) │ └─④ purchase_receipts UPDATE (비고, 총액 재계산)
즉 purchase_receipt_lines와 inventory_lots 양쪽 다 같은 값을 저장합니다. 이전에 유효기한이 안 보였던 이유가 inventory_lots에만 저장하고 purchase_receipt_lines에는 안 넣어서 조회 시 충돌이 났던 거였기 때문에, 이제는 양쪽 모두 업데이트합니다.
정리하면:
purchase_receipt_lines — 입고 전표 (장부용)
"이 입고장에 뭘 얼마나 샀는가"를 기록하는 구매 기록 테이블
┌─────────────────────┬──────────────────────────────────────────────────────────┐
│ 용도 │ 설명 │
├─────────────────────┼──────────────────────────────────────────────────────────┤
│ 입고장 상세 조회 │ 입고장 클릭 시 "무슨 약재를 몇g, g당 얼마에 샀는지" 표시 │
├─────────────────────┼──────────────────────────────────────────────────────────┤
│ 입고장 삭제 시 참조 │ 삭제 가능 여부 판단의 기준 │
├─────────────────────┼──────────────────────────────────────────────────────────┤
│ 금액 집계 │ line_total 합산 → 입고장 total_amount │
└─────────────────────┴──────────────────────────────────────────────────────────┘
→ 입고 이후에는 거의 안 씀. 입고장 조회/출력용 원본 기록.
inventory_lots — 재고 로트 (실물 추적용)
"실제 재고가 지금 얼마나 남아있는가"를 추적하는 핵심 재고 테이블
┌──────────────────────────┬─────────────────────────────────────────────────────┐ │ 용도 │ 설명 │ ├──────────────────────────┼─────────────────────────────────────────────────────┤ │ 조제 시 차감 │ quantity_onhand 에서 사용량 차감, FIFO 순서로 소진 │ ├──────────────────────────┼─────────────────────────────────────────────────────┤ │ 재고 현황 조회 │ 약재별 현재 재고량, 로트별 잔량 표시 │ ├──────────────────────────┼─────────────────────────────────────────────────────┤ │ 재고 조정 │ 실사 후 수량 보정 │ ├──────────────────────────┼─────────────────────────────────────────────────────┤ │ 재고 원장 (stock_ledger) │ 입고/출고/조정 이력의 참조 대상 │ ├──────────────────────────┼─────────────────────────────────────────────────────┤ │ 로트 추적 │ lot_number, expiry_date, origin_country로 품질 관리 │ ├──────────────────────────┼─────────────────────────────────────────────────────┤ │ 원가 계산 │ unit_price_per_g로 조제 원가 산출 │ └──────────────────────────┴─────────────────────────────────────────────────────┘
→ 입고 이후 모든 비즈니스 로직이 이 테이블을 참조.
한 줄 요약
purchase_receipt_lines = "이걸 샀다" (구매 기록, 장부) inventory_lots = "이게 남아있다" (재고 실물, 운영)
둘 다 같은 입고 건에서 1:1로 생성되지만, 이후에 실제로 조제/재고조정/원장에서 사용하는 건 inventory_lots만입니다. 그래서 lot_number나 expiry_date도 inventory_lots에 저장된 값이 중요하고, bulk 수정 시 양쪽 다 업데이트하도록 해둔 겁니다.
✻ Churned for 1m 0s
──────────────────────────────────────────────────────────────────────────────