- 개발/테스트 스크립트를 dev_scripts/ 폴더로 이동 - 스크린샷을 screenshots/ 폴더로 이동 - 백업 파일 보존 (.backup) - 처방 관련 추가 스크립트 포함 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
145 lines
4.5 KiB
Python
145 lines
4.5 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
최종 검증 - 문제 해결 확인
|
|
"""
|
|
|
|
import sqlite3
|
|
import json
|
|
import urllib.request
|
|
|
|
def final_verification():
|
|
print("=" * 80)
|
|
print("📊 재고 자산 문제 해결 최종 검증")
|
|
print("=" * 80)
|
|
print()
|
|
|
|
# 1. API 호출 결과
|
|
print("1. API 응답 확인")
|
|
print("-" * 60)
|
|
|
|
try:
|
|
with urllib.request.urlopen('http://localhost:5001/api/inventory/summary') as response:
|
|
data = json.loads(response.read())
|
|
api_value = data['summary']['total_value']
|
|
total_items = data['summary']['total_items']
|
|
|
|
print(f" API 재고 자산: ₩{api_value:,.0f}")
|
|
print(f" 총 약재 수: {total_items}개")
|
|
except Exception as e:
|
|
print(f" API 호출 실패: {e}")
|
|
api_value = 0
|
|
|
|
# 2. 데이터베이스 직접 계산
|
|
print("\n2. 데이터베이스 직접 계산")
|
|
print("-" * 60)
|
|
|
|
conn = sqlite3.connect('database/kdrug.db')
|
|
conn.row_factory = sqlite3.Row
|
|
cursor = conn.cursor()
|
|
|
|
cursor.execute("""
|
|
SELECT
|
|
SUM(quantity_onhand * unit_price_per_g) as total_value,
|
|
COUNT(*) as lot_count,
|
|
SUM(quantity_onhand) as total_quantity
|
|
FROM inventory_lots
|
|
WHERE is_depleted = 0 AND quantity_onhand > 0
|
|
""")
|
|
|
|
db_result = cursor.fetchone()
|
|
db_value = db_result['total_value'] or 0
|
|
|
|
print(f" DB 재고 자산: ₩{db_value:,.0f}")
|
|
print(f" 활성 LOT: {db_result['lot_count']}개")
|
|
print(f" 총 재고량: {db_result['total_quantity']:,.1f}g")
|
|
|
|
# 3. 입고와 출고 기반 계산
|
|
print("\n3. 입고/출고 기반 계산")
|
|
print("-" * 60)
|
|
|
|
# 총 입고액
|
|
cursor.execute("SELECT SUM(line_total) as total FROM purchase_receipt_lines")
|
|
total_in = cursor.fetchone()['total'] or 0
|
|
|
|
# 총 소비액
|
|
cursor.execute("""
|
|
SELECT SUM(cc.quantity_used * il.unit_price_per_g) as total
|
|
FROM compound_consumptions cc
|
|
JOIN inventory_lots il ON cc.lot_id = il.lot_id
|
|
""")
|
|
total_out = cursor.fetchone()['total'] or 0
|
|
|
|
expected = total_in - total_out
|
|
|
|
print(f" 입고 총액: ₩{total_in:,.0f}")
|
|
print(f" 소비 총액: ₩{total_out:,.0f}")
|
|
print(f" 예상 재고: ₩{expected:,.0f}")
|
|
|
|
# 4. 결과 비교
|
|
print("\n4. 결과 비교")
|
|
print("=" * 60)
|
|
|
|
print(f"\n 🎯 API 재고 자산: ₩{api_value:,.0f}")
|
|
print(f" 🎯 DB 직접 계산: ₩{db_value:,.0f}")
|
|
print(f" 🎯 예상 재고액: ₩{expected:,.0f}")
|
|
|
|
# 차이 계산
|
|
api_db_diff = abs(api_value - db_value)
|
|
db_expected_diff = abs(db_value - expected)
|
|
|
|
print(f"\n API vs DB 차이: ₩{api_db_diff:,.0f}")
|
|
print(f" DB vs 예상 차이: ₩{db_expected_diff:,.0f}")
|
|
|
|
# 5. 결론
|
|
print("\n5. 결론")
|
|
print("=" * 60)
|
|
|
|
if api_db_diff < 100:
|
|
print("\n ✅ 문제 해결 완료!")
|
|
print(" API와 DB 계산이 일치합니다.")
|
|
print(f" 재고 자산: ₩{api_value:,.0f}")
|
|
else:
|
|
print("\n ⚠️ 아직 차이가 있습니다.")
|
|
print(f" 차이: ₩{api_db_diff:,.0f}")
|
|
|
|
if db_expected_diff > 100000:
|
|
print("\n 📌 참고: DB 재고와 예상 재고 간 차이는")
|
|
print(" 다음 요인들로 인해 발생할 수 있습니다:")
|
|
print(" - 입고 시점과 LOT 생성 시점의 단가 차이")
|
|
print(" - 재고 보정 내역")
|
|
print(" - 반올림 오차 누적")
|
|
|
|
# 6. 효능 태그 확인 (중복 문제가 해결되었는지)
|
|
print("\n6. 효능 태그 표시 확인")
|
|
print("-" * 60)
|
|
|
|
# API에서 효능 태그가 있는 약재 확인
|
|
try:
|
|
with urllib.request.urlopen('http://localhost:5001/api/inventory/summary') as response:
|
|
data = json.loads(response.read())
|
|
|
|
herbs_with_tags = [
|
|
item for item in data['data']
|
|
if item.get('efficacy_tags') and len(item['efficacy_tags']) > 0
|
|
]
|
|
|
|
print(f" 효능 태그가 있는 약재: {len(herbs_with_tags)}개")
|
|
|
|
if herbs_with_tags:
|
|
sample = herbs_with_tags[0]
|
|
print(f"\n 예시: {sample['herb_name']}")
|
|
print(f" 태그: {', '.join(sample['efficacy_tags'])}")
|
|
print(f" 재고 가치: ₩{sample['total_value']:,.0f}")
|
|
except Exception as e:
|
|
print(f" 효능 태그 확인 실패: {e}")
|
|
|
|
conn.close()
|
|
|
|
print("\n" + "=" * 80)
|
|
print("검증 완료")
|
|
print("=" * 80)
|
|
|
|
if __name__ == "__main__":
|
|
final_verification() |