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,
|
'success': True,
|
||||||
'message': f'{wholesaler_id} 한도 업데이트 완료'
|
'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