diff --git a/system1-factory/web/pages/attendance/annual-overview.html b/system1-factory/web/pages/attendance/annual-overview.html index 10cca91..f11e006 100644 --- a/system1-factory/web/pages/attendance/annual-overview.html +++ b/system1-factory/web/pages/attendance/annual-overview.html @@ -339,6 +339,22 @@ + +
+ @@ -497,7 +513,7 @@ return `로딩 중...
'; + document.getElementById('monthlyDetailModal').classList.add('active'); + + try { + const res = await axios.get(`/attendance/records?start_date=${year}-01-01&end_date=${year}-12-31&user_id=${userId}`); + const records = (res.data.data || []).filter(r => r.vacation_type_id); + + if (records.length === 0) { + document.getElementById('monthlyDetailBody').innerHTML = '연차 사용 내역이 없습니다
'; + return; + } + + // 월별 그룹핑 + const DAYS_KR = ['일', '월', '화', '수', '목', '금', '토']; + const monthly = {}; + const totals = { ANNUAL_FULL: 0, ANNUAL_HALF: 0, ANNUAL_QUARTER: 0, other: 0 }; + + records.forEach(r => { + const d = new Date(r.record_date); + const m = d.getMonth() + 1; + if (!monthly[m]) monthly[m] = { ANNUAL_FULL: 0, ANNUAL_HALF: 0, ANNUAL_QUARTER: 0, other: 0, total: 0 }; + const days = parseFloat(r.vacation_days) || 1; + const code = r.vacation_type_code || 'other'; + if (['ANNUAL_FULL', 'ANNUAL_HALF', 'ANNUAL_QUARTER'].includes(code)) { + monthly[m][code] += days; + totals[code] += days; + } else { + monthly[m].other += days; + totals.other += days; + } + monthly[m].total += days; + }); + + const grandTotal = totals.ANNUAL_FULL + totals.ANNUAL_HALF + totals.ANNUAL_QUARTER + totals.other; + + // 월별 요약 테이블 + let html = '| 월 | 연차 | 반차 | 반반차 | 합계 | '; + html += '
|---|---|---|---|---|
| ${m}월 | +${d.ANNUAL_FULL > 0 ? fmtNum(d.ANNUAL_FULL) : '-'} | +${d.ANNUAL_HALF > 0 ? fmtNum(d.ANNUAL_HALF) : '-'} | +${d.ANNUAL_QUARTER > 0 ? fmtNum(d.ANNUAL_QUARTER) : '-'} | +${fmtNum(d.total)} | +
| 합계 | +${fmtNum(totals.ANNUAL_FULL)} | +${fmtNum(totals.ANNUAL_HALF)} | +${fmtNum(totals.ANNUAL_QUARTER)} | +${fmtNum(grandTotal)} | +
데이터 로드 실패
'; + } + } + + function closeMonthlyDetail() { + document.getElementById('monthlyDetailModal').classList.remove('active'); + } + + document.getElementById('monthlyDetailModal').addEventListener('click', e => { + if (e.target.id === 'monthlyDetailModal') closeMonthlyDetail(); + }); + // ===== 저장 ===== async function saveAll() { const balancesToSave = [];