diff --git a/reset_purchase_data.py b/reset_purchase_data.py new file mode 100644 index 0000000..2f4063b --- /dev/null +++ b/reset_purchase_data.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +입고 관련 데이터 전체 초기화 스크립트 +- 입고장, 재고, 로트, 조제, 재고 조정 등 모두 초기화 +- herb_items는 기본 31개만 유지 +""" + +import sqlite3 +import sys + +def reset_purchase_data(): + """입고 및 관련 데이터 전체 초기화""" + conn = sqlite3.connect('database/kdrug.db') + cursor = conn.cursor() + + try: + print("=== 입고 및 관련 데이터 초기화 시작 ===\n") + + # 1. 조제 관련 초기화 (재고 소비 기록) + cursor.execute("DELETE FROM compound_consumptions") + print(f"✓ compound_consumptions 초기화: {cursor.rowcount}개 삭제") + + cursor.execute("DELETE FROM compound_ingredients") + print(f"✓ compound_ingredients 초기화: {cursor.rowcount}개 삭제") + + cursor.execute("DELETE FROM compounds") + print(f"✓ compounds 초기화: {cursor.rowcount}개 삭제") + + # 2. 재고 원장 전체 초기화 + cursor.execute("DELETE FROM stock_ledger") + print(f"✓ stock_ledger 전체 초기화: {cursor.rowcount}개 삭제") + + # 3. 재고 로트 초기화 + cursor.execute("DELETE FROM inventory_lots") + print(f"✓ inventory_lots 초기화: {cursor.rowcount}개 삭제") + + # 4. 입고장 라인 초기화 + cursor.execute("DELETE FROM purchase_receipt_lines") + print(f"✓ purchase_receipt_lines 초기화: {cursor.rowcount}개 삭제") + + # 5. 입고장 헤더 초기화 + cursor.execute("DELETE FROM purchase_receipts") + print(f"✓ purchase_receipts 초기화: {cursor.rowcount}개 삭제") + + # 6. 재고 조정 초기화 + cursor.execute("DELETE FROM stock_adjustment_details") + print(f"✓ stock_adjustment_details 초기화: {cursor.rowcount}개 삭제") + + cursor.execute("DELETE FROM stock_adjustments") + print(f"✓ stock_adjustments 초기화: {cursor.rowcount}개 삭제") + + # 7. herb_items 중 보험코드가 8자리인 잘못된 데이터 삭제 + cursor.execute(""" + DELETE FROM herb_items + WHERE LENGTH(insurance_code) = 8 + AND insurance_code NOT LIKE 'A%' + """) + print(f"✓ 잘못된 herb_items 삭제 (8자리 보험코드): {cursor.rowcount}개") + + # 8. 테스트용으로 추가된 herb_items 삭제 (ID 32 이후) + cursor.execute(""" + DELETE FROM herb_items + WHERE herb_item_id > 31 + """) + print(f"✓ 테스트 herb_items 삭제 (ID > 31): {cursor.rowcount}개") + + # 9. 기존 herb_items의 ingredient_code, specification 초기화 + cursor.execute(""" + UPDATE herb_items + SET ingredient_code = NULL, + specification = NULL + WHERE herb_item_id <= 31 + """) + print(f"✓ herb_items ingredient_code/specification 초기화: {cursor.rowcount}개") + + # 커밋 + conn.commit() + + print("\n=== 현재 데이터 상태 ===") + + # 현재 상태 확인 + cursor.execute("SELECT COUNT(*) FROM herb_items") + herb_count = cursor.fetchone()[0] + print(f"herb_items: {herb_count}개") + + cursor.execute("SELECT COUNT(*) FROM purchase_receipts") + receipt_count = cursor.fetchone()[0] + print(f"purchase_receipts: {receipt_count}개") + + cursor.execute("SELECT COUNT(*) FROM inventory_lots") + lot_count = cursor.fetchone()[0] + print(f"inventory_lots: {lot_count}개") + + print("\n✓ 입고 데이터 초기화 완료!") + + except Exception as e: + conn.rollback() + print(f"✗ 오류 발생: {str(e)}", file=sys.stderr) + return False + finally: + conn.close() + + return True + +if __name__ == "__main__": + # 확인 + print("입고 관련 데이터를 초기화합니다.") + print("계속하시겠습니까? (y/n): ", end="") + + confirm = input().strip().lower() + if confirm == 'y': + if reset_purchase_data(): + print("\n초기화가 완료되었습니다.") + else: + print("\n초기화 실패!") + else: + print("취소되었습니다.") \ No newline at end of file diff --git a/test_improved_import.py b/test_improved_import.py new file mode 100644 index 0000000..80d280c --- /dev/null +++ b/test_improved_import.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +개선된 Excel 입고 처리 테스트 +""" + +import sys +sys.path.append('/root/kdrug') + +from excel_processor import ExcelProcessor +import pandas as pd + +def test_excel_processing(): + """Excel 처리 테스트""" + processor = ExcelProcessor() + + # 한의정보 샘플 파일 테스트 + print("=== 한의정보 샘플 파일 처리 테스트 ===\n") + + if processor.read_excel('sample/한의정보.xlsx'): + print(f"✓ 파일 읽기 성공") + print(f"✓ 형식 감지: {processor.format_type}") + + # 처리 + df = processor.process() + print(f"✓ 데이터 처리 완료: {len(df)}행") + + # 보험코드 확인 + if 'insurance_code' in df.columns: + print("\n보험코드 샘플 (처리 후):") + for idx, code in enumerate(df['insurance_code'].head(5)): + herb_name = df.iloc[idx]['herb_name'] + print(f" {herb_name}: {code} (길이: {len(str(code))})") + + print("\n=== 한의사랑 샘플 파일 처리 테스트 ===\n") + + processor2 = ExcelProcessor() + if processor2.read_excel('sample/한의사랑.xlsx'): + print(f"✓ 파일 읽기 성공") + print(f"✓ 형식 감지: {processor2.format_type}") + + # 처리 + df2 = processor2.process() + print(f"✓ 데이터 처리 완료: {len(df2)}행") + + # 보험코드 확인 + if 'insurance_code' in df2.columns: + print("\n보험코드 샘플 (처리 후):") + for idx, code in enumerate(df2['insurance_code'].head(5)): + herb_name = df2.iloc[idx]['herb_name'] + print(f" {herb_name}: {code} (길이: {len(str(code))})") + +if __name__ == "__main__": + test_excel_processing() \ No newline at end of file diff --git a/test_upload_api.py b/test_upload_api.py new file mode 100644 index 0000000..520ef91 --- /dev/null +++ b/test_upload_api.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +API를 통한 Excel 입고 처리 테스트 +""" + +import requests +import json + +# API 베이스 URL +BASE_URL = "http://localhost:5001" + +def test_upload_excel(): + """Excel 업로드 테스트""" + + # 1. 도매상 목록 확인 + print("=== 도매상 목록 확인 ===") + response = requests.get(f"{BASE_URL}/api/suppliers") + suppliers = response.json() + + if suppliers['success'] and suppliers['data']: + print(f"✓ 도매상 {len(suppliers['data'])}개 조회") + supplier_id = suppliers['data'][0]['supplier_id'] + supplier_name = suppliers['data'][0]['name'] + print(f"✓ 선택된 도매상: {supplier_name} (ID: {supplier_id})") + else: + print("도매상이 없습니다. 새로 생성합니다.") + # 도매상 생성 + supplier_data = { + 'name': '한의정보', + 'business_no': '123-45-67890', + 'contact_person': '담당자', + 'phone': '02-1234-5678' + } + response = requests.post(f"{BASE_URL}/api/suppliers", json=supplier_data) + result = response.json() + if result['success']: + supplier_id = result['supplier_id'] + print(f"✓ 도매상 생성 완료 (ID: {supplier_id})") + else: + print(f"✗ 도매상 생성 실패: {result.get('error')}") + return + + # 2. Excel 파일 업로드 + print("\n=== Excel 파일 업로드 ===") + + # 파일 열기 + file_path = 'sample/한의정보.xlsx' + with open(file_path, 'rb') as f: + files = {'file': ('한의정보.xlsx', f, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')} + data = {'supplier_id': supplier_id} + + # 업로드 + response = requests.post(f"{BASE_URL}/api/upload/purchase", files=files, data=data) + + # 결과 확인 + result = response.json() + if result['success']: + print(f"✓ 업로드 성공!") + print(f" - 형식: {result['summary']['format']}") + print(f" - 처리된 행: {result['summary']['processed_rows']}") + if 'processed_items' in result['summary']: + print(f" - 처리된 품목: {result['summary']['processed_items']}") + if 'total_amount' in result['summary']: + total = result['summary']['total_amount'] + if isinstance(total, (int, float)): + print(f" - 총액: {total:,.0f}원") + else: + print(f" - 총액: {total}원") + else: + print(f"✗ 업로드 실패: {result.get('error')}") + + # 3. 입고된 herb_items 확인 + print("\n=== 입고된 herb_items 확인 ===") + response = requests.get(f"{BASE_URL}/api/herbs") + herbs = response.json() + + if herbs['success']: + print(f"✓ 총 {len(herbs['data'])}개 herb_items") + # 샘플 출력 + for herb in herbs['data'][:5]: + print(f" - {herb['herb_name']}: 보험코드={herb.get('insurance_code', 'N/A')}, 재고={herb.get('stock_quantity', 0):,.0f}g") + + # 4. 재고 현황 확인 + print("\n=== 재고 현황 확인 ===") + response = requests.get(f"{BASE_URL}/api/inventory/summary") + inventory = response.json() + + if inventory['success']: + summary = inventory['data'] + print(f"✓ 재고 요약:") + print(f" - 총 품목: {summary['total_items']}개") + print(f" - 재고 있는 품목: {summary['items_with_stock']}개") + print(f" - 총 재고 가치: {summary['total_value']:,.0f}원") + +if __name__ == "__main__": + test_upload_excel() \ No newline at end of file