refactor: 도매상 설정 중앙화 (WHOLESALERS 객체)

- WHOLESALERS 객체로 도매상 정보 일원화
- 향후 도매상 추가 시 객체에만 추가하면 됨
- 결과 모달에 도매상명, 아이콘, 색상 적용
- 단가 정보 결과에 표시
This commit is contained in:
thug0bin 2026-03-06 12:29:11 +09:00
parent 50455e63c7
commit f625a08091

View File

@ -1051,6 +1051,31 @@
document.getElementById('cartDrawer').classList.remove('open');
}
// ──────────────── 도매상 설정 (확장 가능) ────────────────
const WHOLESALERS = {
geoyoung: {
id: 'geoyoung',
name: '지오영',
icon: '🏭',
logo: '/static/img/logo_geoyoung.ico',
color: '#06b6d4',
gradient: 'linear-gradient(135deg, #0891b2, #06b6d4)',
filterFn: (item) => item.supplier === '지오영' || item.wholesaler === 'geoyoung',
getCode: (item) => item.geoyoung_code || item.drug_code
},
sooin: {
id: 'sooin',
name: '수인약품',
icon: '💊',
logo: '/static/img/logo_sooin.svg',
color: '#a855f7',
gradient: 'linear-gradient(135deg, #7c3aed, #a855f7)',
filterFn: (item) => item.supplier === '수인약품' || item.wholesaler === 'sooin',
getCode: (item) => item.sooin_code || item.drug_code
}
// 향후 추가: baekje, etc.
};
// ──────────────── 주문 제출 ────────────────
let currentOrderWholesaler = null;
@ -1058,56 +1083,69 @@
if (cart.length === 0) return;
// 도매상별 분류
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));
const itemsByWholesaler = {};
let otherItems = [...cart];
if (geoItems.length === 0 && sooinItems.length === 0) {
for (const [wsId, ws] of Object.entries(WHOLESALERS)) {
const wsItems = cart.filter(ws.filterFn);
if (wsItems.length > 0) {
itemsByWholesaler[wsId] = wsItems;
otherItems = otherItems.filter(item => !wsItems.includes(item));
}
}
const wsIds = Object.keys(itemsByWholesaler);
if (wsIds.length === 0) {
// API 지원 안 되는 품목만 있으면 클립보드
submitOrderClipboard();
return;
}
// 도매상 선택 모달 열기 (여러 도매상 품목이 있을 때)
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 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);
// 여러 도매상 품목이 있을 때 선택 모달
if (wsIds.length > 1) {
openWholesalerSelectModal(itemsByWholesaler, otherItems);
} else {
openOrderConfirmModal('sooin', sooinItems);
openOrderConfirmModal(wsIds[0], itemsByWholesaler[wsIds[0]]);
}
}
function openOrderConfirmModal(wholesaler, items) {
currentOrderWholesaler = wholesaler;
function openWholesalerSelectModal(itemsByWholesaler, otherItems) {
let msg = `장바구니에 여러 도매상 품목이 있습니다.\n\n`;
const wsIds = Object.keys(itemsByWholesaler);
wsIds.forEach(wsId => {
const ws = WHOLESALERS[wsId];
msg += `${ws.icon} ${ws.name}: ${itemsByWholesaler[wsId].length}개\n`;
});
if (otherItems.length > 0) {
msg += `📋 기타: ${otherItems.length}개\n`;
}
msg += `\n어느 도매상부터 주문하시겠습니까?`;
msg += `\n\n[확인] = ${WHOLESALERS[wsIds[0]].name} 먼저`;
msg += `\n[취소] = ${WHOLESALERS[wsIds[1]].name} 먼저`;
if (confirm(msg)) {
openOrderConfirmModal(wsIds[0], itemsByWholesaler[wsIds[0]]);
} else {
openOrderConfirmModal(wsIds[1], itemsByWholesaler[wsIds[1]]);
}
}
function openOrderConfirmModal(wholesalerId, items) {
currentOrderWholesaler = wholesalerId;
const ws = WHOLESALERS[wholesalerId];
const modal = document.getElementById('orderConfirmModal');
const tbody = document.getElementById('orderConfirmBody');
const header = modal.querySelector('.order-modal-header h3');
const headerDiv = modal.querySelector('.order-modal-header');
// 도매상별 헤더 스타일
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)';
}
header.innerHTML = `${ws.icon} ${ws.name} 주문 확인`;
headerDiv.style.background = ws.gradient;
let html = '';
items.forEach((item, idx) => {
@ -1209,6 +1247,16 @@
function showOrderResultModal(result) {
const modal = document.getElementById('orderResultModal');
const content = document.getElementById('orderResultContent');
const header = modal.querySelector('.order-modal-header h3');
const headerDiv = modal.querySelector('.order-modal-header');
// 도매상 정보 가져오기
const wholesalerId = result.wholesaler || currentOrderWholesaler || 'geoyoung';
const ws = WHOLESALERS[wholesalerId] || WHOLESALERS.geoyoung;
// 결과 모달 헤더 스타일 적용
header.innerHTML = `${ws.icon} ${ws.name} 주문 결과`;
headerDiv.style.background = ws.gradient;
const isDryRun = result.dry_run;
const statusEmoji = result.failed_count === 0 ? '✅' : result.success_count === 0 ? '❌' : '⚠️';
@ -1216,9 +1264,13 @@
let html = `
<div class="result-header ${result.failed_count === 0 ? 'success' : 'partial'}">
<span class="result-emoji">${statusEmoji}</span>
<span class="result-title">${isDryRun ? '[테스트]' : ''} 주문 ${result.failed_count === 0 ? '완료' : '처리됨'}</span>
<span class="result-title">${isDryRun ? '[테스트]' : ''} ${ws.name} 주문 ${result.failed_count === 0 ? '완료' : '처리됨'}</span>
</div>
<div class="result-summary">
<div class="result-stat">
<span class="stat-label">도매상</span>
<span class="stat-value">${ws.icon} ${ws.name}</span>
</div>
<div class="result-stat">
<span class="stat-label">주문번호</span>
<span class="stat-value mono">${result.order_no}</span>
@ -1245,6 +1297,7 @@
<td class="${isSuccess ? 'result-ok' : 'result-fail'}">
${isSuccess ? '✓' : '✗'} ${item.result_code}
${item.result_message ? `<br><small>${escapeHtml(item.result_message)}</small>` : ''}
${item.price ? `<br><small style="color:var(--accent-amber)">단가: ${item.price.toLocaleString()}원</small>` : ''}
</td>
</tr>`;
});
@ -1255,6 +1308,11 @@
html += `<div class="result-note">💡 테스트 모드입니다. 실제 주문은 "실제 주문" 버튼을 누르세요.</div>`;
}
// 수인약품 실제 주문 시 안내
if (!isDryRun && wholesalerId === 'sooin' && result.note) {
html += `<div class="result-note" style="background:rgba(168,85,247,0.1);color:#a855f7;">📌 ${result.note}</div>`;
}
content.innerHTML = html;
modal.classList.add('show');
}