diff --git a/src/main/java/com/ffii/tsms/modules/data/service/DashboardService.kt b/src/main/java/com/ffii/tsms/modules/data/service/DashboardService.kt index 16cb115..d3b2c09 100644 --- a/src/main/java/com/ffii/tsms/modules/data/service/DashboardService.kt +++ b/src/main/java/com/ffii/tsms/modules/data/service/DashboardService.kt @@ -291,19 +291,25 @@ open class DashboardService( + " count(p.name) as projectNo," + " coalesce(sum(p.expectedTotalFee),0) as totalFee," + " coalesce(sum(round(p.expectedTotalFee * 0.8,2)),0) as totalBudget," - + " coalesce(sum((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0)),0) as cumulativeExpenditure," + " coalesce(sum(i.issueAmount),0) as totalInvoiced," + " coalesce(sum(i.paidAmount),0) as totalReceived," + + " round(expenditure.cumulativeExpenditure,2) as cumulativeExpenditure," + " case" - + " when coalesce(round(sum(i.issueAmount) / (sum((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0))),2),0) >= 1 then 'Positive'" - + " when coalesce(round(sum(i.issueAmount) / (sum((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0))),2),0) < 1 then 'Negative'" + + " when coalesce(round(sum(i.issueAmount) / (expenditure.cumulativeExpenditure),2),0) >= 1 then 'Positive'" + + " when coalesce(round(sum(i.issueAmount) / (expenditure.cumulativeExpenditure),2),0) < 1 then 'Negative'" + " end as cashFlowStatus," - + " coalesce(round(sum(i.issueAmount) / (sum((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0))),2),0) as cpi" + + " coalesce(round(sum(i.issueAmount) / (expenditure.cumulativeExpenditure),2),0) as cpi" + " from team t" + " left join project p on t.teamLead = p.teamLead" + " left join invoice i on p.code = i.projectCode" + " left join (" + " select" + + " r.teamId as teamId," + + " sum(r.cumulativeExpenditure) as cumulativeExpenditure" + + " from (" + + " select" + + " t1.id as teamId," + + " (coalesce(sum(t2.normalConsumed),0) * s2.hourlyRate) + (coalesce(sum(t2.otConsumed),0) * s2.hourlyRate * 1.0) as cumulativeExpenditure," + " s2.hourlyRate as hourlyRate," + " sum(t2.normalConsumed) as normalConsumed," + " sum(t2.otConsumed) as otConsumed" @@ -315,41 +321,39 @@ open class DashboardService( + " left join salary s2 on s.salaryId = s2.salaryPoint" + " where p2.status = 'On-going'" + " and t2.id is not null" - + " group by s2.hourlyRate" - + " ) as expenditure on 1=1" + + " group by s2.hourlyRate,t1.id" + + " ) as r" + + " group by r.teamId" + + " ) as expenditure on expenditure.teamId = t.id" + " where t.deleted = 0" + " and p.status = 'On-going'" ) - - if (args != null) { - if (args.containsKey("teamId")) - sql.append(" AND t.id = :teamId"); - } sql.append(" group by t.id, t.name") return jdbcDao.queryForList(sql.toString(), args) } fun searchFinancialSummaryAllTeamCard(args: Map): List> { - val sql = StringBuilder( "select" + val sql = StringBuilder( "select DISTINCT" + " 'All Team' as teamName," + " count(p.code) as projectNo," + " sum(p.expectedTotalFee) as totalFee," + " round(sum(p.expectedTotalFee) * 0.8,2) as totalBudget," - + " sum((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0)) as cumulativeExpenditure," + + " round(expenditure.cumulativeExpenditure,2) as cumulativeExpenditure," + " sum(i.issueAmount) as totalInvoiced," + " sum(i.paidAmount) as totalReceived," + " case" - + " when round(sum(i.issueAmount) / (sum((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0))),2) >= 1 then 'Positive'" - + " when round(sum(i.issueAmount) / (sum((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0))),2) < 1 then 'Negative'" + + " when round(sum(i.issueAmount) / (expenditure.cumulativeExpenditure),2) >= 1 then 'Positive'" + + " when round(sum(i.issueAmount) / (expenditure.cumulativeExpenditure),2) < 1 then 'Negative'" + " end as cashFlowStatus," - + " round(sum(i.issueAmount) / (sum((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0))),2) as cpi" + + " round(sum(i.issueAmount) / (expenditure.cumulativeExpenditure),2) as cpi" + " from project p" + " left join invoice i on p.code = i.projectCode" + " left join (" + " select" - + " s2.hourlyRate as hourlyRate," - + " sum(t2.normalConsumed) as normalConsumed," - + " sum(t2.otConsumed) as otConsumed" + + " sum(r.cumulativeExpenditure) as cumulativeExpenditure" + + " from(" + + " select" + + " (coalesce(sum(t2.normalConsumed),0) * s2.hourlyRate) + (coalesce(sum(t2.otConsumed),0) * s2.hourlyRate * 1.0) as cumulativeExpenditure" + " from project p2" + " left join project_task pt ON p2.id = pt.project_id" + " left join timesheet t2 on pt.id = t2.projectTaskId" @@ -358,8 +362,10 @@ open class DashboardService( + " where p2.status = 'On-going'" + " and t2.id is not null" + " group by s2.hourlyRate" - + " ) as expenditure on 1=1" + + " ) as r" + + " ) as expenditure on 1=1." + " where p.status = 'On-going'" + + " group by expenditure.cumulativeExpenditure" ) return jdbcDao.queryForList(sql.toString(), args) @@ -367,25 +373,26 @@ open class DashboardService( fun searchFinancialSummaryByClient(args: Map): List> { val sql = StringBuilder( "select" + + " ROW_NUMBER() OVER (ORDER BY t.id, c.id) AS id," + " t.id as teamId," - + " c.id as id," + + " c.id as cid," + " c.code as customerCode," + " c.name as customerName," + " count(p.name) as projectNo," + " sum(p.expectedTotalFee) as totalFee," + " round(sum(p.expectedTotalFee) * 0.8,2) as totalBudget," - + " sum((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0)) as cumulativeExpenditure," + + " COALESCE(round(expenditure.cumulativeExpenditure,2),0) as cumulativeExpenditure," + " coalesce(sum(i.issueAmount),0) as totalInvoiced," + " coalesce(sum(i.paidAmount),0) as totalReceived," + " case" - + " when coalesce(round(sum(i.issueAmount) / (sum((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0))),2),0) >= 1 then 'Positive'" - + " when coalesce(round(sum(i.issueAmount) / (sum((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0))),2),0) < 1 then 'Negative'" + + " when coalesce(round(sum(i.issueAmount) / (COALESCE(expenditure.cumulativeExpenditure,0)),2),0) >= 1 then 'Positive'" + + " when coalesce(round(sum(i.issueAmount) / (COALESCE(expenditure.cumulativeExpenditure,0)),2),0) < 1 then 'Negative'" + " end as cashFlowStatus," - + " coalesce(round(sum(i.issueAmount) / (sum((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0))),2),0) as cpi," + + " coalesce(round(sum(i.issueAmount) / (COALESCE(expenditure.cumulativeExpenditure,0)),2),0) as cpi," + " case" - + " when coalesce(round(sum(p.expectedTotalFee) * 0.8,2),0) <= coalesce(sum((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0)),0) then coalesce(round(sum(p.expectedTotalFee) * 0.8,2),0) - coalesce(sum(i.issueAmount),0)" - + " when coalesce(round(sum(p.expectedTotalFee) * 0.8,2),0) > coalesce(sum((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0)),0) and coalesce(sum((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0)),0) < coalesce(sum(i.issueAmount),0) then 0" - + " when coalesce(round(sum(p.expectedTotalFee) * 0.8,2),0) > coalesce(sum((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0)),0) and coalesce(sum((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0)),0) >= coalesce(sum(i.issueAmount),0) then coalesce(sum((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0)),0) - coalesce(sum(i.issueAmount),0)" + + " when coalesce(round(sum(p.expectedTotalFee) * 0.8,2),0) <= COALESCE(expenditure.cumulativeExpenditure,0) then coalesce(round(sum(p.expectedTotalFee) * 0.8,2),0) - coalesce(sum(i.issueAmount),0)" + + " when coalesce(round(sum(p.expectedTotalFee) * 0.8,2),0) > COALESCE(expenditure.cumulativeExpenditure,0) and COALESCE(expenditure.cumulativeExpenditure,0) < coalesce(sum(i.issueAmount),0) then 0" + + " when coalesce(round(sum(p.expectedTotalFee) * 0.8,2),0) > COALESCE(expenditure.cumulativeExpenditure,0) and COALESCE(expenditure.cumulativeExpenditure,0) >= coalesce(sum(i.issueAmount),0) then COALESCE(expenditure.cumulativeExpenditure,0) - coalesce(sum(i.issueAmount),0)" + " end as totalUninvoiced" + " from team t" + " left join project p on t.teamLead = p.teamLead" @@ -393,22 +400,33 @@ open class DashboardService( + " left join invoice i on p.code = i.projectCode" + " left join (" + " select" + + " r.teamId as teamId," + + " r.customerId as customerId," + + " sum(r.cumulativeExpenditure) as cumulativeExpenditure" + + " from (" + + " select" + + " t1.id as teamId," + + " c2.id as customerId," + + " (coalesce(sum(t2.normalConsumed),0) * s2.hourlyRate) + (coalesce(sum(t2.otConsumed),0) * s2.hourlyRate * 1.0) as cumulativeExpenditure," + " s2.hourlyRate as hourlyRate," + " sum(t2.normalConsumed) as normalConsumed," + " sum(t2.otConsumed) as otConsumed" + " from team t1" + " left join project p2 on t1.teamLead = p2.teamLead" + + " left join customer c2 on p2.customerId = c2 .id" + " left join project_task pt ON p2.id = pt.project_id" + " left join timesheet t2 on pt.id = t2.projectTaskId" + " left join staff s on t2.staffId = s.id" + " left join salary s2 on s.salaryId = s2.salaryPoint" + " where p2.status = 'On-going'" + " and t2.id is not null" - + " group by s2.hourlyRate" - + " ) as expenditure on 1=1" + + " group by s2.hourlyRate,t1.id,c2.id" + + " ) as r" + + " group by r.teamId, r.customerId" + + " ) as expenditure on expenditure.teamId = t.id and expenditure.customerId = c.id" + " where t.deleted = 0" + " and p.status = 'On-going'" - ) + ) if (args != null) { if (args.containsKey("teamId")) sql.append(" AND t.id = :teamId"); @@ -426,18 +444,18 @@ open class DashboardService( + " c.name as customerName," + " p.expectedTotalFee as totalFee," + " round(p.expectedTotalFee * 0.8,2) as totalBudget," - + " coalesce((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0),0) as cumulativeExpenditure," + + " COALESCE(round(expenditure.cumulativeExpenditure,2),0) as cumulativeExpenditure," + " coalesce(sum(i.issueAmount),0) as totalInvoiced," + " coalesce(sum(i.paidAmount),0) as totalReceived," + " case" - + " when round(coalesce(sum(i.issueAmount),0) / coalesce(((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0)),0),2) >= 1 then 'Positive'" - + " when round(coalesce(sum(i.issueAmount),0) / coalesce(((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0)),0),2) < 1 then 'Negative'" + + " when coalesce(round(sum(i.issueAmount) / (COALESCE(expenditure.cumulativeExpenditure,0)),2),0) >= 1 then 'Positive'" + + " when coalesce(round(sum(i.issueAmount) / (COALESCE(expenditure.cumulativeExpenditure,0)),2),0) < 1 then 'Negative'" + " end as cashFlowStatus," - + " round(coalesce(sum(i.issueAmount),0) / coalesce(((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0)),0),2) as cpi," + + " coalesce(round(sum(i.issueAmount) / (COALESCE(expenditure.cumulativeExpenditure,0)),2),0) as cpi," + " case" - + " when round(p.expectedTotalFee * 0.8,2) <= coalesce((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0),0) then round(p.expectedTotalFee * 0.8,2) - coalesce(sum(i.issueAmount),0)" - + " when round(p.expectedTotalFee * 0.8,2) > coalesce((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0),0) and coalesce((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0),0) < coalesce(sum(i.issueAmount),0) then 0" - + " when round(p.expectedTotalFee * 0.8,2) > coalesce((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0),0) and coalesce((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0),0) >= coalesce(sum(i.issueAmount),0) then coalesce((expenditure.normalConsumed * expenditure.hourlyRate) + (expenditure.otConsumed * expenditure.hourlyRate * 1.0),0) - coalesce(sum(i.issueAmount),0)" + + " when coalesce(round(sum(p.expectedTotalFee) * 0.8,2),0) <= COALESCE(expenditure.cumulativeExpenditure,0) then coalesce(round(sum(p.expectedTotalFee) * 0.8,2),0) - coalesce(sum(i.issueAmount),0)" + + " when coalesce(round(sum(p.expectedTotalFee) * 0.8,2),0) > COALESCE(expenditure.cumulativeExpenditure,0) and COALESCE(expenditure.cumulativeExpenditure,0) < coalesce(sum(i.issueAmount),0) then 0" + + " when coalesce(round(sum(p.expectedTotalFee) * 0.8,2),0) > COALESCE(expenditure.cumulativeExpenditure,0) and COALESCE(expenditure.cumulativeExpenditure,0) >= coalesce(sum(i.issueAmount),0) then COALESCE(expenditure.cumulativeExpenditure,0) - coalesce(sum(i.issueAmount),0)" + " end as totalUninvoiced" + " from team t" + " left join project p on t.teamLead = p.teamLead" @@ -445,27 +463,64 @@ open class DashboardService( + " left join invoice i on p.code = i.projectCode" + " left join (" + " select" + + " r.teamId as teamId," + + " r.customerId as customerId," + + " r.projectId as projectId," + + " sum(r.cumulativeExpenditure) as cumulativeExpenditure" + + " from (" + + " select" + + " t1.id as teamId," + + " c2.id as customerId," + + " p2.id as projectId," + + " (coalesce(sum(t2.normalConsumed),0) * s2.hourlyRate) + (coalesce(sum(t2.otConsumed),0) * s2.hourlyRate * 1.0) as cumulativeExpenditure," + " s2.hourlyRate as hourlyRate," + " sum(t2.normalConsumed) as normalConsumed," + " sum(t2.otConsumed) as otConsumed" + " from team t1" + " left join project p2 on t1.teamLead = p2.teamLead" + + " left join customer c2 on p2.customerId = c2 .id" + " left join project_task pt ON p2.id = pt.project_id" + " left join timesheet t2 on pt.id = t2.projectTaskId" + " left join staff s on t2.staffId = s.id" + " left join salary s2 on s.salaryId = s2.salaryPoint" + " where p2.status = 'On-going'" + " and t2.id is not null" - + " group by s2.hourlyRate" - + " ) as expenditure on 1=1" + + " group by s2.hourlyRate,t1.id,c2.id,p2.id" + + " ) as r" + + " group by r.teamId, r.customerId, r.projectId" + + " ) as expenditure on expenditure.teamId = t.id and expenditure.customerId = c.id and expenditure.projectId = p.id" + " where t.deleted = 0" + " and p.status = 'On-going'" ) if (args != null) { if (args.containsKey("teamId")) sql.append(" AND t.id = :teamId"); + if (args.containsKey("customerId")) + sql.append(" AND c.id = :customerId"); } - sql.append(" group by t.id, p.id, p.code, p.name, c.name, p.expectedTotalFee,expenditure.normalConsumed, expenditure.hourlyRate, expenditure.otConsumed,i.issueAmount") + sql.append(" group by t.id, p.id, p.code, p.name, c.name, p.expectedTotalFee") + + return jdbcDao.queryForList(sql.toString(), args) + } + fun CashFlowProject(args: Map): List> { + val sql = StringBuilder("select" + + " p.id as id," + + " p.code as projectCode," + + " p.name as projectName," + + " t.code as team," + + " s.name as teamLead," + + " p.actualStart as startDate," + + " p.planEnd as targetEndDate," + + " c.name as client," + + " coalesce(s2.name,'N/A') as subsidiary" + + " from project p" + + " left join team t on t.teamLead = p.teamLead" + + " left join staff s on t.teamLead = s.id" + + " left join customer c on p.customerId = c.id" + + " left join subsidiary s2 on p.customerSubsidiaryId = s2.id" + + " where p.deleted = 0" + + " and p.status = 'On-going'" + ) return jdbcDao.queryForList(sql.toString(), args) } diff --git a/src/main/java/com/ffii/tsms/modules/data/web/DashboardController.kt b/src/main/java/com/ffii/tsms/modules/data/web/DashboardController.kt index 44f13eb..7926dcc 100644 --- a/src/main/java/com/ffii/tsms/modules/data/web/DashboardController.kt +++ b/src/main/java/com/ffii/tsms/modules/data/web/DashboardController.kt @@ -116,10 +116,19 @@ class DashboardController( @GetMapping("/searchFinancialSummaryByProject") fun searchFinancialSummaryByProject(request: HttpServletRequest?): List> { val teamId = request?.getParameter("teamId") + val customerId = request?.getParameter("customerId") val args = mutableMapOf() if (teamId != null) { args["teamId"] = teamId } + if (customerId != null) { + args["customerId"] = customerId + } return dashboardService.searchFinancialSummaryByProject(args) } + @GetMapping("/searchCashFlowProject") + fun searchCashFlowProject(request: HttpServletRequest?): List> { + val args = mutableMapOf() + return dashboardService.CashFlowProject(args) + } } \ No newline at end of file