feat: 수인약품 주문 dry-run 지원

- order_api.py: submit_sooin_order() 함수 추가
- admin_rx_usage.html: 도매상별 주문 분기 처리
- 수인/지오영 모두 dry-run 테스트 가능
- 여러 도매상 품목 있을 때 선택 모달
This commit is contained in:
thug0bin
2026-03-06 12:24:15 +09:00
parent 7dda385b7f
commit 50455e63c7
2 changed files with 276 additions and 17 deletions

View File

@@ -1052,25 +1052,62 @@
}
// ──────────────── 주문 제출 ────────────────
let currentOrderWholesaler = null;
function submitOrder() {
if (cart.length === 0) return;
// 지오영 품목만 필터
const geoItems = cart.filter(c => c.supplier === '지오영' || c.geoyoung_code);
// 도매상별 분류
const geoItems = cart.filter(c => c.supplier === '지오영' || c.wholesaler === 'geoyoung');
const sooinItems = cart.filter(c => c.supplier === '수인약품' || c.wholesaler === 'sooin');
const otherItems = cart.filter(c => !geoItems.includes(c) && !sooinItems.includes(c));
if (geoItems.length === 0) {
// 지오영 품목 없으면 기존 방식 (클립보드)
if (geoItems.length === 0 && sooinItems.length === 0) {
// API 지원 안 되는 품목만 있으면 클립보드
submitOrderClipboard();
return;
}
// 지오영 주문 모달 열기
openOrderConfirmModal(geoItems);
// 도매상 선택 모달 열기 (여러 도매상 품목이 있을 때)
if (geoItems.length > 0 && sooinItems.length > 0) {
openWholesalerSelectModal(geoItems, sooinItems, otherItems);
} else if (geoItems.length > 0) {
openOrderConfirmModal('geoyoung', geoItems);
} else if (sooinItems.length > 0) {
openOrderConfirmModal('sooin', sooinItems);
}
}
function openOrderConfirmModal(items) {
function openWholesalerSelectModal(geoItems, sooinItems, otherItems) {
// 간단하게 지오영 먼저 처리
const msg = `장바구니에 여러 도매상 품목이 있습니다.\n\n` +
`🏭 지오영: ${geoItems.length}\n` +
`💊 수인약품: ${sooinItems.length}\n` +
(otherItems.length > 0 ? `📋 기타: ${otherItems.length}\n` : '') +
`\n어느 도매상부터 주문하시겠습니까?`;
if (confirm(msg + '\n\n[확인] = 지오영 먼저\n[취소] = 수인약품 먼저')) {
openOrderConfirmModal('geoyoung', geoItems);
} else {
openOrderConfirmModal('sooin', sooinItems);
}
}
function openOrderConfirmModal(wholesaler, items) {
currentOrderWholesaler = wholesaler;
const modal = document.getElementById('orderConfirmModal');
const tbody = document.getElementById('orderConfirmBody');
const header = modal.querySelector('.order-modal-header h3');
// 도매상별 헤더 스타일
if (wholesaler === 'sooin') {
header.innerHTML = '💊 수인약품 주문 확인';
modal.querySelector('.order-modal-header').style.background = 'linear-gradient(135deg, #7c3aed, #a855f7)';
} else {
header.innerHTML = '🏭 지오영 주문 확인';
modal.querySelector('.order-modal-header').style.background = 'linear-gradient(135deg, #0891b2, #06b6d4)';
}
let html = '';
items.forEach((item, idx) => {
@@ -1089,13 +1126,22 @@
function closeOrderConfirmModal() {
document.getElementById('orderConfirmModal').classList.remove('show');
currentOrderWholesaler = null;
}
async function executeOrder(dryRun = true) {
const geoItems = cart.filter(c => c.supplier === '지오영' || c.geoyoung_code);
const wholesaler = currentOrderWholesaler || 'geoyoung';
if (geoItems.length === 0) {
showToast('지오영 품목이 없습니다', 'error');
// 해당 도매상 품목 필터
let items;
if (wholesaler === 'sooin') {
items = cart.filter(c => c.supplier === '수인약품' || c.wholesaler === 'sooin');
} else {
items = cart.filter(c => c.supplier === '지오영' || c.wholesaler === 'geoyoung');
}
if (items.length === 0) {
showToast(`${wholesaler === 'sooin' ? '수인약품' : '지오영'} 품목이 없습니다`, 'error');
return;
}
@@ -1109,10 +1155,11 @@
try {
const payload = {
wholesaler_id: 'geoyoung',
items: geoItems.map(item => ({
wholesaler_id: wholesaler,
items: items.map(item => ({
drug_code: item.drug_code,
kd_code: item.geoyoung_code || item.drug_code,
kd_code: item.geoyoung_code || item.sooin_code || item.drug_code,
internal_code: item.internal_code,
product_name: item.product_name,
manufacturer: item.supplier,
specification: item.specification || '',
@@ -1124,8 +1171,8 @@
dry_run: dryRun
};
// 실제 주문은 시간이 오래 걸림 (Playwright 사용)
const timeoutMs = dryRun ? 60000 : 180000; // 테스트 1분, 실제 3분
// 타임아웃 설정
const timeoutMs = dryRun ? 120000 : 180000; // 테스트 2분, 실제 3분
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);