/* ===== 구매 분석 페이지 ===== */
const CAT_LABELS = { consumable: '소모품', safety: '안전용품', repair: '수선비', equipment: '설비' };
const CAT_ICONS = { consumable: 'fa-box', safety: 'fa-hard-hat', repair: 'fa-wrench', equipment: 'fa-cogs' };
const CAT_BG = { consumable: 'bg-blue-50 text-blue-700', safety: 'bg-green-50 text-green-700', repair: 'bg-amber-50 text-amber-700', equipment: 'bg-purple-50 text-purple-700' };
let currentYearMonth = '';
async function loadAnalysis() {
currentYearMonth = document.getElementById('paMonth').value;
if (!currentYearMonth) { showToast('월을 선택해주세요.', 'error'); return; }
try {
const [summaryRes, purchasesRes, priceChangesRes] = await Promise.all([
api(`/settlements/summary?year_month=${currentYearMonth}`),
api(`/settlements/purchases?year_month=${currentYearMonth}`),
api(`/settlements/price-changes?year_month=${currentYearMonth}`)
]);
renderCategorySummary(summaryRes.data?.categorySummary || []);
renderVendorSummary(summaryRes.data?.vendorSummary || []);
renderPurchaseList(purchasesRes.data || []);
renderPriceChanges(priceChangesRes.data || []);
} catch (e) {
showToast('데이터 로드 실패: ' + e.message, 'error');
}
}
function renderCategorySummary(data) {
const el = document.getElementById('paCategorySummary');
const allCategories = ['consumable', 'safety', 'repair', 'equipment'];
const dataMap = {};
data.forEach(d => { dataMap[d.category] = d; });
const totalAmount = data.reduce((sum, d) => sum + Number(d.total_amount || 0), 0);
el.innerHTML = allCategories.map(cat => {
const d = dataMap[cat] || { count: 0, total_amount: 0 };
const label = CAT_LABELS[cat];
const icon = CAT_ICONS[cat];
const bg = CAT_BG[cat];
return `
${Number(d.total_amount || 0).toLocaleString()}원
${d.count || 0}건
`;
}).join('') + `
월 합계: ${totalAmount.toLocaleString()}원
`;
}
function renderVendorSummary(data) {
const tbody = document.getElementById('paVendorSummary');
if (!data.length) {
tbody.innerHTML = '| 해당 월 구매 내역이 없습니다. |
';
return;
}
tbody.innerHTML = data.map(v => {
const isCompleted = v.settlement_status === 'completed';
const statusBadge = isCompleted
? '정산완료'
: '미정산';
const vendorName = v.vendor_name || '(업체 미지정)';
const vendorId = v.vendor_id || 0;
let actionBtn = '';
if (vendorId > 0) {
if (isCompleted) {
actionBtn = ``;
} else {
actionBtn = ``;
}
}
return `
| ${escapeHtml(vendorName)} |
${v.count}건 |
${Number(v.total_amount || 0).toLocaleString()}원 |
${statusBadge} |
${actionBtn} |
`;
}).join('');
}
function renderPurchaseList(data) {
const tbody = document.getElementById('paPurchaseList');
if (!data.length) {
tbody.innerHTML = '| 해당 월 구매 내역이 없습니다. |
';
return;
}
tbody.innerHTML = data.map(p => {
const catLabel = CAT_LABELS[p.category] || p.category;
const catColor = CAT_BG[p.category] || '';
const subtotal = (p.quantity || 0) * (p.unit_price || 0);
const basePrice = Number(p.base_price || 0);
const unitPrice = Number(p.unit_price || 0);
const hasPriceDiff = basePrice > 0 && unitPrice > 0 && basePrice !== unitPrice;
const priceDiffClass = hasPriceDiff ? (unitPrice > basePrice ? 'text-red-600 font-semibold' : 'text-blue-600 font-semibold') : '';
return `
|
${escapeHtml(p.item_name)}${p.spec ? ' [' + escapeHtml(p.spec) + ']' : ''}
${escapeHtml(p.maker || '')}
|
${catLabel} |
${p.quantity} |
${unitPrice.toLocaleString()}원${hasPriceDiff ? ` (기준: ${basePrice.toLocaleString()}) ` : ''} |
${subtotal.toLocaleString()}원 |
${escapeHtml(p.vendor_name || '-')} |
${formatDate(p.purchase_date)} |
${escapeHtml(p.notes || '')} |
`;
}).join('');
}
function renderPriceChanges(data) {
const el = document.getElementById('paPriceChanges');
if (!data.length) {
el.innerHTML = '가격 변동 항목이 없습니다.
';
return;
}
el.innerHTML = `
| 품목 |
기준가 |
실구매가 |
차이 |
업체 |
구매일 |
${data.map(p => {
const diff = Number(p.unit_price) - Number(p.base_price);
const arrow = diff > 0 ? '▲' : '▼';
const color = diff > 0 ? 'text-red-600' : 'text-blue-600';
return `
| ${escapeHtml(p.item_name)}${p.spec ? ' [' + escapeHtml(p.spec) + ']' : ''} ${p.maker ? '(' + escapeHtml(p.maker) + ')' : ''} |
${Number(p.base_price).toLocaleString()}원 |
${Number(p.unit_price).toLocaleString()}원 |
${arrow} ${Math.abs(diff).toLocaleString()}원 |
${escapeHtml(p.vendor_name || '-')} |
${formatDate(p.purchase_date)} |
`;
}).join('')}
`;
}
/* ===== 정산 처리 ===== */
async function completeSettlement(vendorId) {
if (!confirm('이 업체의 정산을 완료 처리하시겠습니까?')) return;
try {
await api('/settlements/complete', {
method: 'POST',
body: JSON.stringify({ year_month: currentYearMonth, vendor_id: vendorId })
});
showToast('정산 완료 처리되었습니다.');
await loadAnalysis();
} catch (e) { showToast(e.message, 'error'); }
}
async function cancelSettlement(vendorId) {
if (!confirm('정산 완료를 취소하시겠습니까?')) return;
try {
await api('/settlements/cancel', {
method: 'POST',
body: JSON.stringify({ year_month: currentYearMonth, vendor_id: vendorId })
});
showToast('정산이 취소되었습니다.');
await loadAnalysis();
} catch (e) { showToast(e.message, 'error'); }
}
/* ===== Init ===== */
(async function() {
if (!await initAuth()) return;
// 기본값: 현재 월
const now = new Date();
document.getElementById('paMonth').value = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}`;
})();