fix: rx-usage 쿼리에 PS_Type!=9 조건 추가 (실제 조제된 약만 집계)
- patient_query: 대체조제 원본 처방 제외 - rx_query: 대체조제 원본 처방 제외 - PS_Type=9는 대체조제시 원래 처방된 약(조제 안됨) - 기타 배치 스크립트 및 문서 추가
This commit is contained in:
@@ -143,6 +143,8 @@ def api_submit_order():
|
||||
# 도매상별 주문 처리
|
||||
if wholesaler_id == 'geoyoung':
|
||||
result = submit_geoyoung_order(order, dry_run)
|
||||
elif wholesaler_id == 'dongwon':
|
||||
result = submit_dongwon_order(order, dry_run)
|
||||
else:
|
||||
result = {
|
||||
'success': False,
|
||||
@@ -517,6 +519,8 @@ def api_quick_submit():
|
||||
submit_result = submit_sooin_order(order, dry_run, cart_only=cart_only)
|
||||
elif order['wholesaler_id'] == 'baekje':
|
||||
submit_result = submit_baekje_order(order, dry_run, cart_only=cart_only)
|
||||
elif order['wholesaler_id'] == 'dongwon':
|
||||
submit_result = submit_dongwon_order(order, dry_run, cart_only=cart_only)
|
||||
else:
|
||||
submit_result = {'success': False, 'error': f"Wholesaler {order['wholesaler_id']} not supported"}
|
||||
|
||||
@@ -1387,3 +1391,226 @@ def api_drugs_preferred_vendors():
|
||||
'count': len(results),
|
||||
'results': results
|
||||
})
|
||||
|
||||
|
||||
def submit_dongwon_order(order: dict, dry_run: bool, cart_only: bool = True) -> dict:
|
||||
"""
|
||||
동원약품 주문 제출
|
||||
|
||||
Args:
|
||||
order: 주문 정보
|
||||
dry_run: True=시뮬레이션만, False=실제 주문
|
||||
cart_only: True=장바구니만, False=주문 확정까지
|
||||
"""
|
||||
order_id = order['id']
|
||||
items = order['items']
|
||||
|
||||
# 상태 업데이트
|
||||
update_order_status(order_id, 'pending',
|
||||
f'동원 주문 시작 (dry_run={dry_run}, cart_only={cart_only})')
|
||||
|
||||
results = []
|
||||
success_count = 0
|
||||
failed_count = 0
|
||||
|
||||
try:
|
||||
from dongwon_api import get_dongwon_session
|
||||
dongwon_session = get_dongwon_session()
|
||||
|
||||
if dry_run:
|
||||
# ─────────────────────────────────────────
|
||||
# DRY RUN: 재고 확인만
|
||||
# ─────────────────────────────────────────
|
||||
for item in items:
|
||||
kd_code = item.get('kd_code') or item.get('drug_code')
|
||||
spec = item.get('specification', '')
|
||||
|
||||
# 재고 검색
|
||||
search_result = dongwon_session.search_products(kd_code)
|
||||
|
||||
matched = None
|
||||
available_specs = []
|
||||
spec_stocks = {}
|
||||
|
||||
if search_result.get('success'):
|
||||
for dongwon_item in search_result.get('items', []):
|
||||
s = dongwon_item.get('spec', '')
|
||||
available_specs.append(s)
|
||||
spec_stocks[s] = dongwon_item.get('stock', 0)
|
||||
|
||||
# 규격 매칭
|
||||
if spec in s or s in spec:
|
||||
if matched is None or dongwon_item.get('stock', 0) > matched.get('stock', 0):
|
||||
matched = dongwon_item
|
||||
|
||||
if matched:
|
||||
stock = matched.get('stock', 0)
|
||||
if stock >= item['order_qty']:
|
||||
status = 'success'
|
||||
result_code = 'OK'
|
||||
result_message = f"[DRY RUN] 주문 가능: 재고 {stock}, 단가 {matched.get('price', 0):,}원"
|
||||
success_count += 1
|
||||
elif stock > 0:
|
||||
status = 'failed'
|
||||
result_code = 'LOW_STOCK'
|
||||
result_message = f"[DRY RUN] 재고 부족: {stock}개 (요청: {item['order_qty']})"
|
||||
failed_count += 1
|
||||
else:
|
||||
status = 'failed'
|
||||
result_code = 'OUT_OF_STOCK'
|
||||
result_message = f"[DRY RUN] 재고 없음"
|
||||
failed_count += 1
|
||||
else:
|
||||
status = 'failed'
|
||||
result_code = 'NOT_FOUND'
|
||||
result_message = f"[DRY RUN] 동원에서 규격 {spec} 미발견"
|
||||
failed_count += 1
|
||||
|
||||
update_item_result(item['id'], status, result_code, result_message)
|
||||
|
||||
results.append({
|
||||
'item_id': item['id'],
|
||||
'drug_code': item.get('drug_code') or item.get('kd_code'),
|
||||
'product_name': item.get('product_name') or item.get('drug_name', ''),
|
||||
'specification': spec,
|
||||
'order_qty': item['order_qty'],
|
||||
'status': status,
|
||||
'result_code': result_code,
|
||||
'result_message': result_message,
|
||||
'matched_spec': matched.get('spec') if matched else None,
|
||||
'stock': matched.get('stock') if matched else 0,
|
||||
'price': matched.get('price') if matched else 0
|
||||
})
|
||||
|
||||
update_order_status(order_id, 'dry_run_complete',
|
||||
f'[DRY RUN] 완료: 성공 {success_count}, 실패 {failed_count}')
|
||||
|
||||
return {
|
||||
'success': True,
|
||||
'dry_run': dry_run,
|
||||
'cart_only': cart_only,
|
||||
'order_id': order_id,
|
||||
'order_no': order['order_no'],
|
||||
'wholesaler': 'dongwon',
|
||||
'total_items': len(items),
|
||||
'success_count': success_count,
|
||||
'failed_count': failed_count,
|
||||
'results': results
|
||||
}
|
||||
|
||||
else:
|
||||
# ─────────────────────────────────────────
|
||||
# 실제 주문: 장바구니 담기 (또는 주문 확정)
|
||||
# ─────────────────────────────────────────
|
||||
cart_items = []
|
||||
|
||||
for item in items:
|
||||
kd_code = item.get('kd_code') or item.get('drug_code')
|
||||
internal_code = item.get('dongwon_code') or item.get('internal_code')
|
||||
spec = item.get('specification', '')
|
||||
order_qty = item['order_qty']
|
||||
|
||||
# internal_code가 없으면 검색해서 찾기
|
||||
if not internal_code:
|
||||
search_result = dongwon_session.search_products(kd_code)
|
||||
if search_result.get('success') and search_result.get('items'):
|
||||
for dongwon_item in search_result['items']:
|
||||
s = dongwon_item.get('spec', '')
|
||||
if spec in s or s in spec:
|
||||
internal_code = dongwon_item.get('internal_code')
|
||||
break
|
||||
# 규격 매칭 안 되면 첫 번째 결과 사용
|
||||
if not internal_code and search_result['items']:
|
||||
internal_code = search_result['items'][0].get('internal_code')
|
||||
|
||||
product_name = item.get('product_name') or item.get('drug_name', '')
|
||||
|
||||
if internal_code:
|
||||
cart_items.append({
|
||||
'internal_code': internal_code,
|
||||
'quantity': order_qty
|
||||
})
|
||||
|
||||
update_item_result(item['id'], 'success', 'CART_READY',
|
||||
f'장바구니 준비 완료: {internal_code}')
|
||||
results.append({
|
||||
'item_id': item['id'],
|
||||
'drug_code': kd_code,
|
||||
'product_name': product_name,
|
||||
'specification': spec,
|
||||
'order_qty': order_qty,
|
||||
'status': 'success',
|
||||
'result_code': 'CART_READY',
|
||||
'result_message': f'장바구니 준비 완료: {internal_code}',
|
||||
'internal_code': internal_code
|
||||
})
|
||||
success_count += 1
|
||||
else:
|
||||
update_item_result(item['id'], 'failed', 'NOT_FOUND',
|
||||
f'동원에서 제품 미발견: {kd_code}')
|
||||
results.append({
|
||||
'item_id': item['id'],
|
||||
'drug_code': kd_code,
|
||||
'product_name': product_name,
|
||||
'specification': spec,
|
||||
'order_qty': order_qty,
|
||||
'status': 'failed',
|
||||
'result_code': 'NOT_FOUND',
|
||||
'result_message': f'동원에서 제품 미발견'
|
||||
})
|
||||
failed_count += 1
|
||||
|
||||
# safe_order 사용 (장바구니 백업/복구)
|
||||
if cart_items:
|
||||
if cart_only:
|
||||
# 장바구니만 담기
|
||||
for cart_item in cart_items:
|
||||
dongwon_session.add_to_cart(
|
||||
cart_item['internal_code'],
|
||||
cart_item['quantity']
|
||||
)
|
||||
update_order_status(order_id, 'cart_added',
|
||||
f'동원 장바구니 담기 완료: {len(cart_items)}개 품목')
|
||||
else:
|
||||
# safe_order로 주문 (기존 장바구니 백업/복구)
|
||||
order_result = dongwon_session.safe_order(
|
||||
items_to_order=cart_items,
|
||||
memo=order.get('memo', ''),
|
||||
dry_run=False
|
||||
)
|
||||
if order_result.get('success'):
|
||||
update_order_status(order_id, 'completed',
|
||||
f'동원 주문 완료: {order_result.get("ordered_count", 0)}개 품목')
|
||||
else:
|
||||
update_order_status(order_id, 'failed',
|
||||
f'동원 주문 실패: {order_result.get("error", "unknown")}')
|
||||
|
||||
# 응답 생성
|
||||
if cart_only:
|
||||
note = '동원약품 장바구니에 담김. 동원몰에서 최종 확정 필요.'
|
||||
else:
|
||||
note = None
|
||||
|
||||
return {
|
||||
'success': True,
|
||||
'dry_run': dry_run,
|
||||
'cart_only': cart_only,
|
||||
'order_id': order_id,
|
||||
'order_no': order['order_no'],
|
||||
'wholesaler': 'dongwon',
|
||||
'total_items': len(items),
|
||||
'success_count': success_count,
|
||||
'failed_count': failed_count,
|
||||
'results': results,
|
||||
'note': note
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"동원 주문 오류: {e}", exc_info=True)
|
||||
update_order_status(order_id, 'error', f'동원 주문 오류: {str(e)}')
|
||||
return {
|
||||
'success': False,
|
||||
'order_id': order_id,
|
||||
'wholesaler': 'dongwon',
|
||||
'error': str(e)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user