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:
parent
1088720081
commit
a23e4bad43
@ -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
|
||||
})
|
||||
|
||||
Loading…
Reference in New Issue
Block a user