瀏覽代碼

overconsumption report

tags/Baseline_30082024_BACKEND_UAT
MSI\derek 1 年之前
父節點
當前提交
c300424500
共有 1 個文件被更改,包括 45 次插入47 次删除
  1. +45
    -47
      src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt

+ 45
- 47
src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt 查看文件

@@ -2026,53 +2026,51 @@ open class ReportService(
}

open fun getProjectResourceOverconsumptionReport(args: Map<String, Any>): List<Map<String, Any>> {
val sql = StringBuilder(
"with teamNormalConsumed as ("
+ " SELECT"
+ " t.projectId,"
+ " p.teamLead,"
+ " sum(t.normalConsumed) as normalConsumed,"
+ " sum(t.otConsumed) as otConsumed,"
+ " sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) as totalConsumed,"
+ " sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) * sal.hourlyRate as totalBudget"
+ " from timesheet t"
+ " left join project p on p.id = t.projectId"
+ " left join staff s on s.id = p.teamLead"
+ " left join salary sal on sal.salaryPoint = s.salaryId"
+ " group by p.teamLead, t.projectId, sal.hourlyRate"
+ " )"
+ " SELECT"
+ " p.id,"
+ " p.code,"
+ " p.name,"
+ " t.code,"
+ " concat(c.code, ' - ',c.name) as client,"
+ " COALESCE(concat(ss.code, ' - ', ss.name), 'N/A') as subsidiary,"
+ " p.expectedTotalFee * 0.8 as plannedBudget,"
+ " COALESCE(tns.totalBudget, 0) as actualConsumedBudget,"
+ " tns.totalConsumed,"
+ " COALESCE(p.totalManhour, 0) as plannedManhour,"
+ " COALESCE(tns.totalConsumed, 0) as actualConsumedManhour,"
+ " (COALESCE((tns.totalConsumed * sa.hourlyRate), 0) / p.expectedTotalFee) as budgetConsumptionRate,"
+ " (COALESCE(tns.totalConsumed, 0) / COALESCE(p.totalManhour, 0)) as manhourConsumptionRate,"
+ " CASE"
+ " when (COALESCE((tns.totalConsumed * sa.hourlyRate), 0) / p.expectedTotalFee) >= :lowerLimit and (COALESCE((tns.totalConsumed * sa.hourlyRate), 0) / p.expectedTotalFee) <= 1"
+ " or (COALESCE(tns.totalConsumed, 0) / COALESCE(p.totalManhour, 0)) >= :lowerLimit and (COALESCE(tns.totalConsumed, 0) / COALESCE(p.totalManhour, 0)) <= 1"
+ " then 'Potential Overconsumption'"
+ " when (COALESCE((tns.totalConsumed * sa.hourlyRate), 0) / p.expectedTotalFee) >= 1"
+ " or (COALESCE(tns.totalConsumed, 0) / COALESCE(p.totalManhour, 0)) >= 1"
+ " then 'Overconsumption'"
+ " else 'Within Budget'"
+ " END as status"
+ " from project p"
+ " left join staff s on s.id = p.teamLead"
+ " left join team t on t.id = s.teamId"
+ " left join customer c on c.id = p.customerId"
+ " LEFT JOIN subsidiary ss on p.customerSubsidiaryId = ss.id"
+ " LEFT JOIN salary sa ON s.salaryId = sa.salaryPoint"
+ " left join teamNormalConsumed tns on tns.projectId = p.id"
+ " WHERE p.deleted = false "
+ " and p.status = 'On-going' "
val sql = StringBuilder("with teamNormalConsumed as ("
+ " SELECT"
+ " t.projectId,"
+ " p.teamLead,"
+ " sum(t.normalConsumed) as normalConsumed,"
+ " sum(t.otConsumed) as otConsumed,"
+ " sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) as totalConsumed,"
+ " sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) * sal.hourlyRate as totalBudget"
+ " from timesheet t"
+ " left join project p on p.id = t.projectId"
+ " left join staff s on s.id = p.teamLead"
+ " left join salary sal on sal.salaryPoint = s.salaryId"
+ " group by p.teamLead, t.projectId, sal.hourlyRate"
+ " )"
+ " SELECT"
+ " p.id,"
+ " p.code,"
+ " p.name,"
+ " t.code,"
+ " concat(c.code, ' - ',c.name) as client,"
+ " COALESCE(concat(ss.code, ' - ', ss.name), 'N/A') as subsidiary,"
+ " p.expectedTotalFee * 0.8 as plannedBudget,"
+ " COALESCE(tns.totalBudget, 0) as actualConsumedBudget,"
+ " COALESCE(p.totalManhour, 0) as plannedManhour,"
+ " COALESCE(tns.totalConsumed, 0) as actualConsumedManhour,"
+ " (COALESCE((tns.totalConsumed * sa.hourlyRate), 0) / p.expectedTotalFee) as budgetConsumptionRate,"
+ " (COALESCE(tns.totalConsumed, 0) / COALESCE(p.totalManhour, 0)) as manhourConsumptionRate,"
+ " CASE"
+ " when (COALESCE((tns.totalConsumed * sa.hourlyRate), 0) / p.expectedTotalFee) >= :lowerLimit and (COALESCE((tns.totalConsumed * sa.hourlyRate), 0) / p.expectedTotalFee) <= 1"
+ " or (COALESCE(tns.totalConsumed, 0) / COALESCE(p.totalManhour, 0)) >= :lowerLimit and (COALESCE(tns.totalConsumed, 0) / COALESCE(p.totalManhour, 0)) <= 1"
+ " then 'Potential Overconsumption'"
+ " when (COALESCE((tns.totalConsumed * sa.hourlyRate), 0) / p.expectedTotalFee) >= 1"
+ " or (COALESCE(tns.totalConsumed, 0) / COALESCE(p.totalManhour, 0)) >= 1"
+ " then 'Overconsumption'"
+ " else 'Within Budget'"
+ " END as status"
+ " from project p"
+ " left join staff s on s.id = p.teamLead"
+ " left join team t on t.id = s.teamId"
+ " left join customer c on c.id = p.customerId"
+ " LEFT JOIN subsidiary ss on p.customerSubsidiaryId = ss.id"
+ " LEFT JOIN salary sa ON s.salaryId = sa.salaryPoint"
+ " left join teamNormalConsumed tns on tns.projectId = p.id"
+ " WHERE p.deleted = false "
+ " and p.status = 'On-going' "
)
if (args != null) {
var statusFilter: String = ""


Loading…
取消
儲存