feat: PMR OTC 구매 이력 기능

- /pmr/api/patient/<cus_code>/otc: OTC 구매 이력 API
- SALE_MAIN + SALE_SUB (PRESERIAL='V' = OTC)
- 💊 OTC 뱃지 클릭 → 모달로 구매 이력 표시
- 자주 구매하는 품목 요약
- 방문/금액 통계
This commit is contained in:
thug0bin
2026-03-04 23:55:54 +09:00
parent 41428646ab
commit ebf2e8a016
2 changed files with 350 additions and 0 deletions

View File

@@ -650,3 +650,134 @@ def get_patient_history(cus_code):
except Exception as e:
logging.error(f"환자 이전 처방 조회 오류: {e}")
return jsonify({'success': False, 'error': str(e)}), 500
# ─────────────────────────────────────────────────────────────
# API: 환자 OTC 구매 이력
# ─────────────────────────────────────────────────────────────
@pmr_bp.route('/api/patient/<cus_code>/otc', methods=['GET'])
def get_patient_otc_history(cus_code):
"""
환자 OTC (일반의약품) 구매 이력 조회
Args:
cus_code: 환자 고유코드 (CusCode = SL_CD_custom)
Query Params:
- limit: 최대 조회 건수 (기본 20, 최대 100)
"""
try:
limit = min(int(request.args.get('limit', 20)), 100)
conn = get_mssql_connection('PM_PRES')
cursor = conn.cursor()
# OTC 거래 목록 조회 (PRESERIAL = 'V' = OTC 판매)
cursor.execute("""
SELECT
m.SL_NO_order,
m.SL_DT_appl,
m.InsertTime,
m.SL_MY_sale,
m.SL_NM_custom
FROM SALE_MAIN m
WHERE m.SL_CD_custom = ?
AND m.PRESERIAL = 'V'
ORDER BY m.InsertTime DESC
""", (cus_code,))
# 먼저 거래 목록 수집
orders = []
for row in cursor.fetchall():
orders.append({
'order_no': row.SL_NO_order,
'date': row.SL_DT_appl,
'datetime': row.InsertTime.strftime('%Y-%m-%d %H:%M') if row.InsertTime else '',
'amount': int(row.SL_MY_sale or 0),
'customer_name': row.SL_NM_custom or ''
})
# 최근 limit개만
orders = orders[:limit]
if not orders:
conn.close()
return jsonify({
'success': True,
'cus_code': cus_code,
'count': 0,
'purchases': []
})
# 각 거래의 품목 조회
purchases = []
for order in orders:
cursor.execute("""
SELECT
s.DrugCode,
g.GoodsName,
s.SL_NM_item,
s.SL_TOTAL_PRICE,
mc.PRINT_TYPE
FROM SALE_SUB s
LEFT JOIN PM_DRUG.dbo.CD_GOODS g ON s.DrugCode = g.DrugCode
LEFT JOIN PM_DRUG.dbo.CD_MC mc ON s.DrugCode = mc.DRUGCODE
WHERE s.SL_NO_order = ?
ORDER BY s.DrugCode
""", (order['order_no'],))
items = []
for item_row in cursor.fetchall():
items.append({
'drug_code': item_row.DrugCode or '',
'name': item_row.GoodsName or item_row.DrugCode or '',
'quantity': int(item_row.SL_NM_item or 0),
'price': int(item_row.SL_TOTAL_PRICE or 0),
'category': item_row.PRINT_TYPE or ''
})
purchases.append({
**order,
'items': items,
'item_count': len(items)
})
conn.close()
# 통계 계산
total_amount = sum(p['amount'] for p in purchases)
total_visits = len(purchases)
# 자주 구매하는 품목 집계
item_freq = {}
for p in purchases:
for item in p['items']:
key = item['drug_code']
if key not in item_freq:
item_freq[key] = {
'name': item['name'],
'category': item['category'],
'count': 0,
'total_qty': 0
}
item_freq[key]['count'] += 1
item_freq[key]['total_qty'] += item['quantity']
# 빈도순 정렬
frequent_items = sorted(item_freq.values(), key=lambda x: x['count'], reverse=True)[:10]
return jsonify({
'success': True,
'cus_code': cus_code,
'count': len(purchases),
'summary': {
'total_visits': total_visits,
'total_amount': total_amount,
'frequent_items': frequent_items
},
'purchases': purchases
})
except Exception as e:
logging.error(f"환자 OTC 구매 이력 조회 오류: {e}")
return jsonify({'success': False, 'error': str(e)}), 500