feat: 약품별 선호 도매상 API + delivery_schedules 테이블

- GET /api/order/drug/{code}/preferred-vendor: 약품별 선호 도매상 조회
- POST /api/order/drugs/preferred-vendors: 일괄 조회
- MSSQL 입고장 데이터 활용 (WH_main, WH_sub)
- 최근 주문 도매상 + 최다 주문 도매상 반환

DB:
- delivery_schedules 테이블 생성 (orders.db)
- 도매상별 주문 마감시간/배송 도착시간 관리
This commit is contained in:
thug0bin 2026-03-07 22:49:12 +09:00
parent 1088720081
commit a23e4bad43

View File

@ -1227,3 +1227,163 @@ def api_update_wholesaler_limit(wholesaler_id):
'success': True,
'message': f'{wholesaler_id} 한도 업데이트 완료'
})
# ========== 약품별 선호 도매상 API ==========
def get_drug_preferred_vendor(drug_code: str, period_days: int = 365):
"""
약품코드 기준 선호 도매상 조회 (MSSQL 입고장 데이터)
"""
import pyodbc
CONN_STR = (
'DRIVER={ODBC Driver 17 for SQL Server};'
'SERVER=192.168.0.4\\PM2014;'
'DATABASE=PM_DRUG;'
'UID=sa;'
'PWD=tmddls214!%(;'
'TrustServerCertificate=yes;'
'Connection Timeout=10'
)
try:
conn = pyodbc.connect(CONN_STR, timeout=10)
cursor = conn.cursor()
# 약품명 조회
cursor.execute("SELECT GoodsName FROM CD_GOODS WHERE DrugCode = ?", drug_code)
row = cursor.fetchone()
drug_name = row[0] if row else ''
# 도매상별 입고 통계
query = """
SELECT
c.CD_NM_custom AS vendor_name,
c.CD_CD_custom AS vendor_code,
COUNT(*) AS order_count,
SUM(ws.WH_NM_item_a) AS total_qty,
SUM(ws.WH_MY_amount_a) AS total_amount,
AVG(ws.WH_MY_unit_a) AS avg_unit_price,
MAX(wm.WH_DT_appl) AS last_order_date
FROM WH_sub ws
JOIN WH_main wm ON ws.WH_SR_stock = wm.WH_NO_stock
LEFT JOIN PM_BASE.dbo.CD_custom c ON wm.WH_CD_cust_sale = c.CD_CD_custom
WHERE ws.DrugCode = ?
AND wm.WH_DT_appl >= CONVERT(varchar(8), DATEADD(day, ?, GETDATE()), 112)
GROUP BY c.CD_NM_custom, c.CD_CD_custom
ORDER BY COUNT(*) DESC
"""
cursor.execute(query, (drug_code, -period_days))
rows = cursor.fetchall()
if not rows:
conn.close()
return {
'success': True,
'drug_code': drug_code,
'drug_name': drug_name,
'recent_vendor': None,
'most_frequent_vendor': None,
'vendors': [],
'message': '입고 이력 없음'
}
vendors = []
for r in rows:
vendors.append({
'vendor_name': r[0] or '알수없음',
'vendor_code': r[1] or '',
'order_count': r[2],
'total_qty': float(r[3] or 0),
'total_amount': float(r[4] or 0),
'avg_unit_price': float(r[5] or 0),
'last_order_date': r[6]
})
most_frequent = vendors[0] if vendors else None
# 최근 주문 도매상
recent_query = """
SELECT TOP 1
c.CD_NM_custom AS vendor_name,
c.CD_CD_custom AS vendor_code,
wm.WH_DT_appl AS order_date,
ws.WH_NM_item_a AS qty,
ws.WH_MY_unit_a AS unit_price
FROM WH_sub ws
JOIN WH_main wm ON ws.WH_SR_stock = wm.WH_NO_stock
LEFT JOIN PM_BASE.dbo.CD_custom c ON wm.WH_CD_cust_sale = c.CD_CD_custom
WHERE ws.DrugCode = ?
ORDER BY wm.WH_DT_appl DESC
"""
cursor.execute(recent_query, drug_code)
recent_row = cursor.fetchone()
recent_vendor = None
if recent_row:
recent_vendor = {
'vendor_name': recent_row[0] or '알수없음',
'vendor_code': recent_row[1] or '',
'order_date': recent_row[2],
'qty': float(recent_row[3] or 0),
'unit_price': float(recent_row[4] or 0)
}
conn.close()
return {
'success': True,
'drug_code': drug_code,
'drug_name': drug_name,
'recent_vendor': recent_vendor,
'most_frequent_vendor': most_frequent,
'vendors': vendors
}
except Exception as e:
return {
'success': False,
'error': str(e),
'drug_code': drug_code
}
@order_bp.route('/drug/<drug_code>/preferred-vendor', methods=['GET'])
def api_drug_preferred_vendor(drug_code):
"""
약품별 선호 도매상 조회 API
GET /api/order/drug/670400830/preferred-vendor
GET /api/order/drug/670400830/preferred-vendor?period=180
"""
period = request.args.get('period', 365, type=int)
result = get_drug_preferred_vendor(drug_code, period)
return jsonify(result)
@order_bp.route('/drugs/preferred-vendors', methods=['POST'])
def api_drugs_preferred_vendors():
"""
여러 약품의 선호 도매상 일괄 조회
POST /api/order/drugs/preferred-vendors
{"drug_codes": ["670400830", "654301800"], "period": 365}
"""
data = request.get_json() or {}
drug_codes = data.get('drug_codes', [])
period = data.get('period', 365)
if not drug_codes:
return jsonify({'success': False, 'error': 'drug_codes required'})
results = {}
for code in drug_codes:
results[code] = get_drug_preferred_vendor(code, period)
return jsonify({
'success': True,
'count': len(results),
'results': results
})