diff --git a/src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt b/src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt index 3778cc0..d923fa6 100644 --- a/src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt +++ b/src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt @@ -2100,47 +2100,95 @@ open class ReportService( return jdbcDao.queryForList(sql.toString(), args) } + open fun getProjectResourceOverconsumptionReport_projectInfo(args: Map): List> { + val sql = StringBuilder("SELECT" + + " t.projectId as id, " + + " p.code as projectCode, " + + " p.name as projectName, " + + " te.code as team, " + + " CONCAT( c.code, ' - ' ,c.name ) as client, " + + " COALESCE(concat(sub.code, ' - ', sub.name), 'N/A') as subsidaiary, " + + " (p.expectedTotalFee - ifnull(p.subContractFee, 0)) * 0.8 as plannedBudget " + + " from timesheet t " + + " left join project p on p.id = t.projectId " + + " left join team te on te.teamLead = p.teamLead " + + " left join customer c ON p.customerId = c.id " + + " left join subsidiary sub on sub.id = p.customerSubsidiaryId " + + " where t.projectid is not NULL " + + " and p.deleted = false " + + " and p.status = 'On-going' " + ) + if (args != null) { + if (args.containsKey("teamId")) + sql.append(" and tm.id = :teamId") + if (args.containsKey("custId")) + sql.append(" and c.id = :custId") + if (args.containsKey("subsidiaryId")) + sql.append(" and ss.id = :subsidiaryId") + } + sql.append(" group by t.projectId; ") + return jdbcDao.queryForList(sql.toString(), args) + } + + open fun getProjectResourceOverconsumptionReport_timesheetInfo(): List> { + val sql = StringBuilder("SELECT" + + " t.*, " + + " sal.hourlyRate " + + " from timesheet t " + + " left join staff s on s.id = t.staffId " + + " left join salary sal on sal.salaryPoint = s.salaryId " + + " where t.deleted = false " + ) + return jdbcDao.queryForList(sql.toString()) + } + open fun getProjectResourceOverconsumptionReport(args: Map): List> { val sql = StringBuilder( - "SELECT" - + " p.code, " - + " p.name, " - + " tm.code as team, " - + " concat(c.code, ' - ',c.name) as client, " - + " COALESCE(concat(ss.code, ' - ', ss.name), 'N/A') as subsidiary, " - + " (p.expectedTotalFee - ifnull(p.subContractFee, 0)) * 0.8 as plannedBudget, " - + " sum(t.consumedBudget) as actualConsumedBudget, " - + " COALESCE(p.totalManhour, 0) as plannedManhour, " - + " sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) as actualConsumedManhour, " - + " sum(t.consumedBudget) / ((p.expectedTotalFee - ifnull(p.subContractFee, 0)) * 0.8) as budgetConsumptionRate, " - + " sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) / COALESCE(p.totalManhour, 0) as manhourConsumptionRate, " - + " case " - + " when sum(t.consumedBudget) / ((p.expectedTotalFee - ifnull(p.subContractFee, 0)) * 0.8) >= 1 " - + " or (sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) / COALESCE(p.totalManhour, 0)) >= 1 " - + " then 'Overconsumption' " - + " when sum(t.consumedBudget) / ((p.expectedTotalFee - ifnull(p.subContractFee, 0)) * 0.8) >= :lowerLimit and sum(t.consumedBudget) / ((p.expectedTotalFee - ifnull(p.subContractFee, 0)) * 0.8) <= 1 " - + " or (sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) / COALESCE(p.totalManhour, 0)) >= :lowerLimit and (sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) / COALESCE(p.totalManhour, 0)) <= 1 " - + " then 'Potential Overconsumption' " - + " else 'Within Budget' " - + " END as status " - + " from " - + " (SELECT " - + " t.*, " - + " (t.normalConsumed + COALESCE(t.otConsumed, 0)) * sal.hourlyRate as consumedBudget " - + " from timesheet t " - + " left join staff s on s.id = t.staffId " - + " left join salary sal on sal.salaryPoint = s.salaryId ) t " - + " left join project p on p.id = t.projectId " - + " left join team tm on p.teamLead = tm.teamLead " - + " left join customer c on c.id = p.customerId " - + " LEFT JOIN subsidiary ss on p.customerSubsidiaryId = ss.id " - + " WHERE p.deleted = false " - + " and p.status = 'On-going' " + "SELECT" + + " p.code, " + + " p.name, " + + " tm.code as team, " + + " concat(c.code, ' - ',c.name) as client, " + + " COALESCE(concat(ss.code, ' - ', ss.name), 'N/A') as subsidiary, " + + " (p.expectedTotalFee - ifnull(p.subContractFee, 0)) * 0.8 as plannedBudget, " + + " sum(t.consumedBudget) as actualConsumedBudget, " + + " COALESCE(p.totalManhour, 0) as plannedManhour, " + + " sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) as actualConsumedManhour, " + + " sum(t.consumedBudget) / ((p.expectedTotalFee - ifnull(p.subContractFee, 0)) * 0.8) as budgetConsumptionRate, " + + " sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) / COALESCE(p.totalManhour, 0) as manhourConsumptionRate, " + + " case " + + " when sum(t.consumedBudget) / ((p.expectedTotalFee - ifnull(p.subContractFee, 0)) * 0.8) >= 1 " + + " or (sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) / COALESCE(p.totalManhour, 0)) >= 1 " + + " then 'Overconsumption' " + + " when sum(t.consumedBudget) / ((p.expectedTotalFee - ifnull(p.subContractFee, 0)) * 0.8) >= :lowerLimit and sum(t.consumedBudget) / ((p.expectedTotalFee - ifnull(p.subContractFee, 0)) * 0.8) <= 1 " + + " or (sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) / COALESCE(p.totalManhour, 0)) >= :lowerLimit and (sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) / COALESCE(p.totalManhour, 0)) <= 1 " + + " then 'Potential Overconsumption' " + + " else 'Within Budget' " + + " END as status " + + " from " + + " (SELECT t.*, (t.normalConsumed + COALESCE(t.otConsumed, 0)) * sal.hourlyRate as consumedBudget " + + " FROM " + + " ( " + + " SELECT t.id AS tid, max(se.date) AS max_date " + + " FROM timesheet t " + + " INNER JOIN salary_effective se ON se.staffId = t.staffId AND se.date <= t.recordDate " + + " GROUP BY t.id " + + " ) max_se " + + " LEFT JOIN timesheet t ON t.id = max_se.tid " + + " LEFT JOIN staff s on s.id = t.staffId " + + " inner join salary_effective se on se.date = max_se.max_date " + + " left join salary sal on se.salaryId = sal.salaryPoint) t " + + " left join project p on p.id = t.projectId " + + " left join team tm on p.teamLead = tm.teamLead " + + " left join customer c on c.id = p.customerId " + + " LEFT JOIN subsidiary ss on p.customerSubsidiaryId = ss.id " + + " WHERE p.deleted = false " + + " and p.status = 'On-going' " ) var statusFilter: String = "" if (args != null) { if (args.containsKey("teamId")) - sql.append(" and t.id = :teamId") + sql.append(" and tm.id = :teamId") if (args.containsKey("custId")) sql.append(" and c.id = :custId") if (args.containsKey("subsidiaryId"))