Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | // /models/analysisModel.js
const { getDb } = require('../dbPool');
/**
* 지정된 기간 동안의 작업 보고서 데이터를 집계하여 분석합니다.
* 이 함수는 여러 개의 SQL 쿼리를 병렬로 실행하여 효율성을 높입니다.
* @param {string} startDate - 시작일 (YYYY-MM-DD)
* @param {string} endDate - 종료일 (YYYY-MM-DD)
* @returns {Promise<object>} - 요약, 프로젝트별, 작업자별, 작업별 집계 데이터 및 상세 내역
*/
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
}; |