test: 입고 프로세스 테스트 및 유틸리티 추가
추가된 파일: 1. reset_purchase_data.py - 입고 및 관련 데이터 초기화 스크립트 - 조제, 재고, 입고장 데이터 완전 초기화 - 잘못된 herb_items 정리 기능 2. test_improved_import.py - Excel 보험코드 9자리 패딩 테스트 - 한의사랑/한의정보 형식 처리 확인 3. test_upload_api.py - API를 통한 Excel 업로드 테스트 - 도매상 생성 및 입고 처리 검증 - 재고 현황 확인 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
f367781031
commit
ae0d093044
118
reset_purchase_data.py
Normal file
118
reset_purchase_data.py
Normal file
@ -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("취소되었습니다.")
|
||||||
54
test_improved_import.py
Normal file
54
test_improved_import.py
Normal file
@ -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()
|
||||||
97
test_upload_api.py
Normal file
97
test_upload_api.py
Normal file
@ -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()
|
||||||
Loading…
Reference in New Issue
Block a user