# All files / models analysisModel.js

0% Statements 0/16
100% Branches 0/0
0% Functions 0/1
0% Lines 0/16

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
    };