/* tkpurchase-workreport-summary.js - Work report summary page */ async function loadCompaniesForFilter() { try { const r = await api('/partners?limit=100'); const list = r.data || []; const sel = document.getElementById('filterCompany'); list.forEach(c => { const opt = document.createElement('option'); opt.value = c.id; opt.textContent = c.company_name; sel.appendChild(opt); }); } catch(e) { console.warn('Load companies error:', e); } } async function loadSchedulesForFilter() { try { const r = await api('/schedules?limit=200'); const list = r.data || []; const sel = document.getElementById('filterSchedule'); list.forEach(s => { const opt = document.createElement('option'); opt.value = s.id; opt.textContent = (s.workplace_name || '') + ' - ' + (s.work_description || '').substring(0, 30); sel.appendChild(opt); }); } catch(e) { console.warn('Load schedules error:', e); } } function getFilterQuery() { const companyId = document.getElementById('filterCompany').value; const scheduleId = document.getElementById('filterSchedule').value; const dateFrom = document.getElementById('filterDateFrom').value; const dateTo = document.getElementById('filterDateTo').value; if (!dateFrom || !dateTo) { showToast('기간을 선택해주세요', 'error'); return null; } let query = `?date_from=${dateFrom}&date_to=${dateTo}`; if (companyId) query += '&company_id=' + companyId; if (scheduleId) query += '&schedule_id=' + scheduleId; return query; } async function loadSummary() { const query = getFilterQuery(); if (!query) return; const tbody = document.getElementById('summaryTableBody'); tbody.innerHTML = '로딩 중...'; try { const r = await api('/work-reports/summary' + query); renderSummaryTable(r.data || []); } catch(e) { tbody.innerHTML = '' + escapeHtml(e.message || '로딩 실패') + ''; } } function renderSummaryTable(list) { const tbody = document.getElementById('summaryTableBody'); if (!list.length) { tbody.innerHTML = '데이터가 없습니다'; return; } let totalReports = 0, totalWorkers = 0, totalHours = 0; tbody.innerHTML = list.map(r => { totalReports += parseInt(r.report_count) || 0; totalWorkers += parseInt(r.total_workers) || 0; totalHours += parseFloat(r.total_hours) || 0; const progressColor = r.avg_progress >= 80 ? 'bg-emerald-500' : r.avg_progress >= 50 ? 'bg-blue-500' : r.avg_progress >= 20 ? 'bg-amber-500' : 'bg-red-500'; const confirmText = r.confirmed_count + '/' + r.report_count; return ` ${formatDate(r.report_date)} ${escapeHtml(r.company_name || '')} ${escapeHtml(r.workplace_name || '')} ${r.report_count}건 ${r.total_workers}명 ${Number(r.total_hours).toFixed(1)}h
${r.avg_progress || 0}%
${confirmText} `; }).join(''); // 합계 행 tbody.insertAdjacentHTML('beforeend', ` 합계 ${totalReports}건 ${totalWorkers}명 ${totalHours.toFixed(1)}h `); } function exportExcel() { const query = getFilterQuery(); if (!query) return; const token = getToken(); const url = API_BASE + '/work-reports/export' + query; // fetch로 다운로드 (인증 헤더 포함) fetch(url, { headers: { 'Authorization': token ? 'Bearer ' + token : '' } }) .then(res => { if (!res.ok) return res.json().then(d => { throw new Error(d.error || '다운로드 실패'); }); return res.blob(); }) .then(blob => { const a = document.createElement('a'); a.href = URL.createObjectURL(blob); const dateFrom = document.getElementById('filterDateFrom').value; const dateTo = document.getElementById('filterDateTo').value; a.download = '업무현황_' + dateFrom + '_' + dateTo + '.xlsx'; a.click(); URL.revokeObjectURL(a.href); showToast('엑셀 다운로드 완료'); }) .catch(e => showToast(e.message || '다운로드 실패', 'error')); } function initSummaryPage() { if (!initAuth()) return; // 기본 기간: 이번 달 const now = new Date(); const firstDay = new Date(now.getFullYear(), now.getMonth(), 1); document.getElementById('filterDateFrom').value = firstDay.toISOString().substring(0, 10); document.getElementById('filterDateTo').value = now.toISOString().substring(0, 10); loadCompaniesForFilter(); loadSchedulesForFilter(); loadSummary(); }