// /models/analysisModel.js const { getDb } = require('../dbPool'); /** * 지정된 기간 동안의 작업 보고서 데이터를 집계하여 분석합니다. * 이 함수는 여러 개의 SQL 쿼리를 병렬로 실행하여 효율성을 높입니다. * @param {string} startDate - 시작일 (YYYY-MM-DD) * @param {string} endDate - 종료일 (YYYY-MM-DD) * @returns {Promise} - 요약, 프로젝트별, 작업자별, 작업별 집계 데이터 및 상세 내역 */ const getAnalysis = async (startDate, endDate) => { try { const db = await getDb(); // SQL 쿼리에서 반복적으로 사용될 WHERE 조건과 실제 투입 시간 계산 로직 const whereClause = `WHERE dwr.report_date BETWEEN ? AND ?`; const workHoursCalc = ` CASE dwr.work_details WHEN '연차' THEN 0 WHEN '반차' THEN 4 WHEN '반반차' THEN 6 WHEN '조퇴' THEN 2 WHEN '휴무' THEN 0 WHEN '유급' THEN 0 ELSE 8 END + (COALESCE(dwr.overtime_hours, 0) * 1.5) `; // 1. 요약 정보 쿼리 const summarySql = ` SELECT COUNT(DISTINCT dwr.project_id) as totalProjects, COUNT(DISTINCT dwr.worker_id) as totalworkers, COUNT(DISTINCT dwr.task_id) as totalTasks, SUM(${workHoursCalc}) as totalHours FROM DailyWorkReports dwr ${whereClause} AND (${workHoursCalc}) > 0 `; // 2. 프로젝트별 집계 쿼리 const byProjectSql = ` SELECT p.project_name as name, SUM(${workHoursCalc}) as hours, COUNT(DISTINCT dwr.worker_id) as participants FROM DailyWorkReports dwr JOIN Projects p ON dwr.project_id = p.project_id ${whereClause} GROUP BY p.project_name HAVING hours > 0 ORDER BY hours DESC; `; // 3. 작업자별 집계 쿼리 const byWorkerSql = ` SELECT w.worker_name as name, SUM(${workHoursCalc}) as hours, COUNT(DISTINCT dwr.project_id) as participants FROM DailyWorkReports dwr JOIN workers w ON dwr.worker_id = w.worker_id ${whereClause} GROUP BY w.worker_name HAVING hours > 0 ORDER BY hours DESC; `; // 4. 작업별 집계 쿼리 const byTaskSql = ` SELECT t.category as name, SUM(${workHoursCalc}) as hours, COUNT(DISTINCT dwr.worker_id) as participants FROM DailyWorkReports dwr JOIN Tasks t ON dwr.task_id = t.task_id ${whereClause} GROUP BY t.category HAVING hours > 0 ORDER BY hours DESC; `; // 5. 상세 내역 쿼리 const detailsSql = ` SELECT dwr.report_date as date, p.project_name, w.worker_name, t.category as task_category, dwr.work_details, (${workHoursCalc}) as work_hours, dwr.memo FROM DailyWorkReports dwr JOIN Projects p ON dwr.project_id = p.project_id JOIN workers w ON dwr.worker_id = w.worker_id JOIN Tasks t ON dwr.task_id = t.task_id ${whereClause} HAVING work_hours > 0 ORDER BY dwr.report_date DESC; `; // 모든 쿼리를 병렬로 실행 const [ [summaryResult], [byProject], [byWorker], [byTask], [details] ] = await Promise.all([ db.query(summarySql, [startDate, endDate]), db.query(byProjectSql, [startDate, endDate]), db.query(byWorkerSql, [startDate, endDate]), db.query(byTaskSql, [startDate, endDate]), db.query(detailsSql, [startDate, endDate]) ]); return { summary: summaryResult[0], byProject, byWorker, byTask, details }; } catch (err) { console.error('[Model] 분석 데이터 조회 오류:', err); throw new Error('데이터베이스에서 분석 데이터를 조회하는 중 오류가 발생했습니다.'); } }; module.exports = { getAnalysis };