#!/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()