fix: 커스텀 처방 감지 로직 개선 및 기존 데이터 업데이트

- 문제: ingredient_code 기준 비교 누락으로 인삼 제거가 감지되지 않음
  - 인삼(3400H1AHM)은 herb_items에 없어서 herb_item_id 매핑 실패
  - 원 처방에만 있고 실제 재고가 없는 약재 처리 불가

- 해결: ingredient_code 기준 비교 로직 추가
  - original_by_code 딕셔너리로 원 처방 구성 저장
  - actual_by_code 딕셔너리로 실제 조제 구성 저장
  - 제거된 약재를 ingredient_code 기준으로 감지

- 조제 상세 모달에 가감방 표시 추가
  - 처방명 옆에 "가감" 뱃지 표시
  - 변경 내용 요약 표시

- 기존 데이터 업데이트 스크립트 추가
  - 십전대보탕에서 인삼 제거 감지 성공
  - compound #4를 가감방으로 정상 업데이트

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
시골약사 2026-02-17 01:38:23 +00:00
parent 1441c01fb4
commit 6ad8bac5c2
3 changed files with 160 additions and 9 deletions

31
app.py
View File

@ -1175,31 +1175,48 @@ def create_compound():
WHERE fi.formula_id = ?
""", (formula_id,))
# ingredient_code -> herb_item_id 매핑
# 원 처방 구성을 ingredient_code 기준으로 저장
original_by_code = {}
original_ingredients = {} # herb_item_id 기준
for row in cursor.fetchall():
ingredient_code = row[0]
herb_name = row[1]
grams = row[2]
# ingredient_code 기준으로 저장
original_by_code[ingredient_code] = {
'herb_name': herb_name,
'grams': grams
}
# 해당 ingredient_code를 가진 herb_item_id들 조회
cursor.execute("SELECT herb_item_id FROM herb_items WHERE ingredient_code = ?",
(ingredient_code,))
herb_ids = [r[0] for r in cursor.fetchall()]
for herb_id in herb_ids:
original_by_code[herb_id] = {
original_ingredients[herb_id] = {
'herb_name': herb_name,
'grams': grams,
'ingredient_code': ingredient_code
}
original_ingredients = original_by_code
# 실제 조제 구성과 비교
actual_ingredients = {ing['herb_item_id']: ing['grams_per_cheop']
for ing in data['ingredients']}
# 실제 조제의 ingredient_code 수집
actual_by_code = {}
for ing in data['ingredients']:
cursor.execute("SELECT ingredient_code FROM herb_items WHERE herb_item_id = ?",
(ing['herb_item_id'],))
result = cursor.fetchone()
if result:
ingredient_code = result[0]
if ingredient_code not in actual_by_code:
actual_by_code[ingredient_code] = ing['grams_per_cheop']
# 추가된 약재 확인
for ing in data['ingredients']:
herb_id = ing['herb_item_id']
@ -1210,9 +1227,9 @@ def create_compound():
custom_details['added'].append(f"{herb_name} {ing['grams_per_cheop']}g")
is_custom = True
# 제거된 약재 확인
for herb_id, info in original_ingredients.items():
if herb_id not in actual_ingredients:
# 제거된 약재 확인 (ingredient_code 기준)
for code, info in original_by_code.items():
if code not in actual_by_code:
custom_details['removed'].append(info['herb_name'])
is_custom = True

View File

@ -1108,8 +1108,15 @@ $(document).ready(function() {
$('#detailPatientPhone').text(data.patient_phone || '-');
$('#detailCompoundDate').text(data.compound_date || '-');
// 처방 정보
$('#detailFormulaName').text(data.formula_name || '직접조제');
// 처방 정보 (가감방 표시 포함)
let formulaDisplay = data.formula_name || '직접조제';
if (data.is_custom && data.formula_name) {
formulaDisplay += ' <span class="badge bg-warning">가감</span>';
if (data.custom_summary) {
formulaDisplay += `<br><small class="text-muted">${data.custom_summary}</small>`;
}
}
$('#detailFormulaName').html(formulaDisplay); // text() 대신 html() 사용
$('#detailPrescriptionNo').text(data.prescription_no || '-');
$('#detailQuantities').text(`${data.je_count}제 / ${data.cheop_total}첩 / ${data.pouch_total}파우치`);

View File

@ -0,0 +1,127 @@
#!/usr/bin/env python3
"""
기존 조제 데이터의 커스텀 처방 여부를 재검사하여 업데이트
"""
import sqlite3
from datetime import datetime
def get_connection():
return sqlite3.connect('database/kdrug.db')
def update_custom_prescriptions():
conn = get_connection()
cursor = conn.cursor()
try:
# formula_id가 있는 모든 조제 조회
cursor.execute("""
SELECT compound_id, formula_id
FROM compounds
WHERE formula_id IS NOT NULL
""")
compounds = cursor.fetchall()
print(f"검사할 조제: {len(compounds)}")
updated_count = 0
for compound_id, formula_id in compounds:
# 원 처방 구성 조회 (ingredient_code 기준)
cursor.execute("""
SELECT fi.ingredient_code, hm.herb_name, fi.grams_per_cheop
FROM formula_ingredients fi
JOIN herb_masters hm ON fi.ingredient_code = hm.ingredient_code
WHERE fi.formula_id = ?
""", (formula_id,))
original_by_code = {}
for row in cursor.fetchall():
ingredient_code = row[0]
herb_name = row[1]
grams = row[2]
original_by_code[ingredient_code] = {
'herb_name': herb_name,
'grams': grams
}
# 실제 조제 구성 조회 (ingredient_code 기준)
cursor.execute("""
SELECT hi.ingredient_code, hi.herb_name, ci.grams_per_cheop
FROM compound_ingredients ci
JOIN herb_items hi ON ci.herb_item_id = hi.herb_item_id
WHERE ci.compound_id = ?
""", (compound_id,))
actual_by_code = {}
for row in cursor.fetchall():
ingredient_code = row[0]
herb_name = row[1]
grams = row[2]
if ingredient_code not in actual_by_code:
actual_by_code[ingredient_code] = {
'herb_name': herb_name,
'grams': grams
}
# 커스텀 여부 판단
is_custom = False
custom_details = []
# 추가된 약재 확인
for code, info in actual_by_code.items():
if code not in original_by_code:
custom_details.append(f"{info['herb_name']} {info['grams']}g 추가")
is_custom = True
# 제거된 약재 확인
for code, info in original_by_code.items():
if code not in actual_by_code:
custom_details.append(f"{info['herb_name']} 제거")
is_custom = True
# 용량 변경된 약재 확인
for code in original_by_code:
if code in actual_by_code:
original_grams = original_by_code[code]['grams']
actual_grams = actual_by_code[code]['grams']
if abs(original_grams - actual_grams) > 0.01:
herb_name = original_by_code[code]['herb_name']
custom_details.append(f"{herb_name} {original_grams}g→{actual_grams}g")
is_custom = True
# 커스텀인 경우 업데이트
if is_custom:
custom_summary = " | ".join(custom_details)
cursor.execute("""
UPDATE compounds
SET is_custom = 1,
custom_summary = ?,
custom_type = 'custom'
WHERE compound_id = ?
""", (custom_summary, compound_id))
# 처방명 조회
cursor.execute("""
SELECT f.formula_name
FROM compounds c
JOIN formulas f ON c.formula_id = f.formula_id
WHERE c.compound_id = ?
""", (compound_id,))
formula_name = cursor.fetchone()[0]
print(f" - Compound #{compound_id} ({formula_name}): 가감방으로 업데이트")
print(f" 변경사항: {custom_summary}")
updated_count += 1
conn.commit()
print(f"\n완료! {updated_count}개의 조제가 가감방으로 업데이트되었습니다.")
except Exception as e:
conn.rollback()
print(f"오류 발생: {e}")
raise
finally:
conn.close()
if __name__ == "__main__":
update_custom_prescriptions()