#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ LOT 생성 방법 분석 - 입고장 연결 vs 독립 생성 """ import sqlite3 def check_lot_creation_methods(): conn = sqlite3.connect('database/kdrug.db') conn.row_factory = sqlite3.Row cursor = conn.cursor() print("=" * 80) print("📦 LOT 생성 방법 분석") print("=" * 80) print() # 1. 전체 LOT 현황 print("1. 전체 LOT 현황") print("-" * 60) cursor.execute(""" SELECT COUNT(*) as total_lots, SUM(CASE WHEN receipt_line_id IS NOT NULL THEN 1 ELSE 0 END) as with_receipt, SUM(CASE WHEN receipt_line_id IS NULL THEN 1 ELSE 0 END) as without_receipt, SUM(CASE WHEN is_depleted = 0 THEN 1 ELSE 0 END) as active_lots FROM inventory_lots """) stats = cursor.fetchone() print(f" 전체 LOT 수: {stats['total_lots']}개") print(f" ✅ 입고장 연결: {stats['with_receipt']}개") print(f" ❌ 입고장 없음: {stats['without_receipt']}개") print(f" 활성 LOT: {stats['active_lots']}개") # 2. 입고장 없는 LOT 상세 if stats['without_receipt'] > 0: print("\n2. 입고장 없이 생성된 LOT 상세") print("-" * 60) cursor.execute(""" SELECT il.lot_id, h.herb_name, il.lot_number, il.quantity_received, il.quantity_onhand, il.unit_price_per_g, il.quantity_onhand * il.unit_price_per_g as value, il.received_date, il.created_at FROM inventory_lots il JOIN herb_items h ON il.herb_item_id = h.herb_item_id WHERE il.receipt_line_id IS NULL ORDER BY il.created_at DESC """) no_receipt_lots = cursor.fetchall() for lot in no_receipt_lots: print(f"\n LOT {lot['lot_id']}: {lot['herb_name']}") print(f" LOT 번호: {lot['lot_number'] or 'None'}") print(f" 수량: {lot['quantity_received']:,.0f}g → {lot['quantity_onhand']:,.0f}g") print(f" 단가: ₩{lot['unit_price_per_g']:.2f}") print(f" 재고 가치: ₩{lot['value']:,.0f}") print(f" 입고일: {lot['received_date']}") print(f" 생성일: {lot['created_at']}") # 금액 합계 cursor.execute(""" SELECT SUM(quantity_onhand * unit_price_per_g) as total_value, SUM(quantity_onhand) as total_qty FROM inventory_lots WHERE receipt_line_id IS NULL AND is_depleted = 0 AND quantity_onhand > 0 """) no_receipt_total = cursor.fetchone() if no_receipt_total['total_value']: print(f"\n 📊 입고장 없는 LOT 합계:") print(f" 총 재고량: {no_receipt_total['total_qty']:,.0f}g") print(f" 총 재고 가치: ₩{no_receipt_total['total_value']:,.0f}") # 3. LOT 생성 방법별 재고 자산 print("\n3. LOT 생성 방법별 재고 자산") print("-" * 60) cursor.execute(""" SELECT CASE WHEN receipt_line_id IS NOT NULL THEN '입고장 연결' ELSE '직접 생성' END as creation_type, COUNT(*) as lot_count, SUM(quantity_onhand) as total_qty, SUM(quantity_onhand * unit_price_per_g) as total_value FROM inventory_lots WHERE is_depleted = 0 AND quantity_onhand > 0 GROUP BY creation_type """) by_type = cursor.fetchall() total_value = 0 for row in by_type: print(f"\n {row['creation_type']}:") print(f" LOT 수: {row['lot_count']}개") print(f" 재고량: {row['total_qty']:,.0f}g") print(f" 재고 가치: ₩{row['total_value']:,.0f}") total_value += row['total_value'] print(f"\n 📊 전체 재고 자산: ₩{total_value:,.0f}") # 4. 시스템 설계 분석 print("\n4. 시스템 설계 분석") print("=" * 60) print("\n 💡 현재 시스템은 두 가지 방법으로 LOT 생성 가능:") print(" 1) 입고장 등록 시 자동 생성 (receipt_line_id 연결)") print(" 2) 재고 직접 입력 (receipt_line_id = NULL)") print() print(" 📌 재고 자산 계산 로직:") print(" - 입고장 연결 여부와 관계없이") print(" - 모든 활성 LOT의 (수량 × 단가) 합계") print() if stats['without_receipt'] > 0: print(" ⚠️ 주의사항:") print(" - 입고장 없는 LOT이 존재합니다") print(" - 초기 재고 입력이나 재고 조정으로 생성된 것으로 추정") print(" - 회계 추적을 위해서는 입고장 연결 권장") conn.close() if __name__ == "__main__": check_lot_creation_methods()