From 11ca86ca41a7624997950f63b161d5c1e5a2c904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=9C=EA=B3=A8=EC=95=BD=EC=82=AC?= Date: Sun, 15 Feb 2026 11:25:58 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20=EC=9E=85=EA=B3=A0=EC=9E=A5=20=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EC=9E=90=EB=8F=99=20=EC=83=9D=EC=84=B1=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 개선사항 - 입고장 번호 형식: PR-YYYYMMDD-XXXX - 기존 데이터에 입고장 번호 부여 (update_receipt_numbers.py) - Excel 업로드시 자동으로 입고장 번호 생성 - 재고 원장 참고번호 개선 - 입고: 입고장 번호 (PR-20260211-0001) - 출고: 처방전 번호 또는 조제#ID ## 확인된 결과 - 오미자 입고: PR-20260211-0001 - 박주호 환자 출고: 조제#1 (처방전 번호 없음) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- app.py | 28 ++++++++--- update_receipt_numbers.py | 103 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 7 deletions(-) create mode 100644 update_receipt_numbers.py diff --git a/app.py b/app.py index 422057d..fba31a9 100644 --- a/app.py +++ b/app.py @@ -434,12 +434,26 @@ def upload_purchase_excel(): for receipt_date, group in grouped: + # 입고장 번호 생성 (PR-YYYYMMDD-XXXX) + date_str = str(receipt_date).replace('-', '') + + # 해당 날짜의 최대 번호 찾기 + cursor.execute(""" + SELECT MAX(CAST(SUBSTR(receipt_no, -4) AS INTEGER)) + FROM purchase_receipts + WHERE receipt_no LIKE ? + """, (f'PR-{date_str}-%',)) + + max_num = cursor.fetchone()[0] + next_num = (max_num or 0) + 1 + receipt_no = f"PR-{date_str}-{next_num:04d}" + # 입고장 헤더 생성 total_amount = group['total_amount'].sum() cursor.execute(""" - INSERT INTO purchase_receipts (supplier_id, receipt_date, total_amount, source_file) - VALUES (?, ?, ?, ?) - """, (supplier_id, str(receipt_date), total_amount, filename)) + INSERT INTO purchase_receipts (supplier_id, receipt_date, receipt_no, total_amount, source_file) + VALUES (?, ?, ?, ?, ?) + """, (supplier_id, str(receipt_date), receipt_no, total_amount, filename)) receipt_id = cursor.lastrowid # 입고장 라인 생성 @@ -1087,8 +1101,8 @@ def get_stock_ledger(): il.origin_country, s.name as supplier_name, CASE - WHEN sl.event_type = 'PURCHASE' THEN pr.receipt_no - WHEN sl.event_type = 'CONSUME' THEN c.compound_id + WHEN sl.event_type = 'PURCHASE' OR sl.event_type = 'RECEIPT' THEN pr.receipt_no + WHEN sl.event_type = 'CONSUME' THEN COALESCE(c.prescription_no, '조제#' || c.compound_id) ELSE NULL END as reference_no, CASE @@ -1121,8 +1135,8 @@ def get_stock_ledger(): il.origin_country, s.name as supplier_name, CASE - WHEN sl.event_type = 'PURCHASE' THEN pr.receipt_no - WHEN sl.event_type = 'CONSUME' THEN c.compound_id + WHEN sl.event_type = 'PURCHASE' OR sl.event_type = 'RECEIPT' THEN pr.receipt_no + WHEN sl.event_type = 'CONSUME' THEN COALESCE(c.prescription_no, '조제#' || c.compound_id) ELSE NULL END as reference_no, CASE diff --git a/update_receipt_numbers.py b/update_receipt_numbers.py new file mode 100644 index 0000000..5ad2b70 --- /dev/null +++ b/update_receipt_numbers.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +기존 입고 데이터에 입고장 번호를 자동으로 부여하는 스크립트 +형식: PR-YYYYMMDD-XXXX (PR: Purchase Receipt) +""" + +import sqlite3 +from datetime import datetime + +def update_receipt_numbers(): + conn = sqlite3.connect('database/kdrug.db') + cursor = conn.cursor() + + try: + # 입고장 번호가 없는 레코드 조회 + cursor.execute(""" + SELECT receipt_id, receipt_date, supplier_id + FROM purchase_receipts + WHERE receipt_no IS NULL OR receipt_no = '' + ORDER BY receipt_date, receipt_id + """) + + receipts = cursor.fetchall() + + if not receipts: + print("모든 입고장에 이미 번호가 있습니다.") + return + + print(f"입고장 번호를 부여할 레코드: {len(receipts)}개") + + # 날짜별 카운터 딕셔너리 + date_counters = {} + + for receipt in receipts: + receipt_id, receipt_date, supplier_id = receipt + + # 날짜 형식 변환 + if receipt_date: + # receipt_date가 문자열인 경우 + if isinstance(receipt_date, str): + date_str = receipt_date.replace('-', '') # YYYYMMDD 형식 + # receipt_date가 정수인 경우 (YYYYMMDD 형식으로 저장된 경우) + else: + date_str = str(receipt_date) + else: + date_str = datetime.now().strftime('%Y%m%d') + + # 해당 날짜의 카운터 증가 + if date_str not in date_counters: + # 해당 날짜의 기존 최대 번호 확인 + cursor.execute(""" + SELECT MAX(CAST(SUBSTR(receipt_no, -4) AS INTEGER)) + FROM purchase_receipts + WHERE receipt_no LIKE ? + """, (f'PR-{date_str}-%',)) + + max_num = cursor.fetchone()[0] + date_counters[date_str] = (max_num or 0) + 1 + else: + date_counters[date_str] += 1 + + # 입고장 번호 생성 (PR-YYYYMMDD-XXXX) + receipt_no = f"PR-{date_str}-{date_counters[date_str]:04d}" + + # 업데이트 + cursor.execute(""" + UPDATE purchase_receipts + SET receipt_no = ? + WHERE receipt_id = ? + """, (receipt_no, receipt_id)) + + print(f" 입고장 ID {receipt_id}: {receipt_no} 부여 완료") + + conn.commit() + print(f"\n총 {len(receipts)}개의 입고장 번호 부여 완료!") + + # 결과 확인 + cursor.execute(""" + SELECT receipt_id, receipt_no, receipt_date, + (SELECT name FROM suppliers WHERE supplier_id = pr.supplier_id) as supplier_name + FROM purchase_receipts pr + ORDER BY receipt_date DESC, receipt_id DESC + LIMIT 10 + """) + + print("\n최근 입고장 목록:") + print("-" * 80) + print(f"{'ID':>6} | {'입고장 번호':<20} | {'입고일':<12} | {'공급처'}") + print("-" * 80) + + for row in cursor.fetchall(): + print(f"{row[0]:>6} | {row[1]:<20} | {row[2]:<12} | {row[3]}") + + except Exception as e: + print(f"오류 발생: {e}") + conn.rollback() + finally: + conn.close() + +if __name__ == "__main__": + update_receipt_numbers() \ No newline at end of file