kdrug-inventory-system/dev_scripts/check_lot_creation_methods.py
시골약사 ad9ac396e2 chore: 개발 파일 정리 및 구조화
- 개발/테스트 스크립트를 dev_scripts/ 폴더로 이동
- 스크린샷을 screenshots/ 폴더로 이동
- 백업 파일 보존 (.backup)
- 처방 관련 추가 스크립트 포함

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-18 04:44:48 +00:00

143 lines
4.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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