kdrug-inventory-system/dev_scripts/check_custom_prescription.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

224 lines
7.0 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
커스텀 처방 감지 유틸리티
조제 시 원 처방과 다른 구성인지 확인
"""
import sqlite3
from typing import Dict, List, Tuple
def get_connection():
"""데이터베이스 연결"""
return sqlite3.connect('database/kdrug.db')
def check_custom_prescription(compound_id: int) -> Tuple[bool, Dict]:
"""
조제가 원 처방과 다른지 확인
Returns:
(is_custom, differences_dict)
"""
conn = get_connection()
cursor = conn.cursor()
# 1. compound의 formula_id 가져오기
cursor.execute("""
SELECT c.formula_id, f.formula_name
FROM compounds c
JOIN formulas f ON c.formula_id = f.formula_id
WHERE c.compound_id = ?
""", (compound_id,))
result = cursor.fetchone()
if not result:
conn.close()
return False, {"error": "Compound not found"}
formula_id, formula_name = result
# 2. 원 처방의 구성 약재
cursor.execute("""
SELECT
fi.herb_item_id,
h.herb_name,
fi.grams_per_cheop
FROM formula_ingredients fi
JOIN herb_items h ON fi.herb_item_id = h.herb_item_id
WHERE fi.formula_id = ?
ORDER BY fi.herb_item_id
""", (formula_id,))
original_ingredients = {row[0]: {
'herb_name': row[1],
'grams_per_cheop': row[2]
} for row in cursor.fetchall()}
# 3. 실제 조제된 구성 약재
cursor.execute("""
SELECT
ci.herb_item_id,
h.herb_name,
ci.grams_per_cheop
FROM compound_ingredients ci
JOIN herb_items h ON ci.herb_item_id = h.herb_item_id
WHERE ci.compound_id = ?
ORDER BY ci.herb_item_id
""", (compound_id,))
actual_ingredients = {row[0]: {
'herb_name': row[1],
'grams_per_cheop': row[2]
} for row in cursor.fetchall()}
conn.close()
# 4. 비교 분석
differences = {
'formula_name': formula_name,
'added': [],
'removed': [],
'modified': [],
'is_custom': False
}
# 추가된 약재
for herb_id, info in actual_ingredients.items():
if herb_id not in original_ingredients:
differences['added'].append({
'herb_id': herb_id,
'herb_name': info['herb_name'],
'grams_per_cheop': info['grams_per_cheop']
})
differences['is_custom'] = True
# 제거된 약재
for herb_id, info in original_ingredients.items():
if herb_id not in actual_ingredients:
differences['removed'].append({
'herb_id': herb_id,
'herb_name': info['herb_name'],
'grams_per_cheop': info['grams_per_cheop']
})
differences['is_custom'] = True
# 용량 변경된 약재
for herb_id in set(original_ingredients.keys()) & set(actual_ingredients.keys()):
orig_grams = original_ingredients[herb_id]['grams_per_cheop']
actual_grams = actual_ingredients[herb_id]['grams_per_cheop']
if abs(orig_grams - actual_grams) > 0.01: # 부동소수점 오차 고려
differences['modified'].append({
'herb_id': herb_id,
'herb_name': original_ingredients[herb_id]['herb_name'],
'original_grams': orig_grams,
'actual_grams': actual_grams,
'difference': actual_grams - orig_grams
})
differences['is_custom'] = True
return differences['is_custom'], differences
def generate_custom_summary(differences: Dict) -> str:
"""커스텀 내역을 요약 문자열로 생성"""
summary_parts = []
# 추가
if differences['added']:
added_herbs = [f"{item['herb_name']} {item['grams_per_cheop']}g"
for item in differences['added']]
summary_parts.append(f"추가: {', '.join(added_herbs)}")
# 제거
if differences['removed']:
removed_herbs = [item['herb_name'] for item in differences['removed']]
summary_parts.append(f"제거: {', '.join(removed_herbs)}")
# 수정
if differences['modified']:
modified_herbs = [f"{item['herb_name']} {item['original_grams']}g→{item['actual_grams']}g"
for item in differences['modified']]
summary_parts.append(f"변경: {', '.join(modified_herbs)}")
return " | ".join(summary_parts) if summary_parts else "표준 처방"
def list_all_custom_prescriptions():
"""모든 커스텀 처방 찾기"""
conn = get_connection()
cursor = conn.cursor()
# 모든 조제 목록
cursor.execute("""
SELECT
c.compound_id,
c.compound_date,
p.name as patient_name,
f.formula_name
FROM compounds c
LEFT JOIN patients p ON c.patient_id = p.patient_id
JOIN formulas f ON c.formula_id = f.formula_id
ORDER BY c.compound_date DESC
""")
compounds = cursor.fetchall()
conn.close()
custom_compounds = []
for compound in compounds:
compound_id = compound[0]
is_custom, differences = check_custom_prescription(compound_id)
if is_custom:
custom_compounds.append({
'compound_id': compound_id,
'compound_date': compound[1],
'patient_name': compound[2],
'formula_name': compound[3],
'summary': generate_custom_summary(differences),
'differences': differences
})
return custom_compounds
def demo():
"""데모 실행"""
print("\n" + "="*80)
print("커스텀 처방 감지 시스템")
print("="*80)
# 전체 커스텀 처방 검색
custom_prescriptions = list_all_custom_prescriptions()
if not custom_prescriptions:
print("\n조제 내역이 없거나 모든 조제가 표준 처방입니다.")
# 테스트용 샘플 데이터 표시
print("\n[시뮬레이션] 만약 십전대보탕에 구기자를 추가했다면:")
print("-" * 60)
sample_diff = {
'formula_name': '십전대보탕',
'added': [{'herb_name': '구기자', 'grams_per_cheop': 3}],
'removed': [],
'modified': [{'herb_name': '인삼', 'original_grams': 5, 'actual_grams': 7}],
'is_custom': True
}
summary = generate_custom_summary(sample_diff)
print(f"처방: 십전대보탕 (가감방)")
print(f"변경 내역: {summary}")
print("\n환자 기록 표시:")
print(" 2024-02-17 십전대보탕 가감방 20첩")
print(f" └─ {summary}")
else:
print(f"\n{len(custom_prescriptions)}개의 커스텀 처방이 발견되었습니다.\n")
for cp in custom_prescriptions:
print(f"조제 #{cp['compound_id']} | {cp['compound_date']} | {cp['patient_name']}")
print(f" 처방: {cp['formula_name']} (가감방)")
print(f" 변경: {cp['summary']}")
print()
if __name__ == "__main__":
demo()