fix(sprint004): 코드 리뷰 반영 — vacation_days 소수 + 이중제출 방지 + deprecated 테이블 전환
- monthlyComparisonModel: vacation_types.deduct_days AS vacation_days 추가 - monthlyComparisonController: vacationDays++ → parseFloat(attend.vacation_days) 소수 지원 - monthly-comparison.js: confirmMonth/submitReject 이중 제출 방지 (isProcessing 플래그) - vacationBalanceModel: create/update/delete/bulkCreate → sp_vacation_balances + balance_type 매핑 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -36,7 +36,8 @@ const MonthlyComparisonModel = {
|
||||
dar.is_present,
|
||||
dar.notes,
|
||||
wat.type_name AS attendance_type_name,
|
||||
vt.type_name AS vacation_type_name
|
||||
vt.type_name AS vacation_type_name,
|
||||
vt.deduct_days AS vacation_days
|
||||
FROM daily_attendance_records dar
|
||||
LEFT JOIN work_attendance_types wat ON dar.attendance_type_id = wat.id
|
||||
LEFT JOIN vacation_types vt ON dar.vacation_type_id = vt.id
|
||||
@@ -162,34 +163,56 @@ const MonthlyComparisonModel = {
|
||||
return rows.map(r => r.user_id);
|
||||
},
|
||||
|
||||
// 7. 엑셀용 전체 일별 상세
|
||||
async getExcelData(year, month) {
|
||||
// 7. 출근부 엑셀용 — 작업자 목록 + 일별 근태 + 연차잔액
|
||||
async getExportData(year, month, departmentId) {
|
||||
const db = await getDb();
|
||||
const [rows] = await db.query(`
|
||||
SELECT
|
||||
w.worker_name, d.department_name, w.job_type,
|
||||
dar.record_date,
|
||||
dar.total_work_hours AS attendance_hours,
|
||||
wat.type_name AS attendance_type_name,
|
||||
vt.type_name AS vacation_type_name,
|
||||
COALESCE(wr.total_hours, 0) AS report_hours
|
||||
|
||||
// (a) 해당 부서 활성 작업자 (worker_id 순)
|
||||
let workerSql = `
|
||||
SELECT w.user_id, w.worker_id, w.worker_name, w.job_type,
|
||||
COALESCE(d.department_name, '미배정') AS department_name
|
||||
FROM workers w
|
||||
LEFT JOIN departments d ON w.department_id = d.department_id
|
||||
LEFT JOIN daily_attendance_records dar
|
||||
ON w.user_id = dar.user_id
|
||||
AND YEAR(dar.record_date) = ? AND MONTH(dar.record_date) = ?
|
||||
LEFT JOIN work_attendance_types wat ON dar.attendance_type_id = wat.id
|
||||
LEFT JOIN vacation_types vt ON dar.vacation_type_id = vt.id
|
||||
LEFT JOIN (
|
||||
SELECT user_id, report_date, SUM(work_hours) AS total_hours
|
||||
FROM daily_work_reports
|
||||
WHERE YEAR(report_date) = ? AND MONTH(report_date) = ?
|
||||
GROUP BY user_id, report_date
|
||||
) wr ON w.user_id = wr.user_id AND dar.record_date = wr.report_date
|
||||
WHERE w.status = 'active'
|
||||
ORDER BY d.department_name, w.worker_name, dar.record_date
|
||||
`, [year, month, year, month]);
|
||||
return rows;
|
||||
`;
|
||||
const workerParams = [];
|
||||
if (departmentId) { workerSql += ' AND w.department_id = ?'; workerParams.push(departmentId); }
|
||||
workerSql += ' ORDER BY w.worker_id';
|
||||
const [workers] = await db.query(workerSql, workerParams);
|
||||
|
||||
if (workers.length === 0) return { workers: [], attendance: [], vacations: [] };
|
||||
|
||||
const userIds = workers.map(w => w.user_id);
|
||||
const placeholders = userIds.map(() => '?').join(',');
|
||||
|
||||
// (b) 일별 근태 기록
|
||||
const [attendance] = await db.query(`
|
||||
SELECT dar.user_id, dar.record_date,
|
||||
dar.total_work_hours,
|
||||
dar.attendance_type_id,
|
||||
dar.vacation_type_id,
|
||||
vt.type_code AS vacation_type_code,
|
||||
vt.type_name AS vacation_type_name,
|
||||
vt.deduct_days
|
||||
FROM daily_attendance_records dar
|
||||
LEFT JOIN vacation_types vt ON dar.vacation_type_id = vt.id
|
||||
WHERE dar.user_id IN (${placeholders})
|
||||
AND YEAR(dar.record_date) = ? AND MONTH(dar.record_date) = ?
|
||||
ORDER BY dar.user_id, dar.record_date
|
||||
`, [...userIds, year, month]);
|
||||
|
||||
// (c) 연차 잔액 (sp_vacation_balances)
|
||||
const [vacations] = await db.query(`
|
||||
SELECT svb.user_id,
|
||||
SUM(svb.total_days) AS total_days,
|
||||
SUM(svb.used_days) AS used_days,
|
||||
SUM(svb.total_days - svb.used_days) AS remaining_days
|
||||
FROM sp_vacation_balances svb
|
||||
WHERE svb.user_id IN (${placeholders}) AND svb.year = ?
|
||||
GROUP BY svb.user_id
|
||||
`, [...userIds, year]);
|
||||
|
||||
return { workers, attendance, vacations };
|
||||
},
|
||||
|
||||
// 8. 작업자 정보
|
||||
|
||||
Reference in New Issue
Block a user