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 99b30f9..a8e6ac8 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 @@ -547,13 +547,16 @@ open class ReportService( val teamLeadCell = row.createCell(4) teamLeadCell.setCellValue(if (item["teamLead"] != null) item.getValue("teamLead").toString() else "N/A") - val startDateCell = row.createCell(5) + val subTeamLeadCell = row.createCell(5) + subTeamLeadCell.setCellValue(if (item["subTeamLead"] != null) item.getValue("subTeamLead").toString() else "N/A") + + val startDateCell = row.createCell(6) startDateCell.setCellValue(if (item["planStart"] != null) item.getValue("planStart").toString() else "N/A") - val endDateCell = row.createCell(6) + val endDateCell = row.createCell(7) endDateCell.setCellValue(if (item["planEnd"] != null) item.getValue("planEnd").toString() else "N/A") - val totalFeeCell = row.createCell(7) + val totalFeeCell = row.createCell(8) val totalFee = (item["expectedTotalFee"]?.let { it as Double } ?: 0.0) totalFeeCell.apply { @@ -566,19 +569,19 @@ open class ReportService( val fee = (item["expectedTotalFee"]?.let { it as Double } ?: 0.0) - val budgetCell = row.createCell(8) + val budgetCell = row.createCell(9) budgetCell.apply { setCellValue(fee.times(0.8)) cellStyle.dataFormat = accountingStyle } - val cumExpenditureCell = row.createCell(9) + val cumExpenditureCell = row.createCell(10) cumExpenditureCell.apply { - cellFormula = "K${rowNum} + L${rowNum}" + cellFormula = "L${rowNum} + M${rowNum}" cellStyle.dataFormat = accountingStyle } - val cumManHourSpentCell = row.createCell(10) + val cumManHourSpentCell = row.createCell(11) // val normalConsumed = item["normalConsumed"]?.let { it as BigDecimal } ?: BigDecimal(0) // val otConsumed = item["otConsumed"]?.let { it as BigDecimal } ?: BigDecimal(0) // val cumExpenditure = normalConsumed.add(otConsumed) @@ -588,20 +591,20 @@ open class ReportService( cellStyle.dataFormat = accountingStyle } - val projectExpenseCell = row.createCell(11) + val projectExpenseCell = row.createCell(12) val projectExpense = item["projectExpense"]?.let { it as BigDecimal } ?: BigDecimal(0) projectExpenseCell.apply { setCellValue(projectExpense.toDouble()) cellStyle.dataFormat = accountingStyle } - val budgetVCell = row.createCell(12) + val budgetVCell = row.createCell(13) budgetVCell.apply { - cellFormula = "I${rowNum} - J${rowNum}" + cellFormula = "J${rowNum} - K${rowNum}" cellStyle.dataFormat = accountingStyle } - val issuedCell = row.createCell(13) + val issuedCell = row.createCell(14) val issuedAmount = item["sumIssuedAmount"]?.let { it as BigDecimal } ?: BigDecimal(0) issuedCell.apply { setCellValue(issuedAmount.toDouble()) @@ -609,37 +612,37 @@ open class ReportService( cellStyle.dataFormat = accountingStyle } - val uninvoiceCell = row.createCell(14) + val uninvoiceCell = row.createCell(15) uninvoiceCell.apply { cellFormula = - " H${rowNum}-N${rowNum} " + " I${rowNum}-O${rowNum} " // " IF(H${rowNum}-N${rowNum}<0, 0, H${rowNum}-N${rowNum})" // " IF(I${rowNum}<=J${rowNum}, I${rowNum}-L${rowNum}, IF(AND(I${rowNum}>J${rowNum}, J${rowNum}J${rowNum}, J${rowNum}>=L${rowNum}), J${rowNum}-L${rowNum}, 0))) " cellStyle.dataFormat = accountingStyle } - val cpiCell = row.createCell(15) + val cpiCell = row.createCell(16) cpiCell.apply { - cellFormula = "IF(J${rowNum} = 0, 0, N${rowNum}/(J${rowNum}))" + cellFormula = "IF(K${rowNum} = 0, 0, O${rowNum}/(K${rowNum}))" cellStyle = boldFontCellStyle } - val projectedCpiCell = row.createCell(16) + val projectedCpiCell = row.createCell(17) projectedCpiCell.apply { - cellFormula = "IF(J${rowNum} = 0, 0, H${rowNum}/(J${rowNum}))" + cellFormula = "IF(K${rowNum} = 0, 0, I${rowNum}/(K${rowNum}))" cellStyle = boldFontCellStyle } - val receivedAmountCell = row.createCell(17) + val receivedAmountCell = row.createCell(18) val paidAmount = item["sumPaidAmount"]?.let { it as BigDecimal } ?: BigDecimal(0) receivedAmountCell.apply { setCellValue(paidAmount.toDouble()) cellStyle.dataFormat = accountingStyle } - val unsettledAmountCell = row.createCell(18) + val unsettledAmountCell = row.createCell(19) unsettledAmountCell.apply { - cellFormula = "N${rowNum}-R${rowNum}" + cellFormula = "O${rowNum}-S${rowNum}" cellStyle = boldFontCellStyle cellStyle.dataFormat = accountingStyle } @@ -648,13 +651,13 @@ open class ReportService( val lastRowNum = rowNum + 1 val row: Row = sheet.createRow(rowNum) - for (i in 0..5) { + for (i in 0..6) { val cell = row.createCell(i) CellUtil.setCellStyleProperty(cell, "borderTop", BorderStyle.THIN) CellUtil.setCellStyleProperty(cell, "borderBottom", BorderStyle.DOUBLE) } - val subTotalCell = row.createCell(6) + val subTotalCell = row.createCell(7) subTotalCell.apply { setCellValue("Sub-total:") } @@ -662,85 +665,85 @@ open class ReportService( CellUtil.setCellStyleProperty(subTotalCell, "borderBottom", BorderStyle.DOUBLE) - val sumTotalFeeCell = row.createCell(7) + val sumTotalFeeCell = row.createCell(8) sumTotalFeeCell.apply { - cellFormula = "SUM(H15:H${rowNum})" + cellFormula = "SUM(I15:I${rowNum})" cellStyle.dataFormat = accountingStyle } CellUtil.setCellStyleProperty(sumTotalFeeCell, "borderTop", BorderStyle.THIN) CellUtil.setCellStyleProperty(sumTotalFeeCell, "borderBottom", BorderStyle.DOUBLE) - val sumBudgetCell = row.createCell(8) + val sumBudgetCell = row.createCell(9) sumBudgetCell.apply { - cellFormula = "SUM(I15:I${rowNum})" + cellFormula = "SUM(J15:J${rowNum})" cellStyle.dataFormat = accountingStyle } CellUtil.setCellStyleProperty(sumBudgetCell, "borderTop", BorderStyle.THIN) CellUtil.setCellStyleProperty(sumBudgetCell, "borderBottom", BorderStyle.DOUBLE) - val sumCumExpenditureCell = row.createCell(9) + val sumCumExpenditureCell = row.createCell(10) sumCumExpenditureCell.apply { - cellFormula = "SUM(J15:J${rowNum})" + cellFormula = "SUM(K15:K${rowNum})" cellStyle.dataFormat = accountingStyle } CellUtil.setCellStyleProperty(sumCumExpenditureCell, "borderTop", BorderStyle.THIN) CellUtil.setCellStyleProperty(sumCumExpenditureCell, "borderBottom", BorderStyle.DOUBLE) - val sumTotalManHourSpent = row.createCell(10) + val sumTotalManHourSpent = row.createCell(11) sumTotalManHourSpent.apply { - cellFormula = "SUM(K15:K${rowNum})" + cellFormula = "SUM(L15:L${rowNum})" cellStyle.dataFormat = accountingStyle } CellUtil.setCellStyleProperty(sumTotalManHourSpent, "borderTop", BorderStyle.THIN) CellUtil.setCellStyleProperty(sumTotalManHourSpent, "borderBottom", BorderStyle.DOUBLE) - val sumProjectExpenseCell = row.createCell(11) + val sumProjectExpenseCell = row.createCell(12) sumProjectExpenseCell.apply { - cellFormula = "SUM(L15:L${rowNum})" + cellFormula = "SUM(M15:M${rowNum})" cellStyle.dataFormat = accountingStyle } CellUtil.setCellStyleProperty(sumProjectExpenseCell, "borderTop", BorderStyle.THIN) CellUtil.setCellStyleProperty(sumProjectExpenseCell, "borderBottom", BorderStyle.DOUBLE) - val sumBudgetVCell = row.createCell(12) + val sumBudgetVCell = row.createCell(13) sumBudgetVCell.apply { - cellFormula = "SUM(M15:M${rowNum})" + cellFormula = "SUM(N15:N${rowNum})" cellStyle = boldFontCellStyle cellStyle.dataFormat = accountingStyle } CellUtil.setCellStyleProperty(sumBudgetVCell, "borderTop", BorderStyle.THIN) CellUtil.setCellStyleProperty(sumBudgetVCell, "borderBottom", BorderStyle.DOUBLE) - val sumIInvoiceCell = row.createCell(13) + val sumIInvoiceCell = row.createCell(14) sumIInvoiceCell.apply { - cellFormula = "SUM(N15:N${rowNum})" + cellFormula = "SUM(O15:O${rowNum})" cellStyle.dataFormat = accountingStyle } CellUtil.setCellStyleProperty(sumIInvoiceCell, "borderTop", BorderStyle.THIN) CellUtil.setCellStyleProperty(sumIInvoiceCell, "borderBottom", BorderStyle.DOUBLE) - val sumUInvoiceCell = row.createCell(14) + val sumUInvoiceCell = row.createCell(15) sumUInvoiceCell.apply { // cellFormula = "IF(H${rowNum+1}-N${rowNum+1}<0,0,H${rowNum+1}-N${rowNum+1})" - cellFormula = " H${rowNum+1}-N${rowNum+1} " + cellFormula = " I${rowNum+1}-O${rowNum+1} " cellStyle = boldFontCellStyle cellStyle.dataFormat = accountingStyle } CellUtil.setCellStyleProperty(sumUInvoiceCell, "borderTop", BorderStyle.THIN) CellUtil.setCellStyleProperty(sumUInvoiceCell, "borderBottom", BorderStyle.DOUBLE) - val lastCpiCell = row.createCell(15) + val lastCpiCell = row.createCell(16) lastCpiCell.apply { - cellFormula = "IF(J${rowNum+1}=0,0,N${rowNum+1}/J${rowNum+1})" + cellFormula = "IF(K${rowNum+1}=0,0,O${rowNum+1}/K${rowNum+1})" cellStyle = boldFontCellStyle cellStyle.dataFormat = accountingStyle } CellUtil.setCellStyleProperty(lastCpiCell, "borderTop", BorderStyle.THIN) CellUtil.setCellStyleProperty(lastCpiCell, "borderBottom", BorderStyle.DOUBLE) - val lastPCpiCell = row.createCell(16) + val lastPCpiCell = row.createCell(17) lastPCpiCell.apply { - cellFormula = "IF(J${rowNum+1}=0,0,H${rowNum+1}/J${rowNum+1})" + cellFormula = "IF(K${rowNum+1}=0,0,I${rowNum+1}/K${rowNum+1})" cellStyle = boldFontCellStyle cellStyle.dataFormat = accountingStyle } @@ -748,17 +751,17 @@ open class ReportService( CellUtil.setCellStyleProperty(lastPCpiCell, "borderBottom", BorderStyle.DOUBLE) - val sumRAmountCell = row.createCell(17) + val sumRAmountCell = row.createCell(18) sumRAmountCell.apply { - cellFormula = "SUM(R15:R${rowNum})" + cellFormula = "SUM(S15:S${rowNum})" cellStyle.dataFormat = accountingStyle } CellUtil.setCellStyleProperty(sumRAmountCell, "borderTop", BorderStyle.THIN) CellUtil.setCellStyleProperty(sumRAmountCell, "borderBottom", BorderStyle.DOUBLE) - val sumUnSettleCell = row.createCell(18) + val sumUnSettleCell = row.createCell(19) sumUnSettleCell.apply { - cellFormula = "SUM(S15:S${rowNum})" + cellFormula = "SUM(T15:T${rowNum})" cellStyle = boldFontCellStyle cellStyle.dataFormat = accountingStyle } @@ -778,7 +781,7 @@ open class ReportService( row2Cell.setCellValue("All") } else { row2Cell.apply { - cellFormula = "E16" + cellFormula = "E17" } } @@ -796,7 +799,7 @@ open class ReportService( val row5: Row = sheet.getRow(rowNum) val cell1 = row5.createCell(2) cell1.apply { - cellFormula = "I${lastRowNum}" + cellFormula = "J${lastRowNum}" cellStyle.dataFormat = accountingStyle } @@ -804,7 +807,7 @@ open class ReportService( val row6: Row = sheet.getRow(rowNum) val cell2 = row6.createCell(2) cell2.apply { - cellFormula = "J${lastRowNum}" + cellFormula = "K${lastRowNum}" cellStyle.dataFormat = accountingStyle } @@ -812,7 +815,7 @@ open class ReportService( val row7: Row = sheet.getRow(rowNum) val cell3 = row7.createCell(2) cell3.apply { - cellFormula = "M${lastRowNum}" + cellFormula = "N${lastRowNum}" cellStyle.dataFormat = accountingStyle } @@ -820,7 +823,7 @@ open class ReportService( val row8: Row = sheet.getRow(rowNum) val cell4 = row8.createCell(2) cell4.apply { - cellFormula = "N${lastRowNum}" + cellFormula = "O${lastRowNum}" cellStyle.dataFormat = accountingStyle } @@ -828,7 +831,7 @@ open class ReportService( val row9: Row = sheet.getRow(rowNum) val cell5 = row9.createCell(2) cell5.apply { - cellFormula = "O${lastRowNum}" + cellFormula = "P${lastRowNum}" cellStyle.dataFormat = accountingStyle } @@ -836,7 +839,7 @@ open class ReportService( val row10: Row = sheet.getRow(rowNum) val cell6 = row10.createCell(2) cell6.apply { - cellFormula = "R${lastRowNum}" + cellFormula = "S${lastRowNum}" cellStyle.dataFormat = accountingStyle } @@ -844,7 +847,7 @@ open class ReportService( val row11: Row = sheet.getRow(rowNum) val cell7 = row11.createCell(2) cell7.apply { - cellFormula = "S${lastRowNum}" + cellFormula = "T${lastRowNum}" cellStyle.dataFormat = accountingStyle } @@ -2262,6 +2265,7 @@ open class ReportService( + " group by p.id" + " ) " + " select p.code, p.name, p.description, c.name as client, IFNULL(s2.name, \"N/A\") as subsidiary, concat(t.code, \' - \', t.name) as teamLead, " + + " concat(t.code, \' - \', s.staffId, \' - \', s.name) as subTeamLead," + " p.planStart , p.planEnd ," + " IFNULL(cte_f.expectedTotalFee, 0) as expectedTotalFee, ifnull(p.subContractFee, 0) as subContractFee, " + " IFNULL(cte_i.sumIssuedAmount, 0) as sumIssuedAmount, IFNULL(cte_ri.sumPaidAmount, 0) as sumPaidAmount" @@ -2272,6 +2276,8 @@ open class ReportService( + " left join customer_subsidiary cs on cs.id = p.customerSubsidiaryId" + " left join subsidiary s2 on s2.id = cs.subsidiaryId " + " left join tsmsdb.team t on t.teamLead = p.teamLead" + + " left join staff s on s.id = p.subTeamLead" + + " left join team st on st.id = s.teamId" + " left join cte_invoice cte_i on cte_i.code = p.code" + " left join cte_rinvoice cte_ri on cte_ri.code = p.code" + " left join cte_expense cte_e on cte_e.projectId = p.id " @@ -2580,7 +2586,7 @@ open class ReportService( // } private fun updateInfo(info: MutableMap, item: Map) { - val simpleFields = listOf("teamLead", "client", "code", "description") + val simpleFields = listOf("teamLead", "subTeamLead", "subsidiary", "client", "code", "description") val conditionalFields = mapOf( "paidAmount" to "sumPaidAmount", "subsidiary" to "subsidiary", @@ -2655,6 +2661,7 @@ open class ReportService( + " and (DATE_FORMAT(pe.issueDate, '%Y-%m') >= :startMonth and DATE_FORMAT(pe.issueDate, '%Y-%m') <= :endMonth) " + " ) " + " select p.code, p.description, c.name as client, IFNULL(s2.name, \"N/A\") as subsidiary, concat(t.code, \" - \", t.name) as teamLead," + + " concat(stlt.code, \" - \", stl.staffId, \" - \", stl.name) as subTeamLead," + " IFNULL(cte_ts.normalConsumed, 0) as normalConsumed, IFNULL(cte_ts.otConsumed, 0) as otConsumed, DATE_FORMAT(cte_ts.recordDate, '%Y-%m') as recordDate, " + " IFNULL(cte_ts.salaryPoint, 0) as salaryPoint, " + " (p.expectedTotalFee - IFNULL(cte_Ii.sumIssuedAmount, 0)) as expectedTotalFee, " @@ -2665,6 +2672,8 @@ open class ReportService( + " left join cte_timesheet_sum cte_tss on p.code = cte_tss.code" + " left join customer c on c.id = p.customerId" + " left join tsmsdb.team t on t.teamLead = p.teamLead" + + " left join staff stl on stl.id = p.subTeamLead" + + " left join team stlt on stlt.id = stl.teamId" + " left join cte_Iinvoice cte_Ii on cte_Ii.code = p.code" + " left join cte_Rinvoice cte_Ri on cte_Ri.code = p.code" + " left join staff s on s.id = cte_ts.staffId" @@ -2705,7 +2714,7 @@ open class ReportService( val manHoursSpent = jdbcDao.queryForList(sql.toString(), args) val projectCodeSql = StringBuilder( - "select p.code, p.description from project p where p.deleted = false and p.id = :projectId" + "select p.name, p.code, p.description from project p where p.deleted = false and p.id = :projectId" ) val projectExpenseSql = StringBuilder( @@ -2729,6 +2738,7 @@ open class ReportService( "startMonth" to startMonth, "endMonth" to endMonth, "code" to projectsCode["code"], + "name" to projectsCode["name"], "description" to projectsCode["description"], "projectExpense" to projectExpense["amount"] ) @@ -3140,6 +3150,11 @@ open class ReportService( val row6Cell = row6.getCell(1) row6Cell.setCellValue("-") + rowNum = 7 + val row7: Row = sheet.getRow(rowNum) + val row7Cell = row6.getCell(1) + row7Cell.setCellValue("-") + return workbook } @@ -3163,7 +3178,7 @@ open class ReportService( rowNum = 4 val row4: Row = sheet.getRow(rowNum) val row4Cell = row4.getCell(1) - row4Cell.setCellValue(info.getValue("description").toString()) + row4Cell.setCellValue(info.getValue("name").toString()) rowNum = 5 val row5: Row = sheet.getRow(rowNum) @@ -3173,52 +3188,57 @@ open class ReportService( rowNum = 6 val row6: Row = sheet.getRow(rowNum) val row6Cell = row6.getCell(1) + row6Cell.setCellValue(info.getOrDefault("subTeamLead", "N/A").toString()) + + rowNum = 7 + val row7: Row = sheet.getRow(rowNum) + val row7Cell = row7.getCell(1) val clientSubsidiary = if (info.getValue("subsidiary").toString() != "N/A") { info.getValue("subsidiary").toString() } else { info.getValue("client").toString() } - row6Cell.setCellValue(clientSubsidiary) + row7Cell.setCellValue(clientSubsidiary) // Average Hourly Rate by Pay Scale Point - rowNum = 8 - val row8: Row = sheet.getRow(rowNum) ?: sheet.createRow(rowNum) + rowNum = 9 + val row9: Row = sheet.getRow(rowNum) ?: sheet.createRow(rowNum) sheet.addMergedRegion(CellRangeAddress(rowNum, rowNum, 2, (financialYears.size + 1) * 2 - 1)) - val row8Cell = row8.getCell(2) ?: row8.createCell(2) - row8Cell.apply { + val row9Cell = row9.getCell(2) ?: row9.createCell(2) + row9Cell.apply { setCellValue("Average Hourly Rate by Pay Scale Point") } - CellUtil.setAlignment(row8Cell, HorizontalAlignment.CENTER); - CellUtil.setVerticalAlignment(row8Cell, VerticalAlignment.CENTER); - CellUtil.setCellStyleProperty(row8Cell, CellUtil.WRAP_TEXT, true) + CellUtil.setAlignment(row9Cell, HorizontalAlignment.CENTER); + CellUtil.setVerticalAlignment(row9Cell, VerticalAlignment.CENTER); + CellUtil.setCellStyleProperty(row9Cell, CellUtil.WRAP_TEXT, true) // Need to be updated to financial year // Base on the searching criteria - rowNum = 9 - val row9: Row = sheet.getRow(rowNum) ?: sheet.createRow(rowNum) + rowNum = 10 + val row10: Row = sheet.getRow(rowNum) ?: sheet.createRow(rowNum) var column = 2 financialYears.indices.forEach { i -> - val row9Cell = row9.getCell(column) ?: row9.createCell(column) - val row9Cell2 = row9.getCell(column + 1) ?: row9.createCell(column + 1) + val row10Cell = row10.getCell(column) ?: row10.createCell(column) + val row10Cell2 = row10.getCell(column + 1) ?: row10.createCell(column + 1) sheet.addMergedRegion(CellRangeAddress(rowNum, rowNum, column, column + 1)) - row9Cell.setCellValue( + row10Cell.setCellValue( "${financialYears[i].start.format(monthFormat)} - ${ financialYears[i].end.format( monthFormat ) }" ) - CellUtil.setAlignment(row9Cell, HorizontalAlignment.CENTER); - CellUtil.setVerticalAlignment(row9Cell, VerticalAlignment.CENTER); - CellUtil.setCellStyleProperty(row9Cell, "borderBottom", BorderStyle.THIN) - CellUtil.setCellStyleProperty(row9Cell2, "borderBottom", BorderStyle.THIN) + CellUtil.setAlignment(row10Cell, HorizontalAlignment.CENTER); + CellUtil.setVerticalAlignment(row10Cell, VerticalAlignment.CENTER); + CellUtil.setCellStyleProperty(row10Cell, "borderBottom", BorderStyle.THIN) + CellUtil.setCellStyleProperty(row10Cell2, "borderBottom", BorderStyle.THIN) column = column.plus(2) } - rowNum = 10 + rowNum = 11 for (staff in staffInfoList) { // val row: Row = sheet.getRow(rowNum++) ?: sheet.createRow(rowNum++) val row: Row = sheet.getRow(rowNum) ?: sheet.createRow(rowNum) diff --git a/src/main/resources/templates/report/AR07_Project P&L Report v02.xlsx b/src/main/resources/templates/report/AR07_Project P&L Report v02.xlsx index ba5e1b1..8104264 100644 Binary files a/src/main/resources/templates/report/AR07_Project P&L Report v02.xlsx and b/src/main/resources/templates/report/AR07_Project P&L Report v02.xlsx differ diff --git a/src/main/resources/templates/report/EX01_Financial Status Report.xlsx b/src/main/resources/templates/report/EX01_Financial Status Report.xlsx index def5e66..7a529b8 100644 Binary files a/src/main/resources/templates/report/EX01_Financial Status Report.xlsx and b/src/main/resources/templates/report/EX01_Financial Status Report.xlsx differ