const { getPool } = require('../middleware/auth'); const vacationDashboardModel = { async getSummary(year) { const db = getPool(); const [rows] = await db.query(` SELECT d.department_id, COALESCE(d.department_name, '미배정') as department_name, COUNT(DISTINCT su.user_id) as employee_count, AVG(vb.total_days - vb.used_days) as avg_remaining, SUM(CASE WHEN (vb.total_days - vb.used_days) <= 2 THEN 1 ELSE 0 END) as low_balance_count FROM sso_users su LEFT JOIN departments d ON su.department_id = d.department_id LEFT JOIN sp_vacation_balances vb ON su.user_id = vb.user_id AND vb.year = ? AND vb.balance_type = 'AUTO' WHERE su.is_active = 1 GROUP BY d.department_id `, [year]); return rows; }, async getEmployeeList(year, filters = {}) { const db = getPool(); let query = ` SELECT su.user_id, su.name, su.username, su.hire_date, su.department_id, COALESCE(d.department_name, '미배정') as department_name, vb.id, vb.balance_type, vb.total_days, vb.used_days, (vb.total_days - vb.used_days) as remaining_days, vb.expires_at, vt.type_name, vt.type_code FROM sso_users su LEFT JOIN departments d ON su.department_id = d.department_id LEFT JOIN sp_vacation_balances vb ON su.user_id = vb.user_id AND (vb.year = ? OR (vb.balance_type = 'LONG_SERVICE' AND vb.expires_at IS NULL)) LEFT JOIN vacation_types vt ON vb.vacation_type_id = vt.id WHERE su.is_active = 1 `; const params = [year]; if (filters.department_id) { query += ' AND su.department_id = ?'; params.push(filters.department_id); } if (filters.search_name) { query += ' AND su.name LIKE ?'; params.push(`%${filters.search_name}%`); } query += ' ORDER BY su.name ASC'; const [rows] = await db.query(query, params); return rows; }, // View 1: 연간 총괄 — 전직원 월별 사용 합계 async getYearlyOverview(year) { const db = getPool(); const [rows] = await db.query(` SELECT su.user_id, su.name, su.username, su.hire_date, COALESCE(d.department_id, 0) as department_id, COALESCE(d.department_name, '미배정') as department_name, MONTH(vr.start_date) as month, SUM(vr.days_used) as total_days FROM sso_users su LEFT JOIN departments d ON su.department_id = d.department_id LEFT JOIN sp_vacation_requests vr ON su.user_id = vr.user_id AND vr.status = 'approved' AND YEAR(vr.start_date) = ? WHERE su.is_active = 1 AND su.hire_date IS NOT NULL GROUP BY su.user_id, MONTH(vr.start_date) ORDER BY d.department_name, su.name `, [year]); return rows; }, // View 1: 연간 부여/사용 잔액 async getBalances(year) { const db = getPool(); const [rows] = await db.query(` SELECT user_id, SUM(total_days) as granted, SUM(used_days) as used FROM sp_vacation_balances WHERE year = ? AND balance_type = 'AUTO' GROUP BY user_id `, [year]); return rows; }, // View 2: 월간 상세 — 부서 전직원 일별 휴가 ($1=year ON, $2=month ON, $3=deptId WHERE, $4=deptId WHERE) async getMonthlyDetail(year, month, departmentId) { const db = getPool(); const [rows] = await db.query(` SELECT su.user_id, su.name, su.username, vr.request_id, vr.start_date, vr.end_date, vr.days_used, vt.type_code, vt.type_name FROM sso_users su LEFT JOIN sp_vacation_requests vr ON su.user_id = vr.user_id AND vr.status = 'approved' AND YEAR(vr.start_date) = ? AND MONTH(vr.start_date) = ? LEFT JOIN vacation_types vt ON vr.vacation_type_id = vt.id WHERE su.is_active = 1 AND su.hire_date IS NOT NULL AND (su.department_id = ? OR (? = 0 AND su.department_id IS NULL)) ORDER BY su.name, vr.start_date `, [year, month, departmentId, departmentId]); return rows; }, // View 1: 전사 휴가 차감 내역 async getCompanyDeductions(year) { const db = getPool(); const [rows] = await db.query(` SELECT holiday_date, holiday_name, MONTH(holiday_date) as month FROM company_holidays WHERE YEAR(holiday_date) = ? AND holiday_type = 'ANNUAL_DEDUCT' AND deduction_applied_at IS NOT NULL `, [year]); return rows; }, // View 2: 공휴일 표시용 async getHolidays(year, month) { const db = getPool(); const [rows] = await db.query(` SELECT holiday_date, holiday_name, holiday_type, deduction_applied_at FROM company_holidays WHERE YEAR(holiday_date) = ? AND MONTH(holiday_date) = ? `, [year, month]); return rows; } }; module.exports = vacationDashboardModel;