From 849c2dd561aca5c7dfb728a28ad99ceb380a1467 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=9C=EA=B3=A8=EC=95=BD=EC=82=AC?= Date: Mon, 16 Feb 2026 14:37:52 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=9E=85=EA=B3=A0=20=EC=8B=9C=20herb?= =?UTF-8?q?=5Fproducts=EC=97=90=EC=84=9C=20=EC=9E=90=EB=8F=99=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EB=A7=A4=ED=95=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 주요 개선사항: 1. 보험코드로 herb_products 테이블에서 자동 정보 조회 - 성분코드(ingredient_code) 자동 매핑 - 회사명(specification) 자동 입력 - 표준 제품명 자동 적용 2. 입고 날짜 처리 버그 수정 - pandas groupby 튜플 문제 해결 - receipt_date 문자열 변환 처리 - 입고번호 정상 생성 (PR-YYYYMMDD-XXXX) 3. 데이터 타입 문제 수정 - total_amount numpy 타입을 float로 변환 - JSON 직렬화 오류 방지 이제 Excel 입고 시 보험코드만으로 모든 정보 자동 입력 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- app.py | 101 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 85 insertions(+), 16 deletions(-) diff --git a/app.py b/app.py index 2d0d14c..6bce373 100644 --- a/app.py +++ b/app.py @@ -545,12 +545,18 @@ def upload_purchase_excel(): return jsonify({'success': False, 'error': '유효하지 않은 도매상입니다'}), 400 # 날짜별로 그룹화 (도매상은 이미 선택됨) - grouped = df.groupby(['receipt_date']) + grouped = df.groupby('receipt_date') # 리스트 대신 문자열로 변경 for receipt_date, group in grouped: + # receipt_date가 튜플인 경우 처리 + if isinstance(receipt_date, tuple): + receipt_date = receipt_date[0] + + # receipt_date를 문자열로 확실히 변환 + receipt_date_str = str(receipt_date) # 입고장 번호 생성 (PR-YYYYMMDD-XXXX) - date_str = str(receipt_date).replace('-', '') + date_str = receipt_date_str.replace('-', '') # 해당 날짜의 최대 번호 찾기 cursor.execute(""" @@ -564,30 +570,93 @@ def upload_purchase_excel(): receipt_no = f"PR-{date_str}-{next_num:04d}" # 입고장 헤더 생성 - total_amount = group['total_amount'].sum() + total_amount = float(group['total_amount'].sum()) # float로 변환하여 numpy 타입 문제 해결 cursor.execute(""" 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)) + """, (supplier_id, receipt_date_str, receipt_no, total_amount, filename)) receipt_id = cursor.lastrowid # 입고장 라인 생성 for _, row in group.iterrows(): - # 약재 확인/생성 - cursor.execute(""" - SELECT herb_item_id FROM herb_items - WHERE insurance_code = ? OR herb_name = ? - """, (row.get('insurance_code'), row['herb_name'])) - herb = cursor.fetchone() + insurance_code = row.get('insurance_code') - if not herb: + # 보험코드가 있는 경우 herb_products에서 정보 가져오기 + if insurance_code: cursor.execute(""" - INSERT INTO herb_items (insurance_code, herb_name) - VALUES (?, ?) - """, (row.get('insurance_code'), row['herb_name'])) - herb_item_id = cursor.lastrowid + SELECT DISTINCT + hp.ingredient_code, + hp.product_name, + hp.company_name + FROM herb_products hp + WHERE hp.product_code = ? + """, (insurance_code,)) + product_info = cursor.fetchone() + + if product_info: + ingredient_code = product_info[0] + product_name = product_info[1] + company_name = product_info[2] + + # herb_items에서 해당 보험코드 제품 확인 + cursor.execute(""" + SELECT herb_item_id FROM herb_items + WHERE insurance_code = ? + """, (insurance_code,)) + herb = cursor.fetchone() + + if not herb: + # 새 제품 생성 (ingredient_code, company_name 포함) + cursor.execute(""" + INSERT INTO herb_items ( + ingredient_code, + insurance_code, + herb_name, + specification + ) VALUES (?, ?, ?, ?) + """, (ingredient_code, insurance_code, product_name, company_name)) + herb_item_id = cursor.lastrowid + else: + herb_item_id = herb[0] + # 기존 제품의 ingredient_code가 없으면 업데이트 + cursor.execute(""" + UPDATE herb_items + SET ingredient_code = COALESCE(ingredient_code, ?), + specification = COALESCE(specification, ?) + WHERE herb_item_id = ? + """, (ingredient_code, company_name, herb_item_id)) + else: + # herb_products에 없는 경우 기존 로직 + cursor.execute(""" + SELECT herb_item_id FROM herb_items + WHERE insurance_code = ? OR herb_name = ? + """, (insurance_code, row['herb_name'])) + herb = cursor.fetchone() + + if not herb: + cursor.execute(""" + INSERT INTO herb_items (insurance_code, herb_name) + VALUES (?, ?) + """, (insurance_code, row['herb_name'])) + herb_item_id = cursor.lastrowid + else: + herb_item_id = herb[0] else: - herb_item_id = herb[0] + # 보험코드가 없는 경우 약재명으로만 처리 + cursor.execute(""" + SELECT herb_item_id FROM herb_items + WHERE herb_name = ? + """, (row['herb_name'],)) + herb = cursor.fetchone() + + if not herb: + cursor.execute(""" + INSERT INTO herb_items (herb_name) + VALUES (?) + """, (row['herb_name'],)) + herb_item_id = cursor.lastrowid + else: + herb_item_id = herb[0] # 단가 계산 (총액 / 수량) quantity = float(row['quantity'])