| @@ -63,6 +63,30 @@ open class ReportService( | |||||
| private val COMPLETION_PROJECT = "templates/report/AR05_Project Completion Report.xlsx" | private val COMPLETION_PROJECT = "templates/report/AR05_Project Completion Report.xlsx" | ||||
| // ==============================|| GENERATE REPORT ||============================== // | // ==============================|| GENERATE REPORT ||============================== // | ||||
| fun generalCreateReportIndexed( // just loop through query records one by one, return rowIndex | |||||
| sheet: Sheet, | |||||
| result: List<Map<String, Any>>, | |||||
| startRow: Int, | |||||
| startColumn: Int | |||||
| ): Int { | |||||
| var rowIndex = startRow | |||||
| var columnIndex = startColumn | |||||
| result.forEachIndexed { index, obj -> | |||||
| var tempCell = sheet.getRow(rowIndex).createCell(columnIndex) | |||||
| tempCell.setCellValue((index + 1).toDouble()) | |||||
| val keys = obj.keys.toList() | |||||
| keys.forEachIndexed { keyIndex, key -> | |||||
| tempCell = sheet.getRow(rowIndex).getCell(columnIndex + keyIndex + 1) ?: sheet.getRow(rowIndex) | |||||
| .createCell(columnIndex + keyIndex + 1) | |||||
| when (obj[key]) { | |||||
| is Double -> tempCell.setCellValue(obj[key] as Double) | |||||
| else -> tempCell.setCellValue(obj[key] as String) | |||||
| } | |||||
| } | |||||
| rowIndex++ | |||||
| } | |||||
| return rowIndex | |||||
| } | |||||
| fun genFinancialStatusReport(teamLeadId: Long): ByteArray { | fun genFinancialStatusReport(teamLeadId: Long): ByteArray { | ||||
| @@ -1298,20 +1322,8 @@ open class ReportService( | |||||
| rowIndex = 5 | rowIndex = 5 | ||||
| columnIndex = 0 | columnIndex = 0 | ||||
| result.forEachIndexed { index, obj -> | |||||
| tempCell = sheet.getRow(rowIndex).createCell(columnIndex) | |||||
| tempCell.setCellValue((index + 1).toDouble()) | |||||
| val keys = obj.keys.toList() | |||||
| keys.forEachIndexed { keyIndex, key -> | |||||
| tempCell = sheet.getRow(rowIndex).getCell(columnIndex + keyIndex + 1) ?: sheet.getRow(rowIndex) | |||||
| .createCell(columnIndex + keyIndex + 1) | |||||
| when (obj[key]) { | |||||
| is Double -> tempCell.setCellValue(obj[key] as Double) | |||||
| else -> tempCell.setCellValue(obj[key] as String) | |||||
| } | |||||
| } | |||||
| rowIndex++ | |||||
| } | |||||
| generalCreateReportIndexed(sheet, result, rowIndex, columnIndex) | |||||
| return workbook | return workbook | ||||
| } | } | ||||
| @@ -1350,20 +1362,9 @@ open class ReportService( | |||||
| rowIndex = 6 | rowIndex = 6 | ||||
| columnIndex = 0 | columnIndex = 0 | ||||
| result.forEachIndexed { index, obj -> | |||||
| tempCell = sheet.getRow(rowIndex).createCell(columnIndex) | |||||
| tempCell.setCellValue((index + 1).toDouble()) | |||||
| val keys = obj.keys.toList() | |||||
| keys.forEachIndexed { keyIndex, key -> | |||||
| tempCell = sheet.getRow(rowIndex).getCell(columnIndex + keyIndex + 1) ?: sheet.getRow(rowIndex) | |||||
| .createCell(columnIndex + keyIndex + 1) | |||||
| when (obj[key]) { | |||||
| is Double -> tempCell.setCellValue(obj[key] as Double) | |||||
| else -> tempCell.setCellValue(obj[key] as String) | |||||
| } | |||||
| } | |||||
| rowIndex++ | |||||
| } | |||||
| // val currRow = generalCreateReportIndexed(sheet, result, rowIndex, columnIndex) | |||||
| generalCreateReportIndexed(sheet, result, rowIndex, columnIndex) | |||||
| val sheetCF = sheet.sheetConditionalFormatting | val sheetCF = sheet.sheetConditionalFormatting | ||||
| val rule1 = sheetCF.createConditionalFormattingRule("AND(J7 >= $lowerLimit, J7 <= 1)") | val rule1 = sheetCF.createConditionalFormattingRule("AND(J7 >= $lowerLimit, J7 <= 1)") | ||||
| @@ -1529,111 +1530,107 @@ open class ReportService( | |||||
| ) | ) | ||||
| return jdbcDao.queryForList(sql.toString(), args) | return jdbcDao.queryForList(sql.toString(), args) | ||||
| } | } | ||||
| open fun getProjectCompletionReport(args: Map<String, Any>): List<Map<String, Any>> { | open fun getProjectCompletionReport(args: Map<String, Any>): List<Map<String, Any>> { | ||||
| val sql = StringBuilder( | |||||
| "select" | |||||
| + " result.code, " | |||||
| + " result.name, " | |||||
| + " result.teamCode, " | |||||
| + " result.custCode, " | |||||
| ) | |||||
| val sql = StringBuilder("select" | |||||
| + " result.code, " | |||||
| + " result.name, " | |||||
| + " result.teamCode, " | |||||
| + " result.custCode, " ) | |||||
| if (args.get("outstanding") as Boolean) { | if (args.get("outstanding") as Boolean) { | ||||
| sql.append(" result.projectFee - (result.totalBudget - COALESCE(i.issueAmount , 0) + COALESCE(i.issueAmount, 0) - COALESCE(i.paidAmount, 0)) as `Receivable Remained`, ") | sql.append(" result.projectFee - (result.totalBudget - COALESCE(i.issueAmount , 0) + COALESCE(i.issueAmount, 0) - COALESCE(i.paidAmount, 0)) as `Receivable Remained`, ") | ||||
| } | } | ||||
| sql.append( | sql.append( | ||||
| " DATE_FORMAT(result.actualEnd, '%d/%m/%Y') as actualEnd " | " DATE_FORMAT(result.actualEnd, '%d/%m/%Y') as actualEnd " | ||||
| + " from ( " | |||||
| + " SELECT " | |||||
| + " pt.project_id, " | |||||
| + " min(p.code) as code, " | |||||
| + " min(p.name) as name, " | |||||
| + " min(t.code) as teamCode, " | |||||
| + " min(c.code) as custCode, " | |||||
| + " min(p.actualEnd) as actualEnd, " | |||||
| + " min(p.expectedTotalFee) as projectFee, " | |||||
| + " sum(COALESCE(tns.totalConsumed*sal.hourlyRate, 0)) as totalBudget " | |||||
| + " FROM ( " | |||||
| + " SELECT " | |||||
| + " t.staffId, " | |||||
| + " sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) as totalConsumed, " | |||||
| + " t.projectTaskId AS taskId " | |||||
| + " FROM timesheet t " | |||||
| + " LEFT JOIN staff s ON t.staffId = s.id " | |||||
| + " LEFT JOIN team te on s.teamId = te.id " | |||||
| + " GROUP BY t.staffId, t.projectTaskId " | |||||
| + " order by t.staffId " | |||||
| + " ) AS tns " | |||||
| + " right join project_task pt ON tns.taskId = pt.id " | |||||
| + " left join project p on p.id = pt.project_id " | |||||
| + " left JOIN staff s ON p.teamLead = s.id " | |||||
| + " left join salary sal on s.salaryId = sal.salaryPoint " | |||||
| + " left JOIN team t ON s.teamId = t.id " | |||||
| + " left join customer c on c.id = p.customerId " | |||||
| + " where p.deleted = false " | |||||
| + " and p.status = 'Completed' " | |||||
| + " and p.actualEnd BETWEEN :startDate and :endDate " | |||||
| + " group by pt.project_id " | |||||
| + " ) as result " | |||||
| + " left join invoice i on result.code = i.projectCode " | |||||
| + " order by result.actualEnd " | |||||
| + " from ( " | |||||
| + " SELECT " | |||||
| + " pt.project_id, " | |||||
| + " min(p.code) as code, " | |||||
| + " min(p.name) as name, " | |||||
| + " min(t.code) as teamCode, " | |||||
| + " min(c.code) as custCode, " | |||||
| + " min(p.actualEnd) as actualEnd, " | |||||
| + " min(p.expectedTotalFee) as projectFee, " | |||||
| + " sum(COALESCE(tns.totalConsumed*sal.hourlyRate, 0)) as totalBudget " | |||||
| + " FROM ( " | |||||
| + " SELECT " | |||||
| + " t.staffId, " | |||||
| + " sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) as totalConsumed, " | |||||
| + " t.projectTaskId AS taskId " | |||||
| + " FROM timesheet t " | |||||
| + " LEFT JOIN staff s ON t.staffId = s.id " | |||||
| + " LEFT JOIN team te on s.teamId = te.id " | |||||
| + " GROUP BY t.staffId, t.projectTaskId " | |||||
| + " order by t.staffId " | |||||
| + " ) AS tns " | |||||
| + " right join project_task pt ON tns.taskId = pt.id " | |||||
| + " left join project p on p.id = pt.project_id " | |||||
| + " left JOIN staff s ON p.teamLead = s.id " | |||||
| + " left join salary sal on s.salaryId = sal.salaryPoint " | |||||
| + " left JOIN team t ON s.teamId = t.id " | |||||
| + " left join customer c on c.id = p.customerId " | |||||
| + " where p.deleted = false " | |||||
| + " and p.status = 'Completed' " | |||||
| + " and p.actualEnd BETWEEN :startDate and :endDate " | |||||
| + " group by pt.project_id " | |||||
| + " ) as result " | |||||
| + " left join invoice i on result.code = i.projectCode " | |||||
| + " order by result.actualEnd " | |||||
| ) | ) | ||||
| return jdbcDao.queryForList(sql.toString(), args) | return jdbcDao.queryForList(sql.toString(), args) | ||||
| } | } | ||||
| open fun getProjectResourceOverconsumptionReport(args: Map<String, Any>): List<Map<String, Any>> { | open fun getProjectResourceOverconsumptionReport(args: Map<String, Any>): List<Map<String, Any>> { | ||||
| val sql = StringBuilder( | |||||
| "WITH teamNormalConsumed AS (" | |||||
| + " SELECT " | |||||
| + " s.teamId, " | |||||
| + " pt.project_id, " | |||||
| + " SUM(tns.totalConsumed) AS totalConsumed, " | |||||
| + " sum(tns.totalBudget) as totalBudget " | |||||
| + " FROM ( " | |||||
| + " SELECT " | |||||
| + " t.staffId, " | |||||
| + " sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) as totalConsumed, " | |||||
| + " t.projectTaskId AS taskId, " | |||||
| + " sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) * min(sal.hourlyRate) as totalBudget " | |||||
| + " FROM timesheet t " | |||||
| + " LEFT JOIN staff s ON t.staffId = s.id " | |||||
| + " left join salary sal on sal.salaryPoint = s.salaryId " | |||||
| + " GROUP BY t.staffId, t.projectTaskId " | |||||
| + " ) AS tns " | |||||
| + " INNER JOIN project_task pt ON tns.taskId = pt.id " | |||||
| + " JOIN staff s ON tns.staffId = s.id " | |||||
| + " JOIN team t ON s.teamId = t.id " | |||||
| + " GROUP BY teamId, project_id " | |||||
| + " ) " | |||||
| + " SELECT " | |||||
| + " p.code, " | |||||
| + " p.name, " | |||||
| + " t.code as team, " | |||||
| + " c.code as client, " | |||||
| + " 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 team t ON p.teamLead = t.teamLead " | |||||
| + " LEFT JOIN staff s ON p.teamLead = s.id " | |||||
| + " LEFT JOIN salary sa ON s.salaryId = sa.salaryPoint " | |||||
| + " LEFT JOIN customer c ON p.customerId = c.id " | |||||
| + " left join teamNormalConsumed tns on tns.project_id = p.id " | |||||
| + " WHERE p.deleted = false " | |||||
| + " and p.status = 'On-going' " | |||||
| val sql = StringBuilder("WITH teamNormalConsumed AS (" | |||||
| + " SELECT " | |||||
| + " s.teamId, " | |||||
| + " pt.project_id, " | |||||
| + " SUM(tns.totalConsumed) AS totalConsumed, " | |||||
| + " sum(tns.totalBudget) as totalBudget " | |||||
| + " FROM ( " | |||||
| + " SELECT " | |||||
| + " t.staffId, " | |||||
| + " sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) as totalConsumed, " | |||||
| + " t.projectTaskId AS taskId, " | |||||
| + " sum(t.normalConsumed + COALESCE(t.otConsumed, 0)) * min(sal.hourlyRate) as totalBudget " | |||||
| + " FROM timesheet t " | |||||
| + " LEFT JOIN staff s ON t.staffId = s.id " | |||||
| + " left join salary sal on sal.salaryPoint = s.salaryId " | |||||
| + " GROUP BY t.staffId, t.projectTaskId " | |||||
| + " ) AS tns " | |||||
| + " INNER JOIN project_task pt ON tns.taskId = pt.id " | |||||
| + " JOIN staff s ON tns.staffId = s.id " | |||||
| + " JOIN team t ON s.teamId = t.id " | |||||
| + " GROUP BY teamId, project_id " | |||||
| + " ) " | |||||
| + " SELECT " | |||||
| + " p.code, " | |||||
| + " p.name, " | |||||
| + " t.code as team, " | |||||
| + " c.code as client, " | |||||
| + " 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 team t ON p.teamLead = t.teamLead " | |||||
| + " LEFT JOIN staff s ON p.teamLead = s.id " | |||||
| + " LEFT JOIN salary sa ON s.salaryId = sa.salaryPoint " | |||||
| + " LEFT JOIN customer c ON p.customerId = c.id " | |||||
| + " left join teamNormalConsumed tns on tns.project_id = p.id " | |||||
| + " WHERE p.deleted = false " | |||||
| + " and p.status = 'On-going' " | |||||
| ) | ) | ||||
| if (args != null) { | if (args != null) { | ||||
| var statusFilter: String = "" | var statusFilter: String = "" | ||||
| @@ -2126,10 +2123,10 @@ open class ReportService( | |||||
| return workbook | return workbook | ||||
| } | } | ||||
| fun getCostAndExpense(clientId: Long?, teamId: Long?): List<Map<String, Any?>> { | |||||
| fun getCostAndExpense(clientId: Long?, teamId: Long?): List<Map<String,Any?>>{ | |||||
| val sql = StringBuilder( | val sql = StringBuilder( | ||||
| " with cte_timesheet as ( " | " with cte_timesheet as ( " | ||||
| + " Select p.code, s.name as staff, IFNULL(t.normalConsumed, 0) as normalConsumed, IFNULL(t.otConsumed , 0) as otConsumed, s2.salaryPoint, s2.hourlyRate, t.staffId," | |||||
| + " Select p.code, s.name as staff, IFNULL(t.normalConsumed, 0) as normalConsumed, IFNULL(t.otConsumed , 0) as otConsumed, s2.salaryPoint, s2.hourlyRate, t.staffId," | |||||
| + " t.recordDate" | + " t.recordDate" | ||||
| + " from timesheet t" | + " from timesheet t" | ||||
| + " left join project_task pt on pt.id = t.projectTaskId" | + " left join project_task pt on pt.id = t.projectTaskId" | ||||
| @@ -2151,13 +2148,13 @@ open class ReportService( | |||||
| + " left join team t2 on t2.id = s.teamId" | + " left join team t2 on t2.id = s.teamId" | ||||
| + " where ISNULL(p.code) = False" | + " where ISNULL(p.code) = False" | ||||
| ) | ) | ||||
| if (clientId != null) { | |||||
| if(clientId != null){ | |||||
| sql.append( | sql.append( | ||||
| " and c.id = :clientId " | " and c.id = :clientId " | ||||
| ) | ) | ||||
| } | } | ||||
| if (teamId != null) { | |||||
| if(teamId != null){ | |||||
| sql.append( | sql.append( | ||||
| " and p.teamLead = :teamId " | " and p.teamLead = :teamId " | ||||
| ) | ) | ||||
| @@ -2176,9 +2173,9 @@ open class ReportService( | |||||
| val queryList = jdbcDao.queryForList(sql.toString(), args) | val queryList = jdbcDao.queryForList(sql.toString(), args) | ||||
| val costAndExpenseList = mutableListOf<Map<String, Any?>>() | val costAndExpenseList = mutableListOf<Map<String, Any?>>() | ||||
| for (item in queryList) { | |||||
| for(item in queryList){ | |||||
| val hourlyRate = (item.getValue("hourlyRate") as BigDecimal).toDouble() | val hourlyRate = (item.getValue("hourlyRate") as BigDecimal).toDouble() | ||||
| if (item["code"] !in costAndExpenseList) { | |||||
| if(item["code"] !in costAndExpenseList){ | |||||
| costAndExpenseList.add( | costAndExpenseList.add( | ||||
| mapOf( | mapOf( | ||||
| "code" to item["code"], | "code" to item["code"], | ||||
| @@ -2186,27 +2183,22 @@ open class ReportService( | |||||
| "client" to item["client"], | "client" to item["client"], | ||||
| "teamLead" to item["teamLead"], | "teamLead" to item["teamLead"], | ||||
| "budget" to item["expectedTotalFee"], | "budget" to item["expectedTotalFee"], | ||||
| "totalManhours" to item["normalConsumed"] as Double + item["otConsumed"] as Double, | |||||
| "manhourExpenditure" to (hourlyRate * item["normalConsumed"] as Double) | |||||
| + (hourlyRate * item["otConsumed"] as Double * otFactor) | |||||
| "totalManhours" to item["normalConsumed"] as Double + item["otConsumed"] as Double, | |||||
| "manhourExpenditure" to (hourlyRate * item["normalConsumed"] as Double ) | |||||
| + (hourlyRate * item["otConsumed"]as Double * otFactor) | |||||
| ) | ) | ||||
| ) | ) | ||||
| } else { | |||||
| }else{ | |||||
| val existingMap = costAndExpenseList.find { it.containsValue(item["code"]) }!! | val existingMap = costAndExpenseList.find { it.containsValue(item["code"]) }!! | ||||
| costAndExpenseList[costAndExpenseList.indexOf(existingMap)] = existingMap.toMutableMap().apply { | costAndExpenseList[costAndExpenseList.indexOf(existingMap)] = existingMap.toMutableMap().apply { | ||||
| put( | |||||
| "totalManhours", | |||||
| get("manhours") as Double + (item["normalConsumed"] as Double + item["otConsumed"] as Double) | |||||
| ) | |||||
| put( | |||||
| "manhourExpenditure", | |||||
| get("manhourExpenditure") as Double + ((hourlyRate * item["normalConsumed"] as Double) | |||||
| + (hourlyRate * item["otConsumed"] as Double * otFactor)) | |||||
| ) | |||||
| put("totalManhours", get("manhours") as Double + (item["normalConsumed"] as Double + item["otConsumed"] as Double)) | |||||
| put("manhourExpenditure", get("manhourExpenditure") as Double + ((hourlyRate * item["normalConsumed"] as Double ) | |||||
| + (hourlyRate * item["otConsumed"]as Double * otFactor))) | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| val result = costAndExpenseList.map { item -> | |||||
| val result = costAndExpenseList.map { | |||||
| item -> | |||||
| val budget = (item["budget"] as? Double)?.times(0.8) ?: 0.0 | val budget = (item["budget"] as? Double)?.times(0.8) ?: 0.0 | ||||
| val budgetRemain = budget - (item["manhourExpenditure"] as? Double ?: 0.0) | val budgetRemain = budget - (item["manhourExpenditure"] as? Double ?: 0.0) | ||||
| val remainingPercent = (budgetRemain / budget) | val remainingPercent = (budgetRemain / budget) | ||||
| @@ -2224,7 +2216,7 @@ open class ReportService( | |||||
| teamId: Long?, | teamId: Long?, | ||||
| clientId: Long?, | clientId: Long?, | ||||
| budgetPercentage: Double? | budgetPercentage: Double? | ||||
| ): Workbook { | |||||
| ): Workbook{ | |||||
| val resource = ClassPathResource(templatePath) | val resource = ClassPathResource(templatePath) | ||||
| val templateInputStream = resource.inputStream | val templateInputStream = resource.inputStream | ||||
| val workbook: Workbook = XSSFWorkbook(templateInputStream) | val workbook: Workbook = XSSFWorkbook(templateInputStream) | ||||
| @@ -2242,9 +2234,9 @@ open class ReportService( | |||||
| rowNum = 2 | rowNum = 2 | ||||
| val row2: Row = sheet.getRow(rowNum) | val row2: Row = sheet.getRow(rowNum) | ||||
| val row2Cell = row2.getCell(2) | val row2Cell = row2.getCell(2) | ||||
| if (teamId == null) { | |||||
| if(teamId == null){ | |||||
| row2Cell.setCellValue("All") | row2Cell.setCellValue("All") | ||||
| } else { | |||||
| }else{ | |||||
| val sql = StringBuilder( | val sql = StringBuilder( | ||||
| " select t.id, t.code, t.name, concat(t.code, \" - \" ,t.name) as teamLead from team t where t.id = :teamId " | " select t.id, t.code, t.name, concat(t.code, \" - \" ,t.name) as teamLead from team t where t.id = :teamId " | ||||
| ) | ) | ||||
| @@ -2255,9 +2247,9 @@ open class ReportService( | |||||
| rowNum = 3 | rowNum = 3 | ||||
| val row3: Row = sheet.getRow(rowNum) | val row3: Row = sheet.getRow(rowNum) | ||||
| val row3Cell = row3.getCell(2) | val row3Cell = row3.getCell(2) | ||||
| if (clientId == null) { | |||||
| if(clientId == null){ | |||||
| row3Cell.setCellValue("All") | row3Cell.setCellValue("All") | ||||
| } else { | |||||
| }else{ | |||||
| val sql = StringBuilder( | val sql = StringBuilder( | ||||
| " select c.id, c.name from customer c where c.id = :clientId " | " select c.id, c.name from customer c where c.id = :clientId " | ||||
| ) | ) | ||||
| @@ -2267,15 +2259,15 @@ open class ReportService( | |||||
| val filterList: List<Map<String, Any?>> | val filterList: List<Map<String, Any?>> | ||||
| if (budgetPercentage != null) { | |||||
| if(budgetPercentage != null){ | |||||
| filterList = costAndExpenseList.filter { ((it["budgetPercentage"] as? Double) ?: 0.0) > budgetPercentage } | filterList = costAndExpenseList.filter { ((it["budgetPercentage"] as? Double) ?: 0.0) > budgetPercentage } | ||||
| } else { | |||||
| }else{ | |||||
| filterList = costAndExpenseList | filterList = costAndExpenseList | ||||
| } | } | ||||
| rowNum = 6 | rowNum = 6 | ||||
| for (item in filterList) { | |||||
| for(item in filterList){ | |||||
| val index = filterList.indexOf(item) | val index = filterList.indexOf(item) | ||||
| val row: Row = sheet.getRow(rowNum) ?: sheet.createRow(rowNum) | val row: Row = sheet.getRow(rowNum) ?: sheet.createRow(rowNum) | ||||
| val cell = row.getCell(0) ?: row.createCell(0) | val cell = row.getCell(0) ?: row.createCell(0) | ||||
| @@ -2320,13 +2312,13 @@ open class ReportService( | |||||
| val cell7 = row.getCell(7) ?: row.createCell(7) | val cell7 = row.getCell(7) ?: row.createCell(7) | ||||
| cell7.apply { | cell7.apply { | ||||
| cellFormula = "F${rowNum + 1}-G${rowNum + 1}" | |||||
| cellFormula = "F${rowNum+1}-G${rowNum+1}" | |||||
| } | } | ||||
| CellUtil.setCellStyleProperty(cell7, "dataFormat", accountingStyle) | CellUtil.setCellStyleProperty(cell7, "dataFormat", accountingStyle) | ||||
| val cell8 = row.getCell(8) ?: row.createCell(8) | val cell8 = row.getCell(8) ?: row.createCell(8) | ||||
| cell8.apply { | cell8.apply { | ||||
| cellFormula = "H${rowNum + 1}/F${rowNum + 1}" | |||||
| cellFormula = "H${rowNum+1}/F${rowNum+1}" | |||||
| } | } | ||||
| CellUtil.setCellStyleProperty(cell8, "dataFormat", percentStyle) | CellUtil.setCellStyleProperty(cell8, "dataFormat", percentStyle) | ||||
| @@ -2336,17 +2328,11 @@ open class ReportService( | |||||
| return workbook | return workbook | ||||
| } | } | ||||
| fun genCostAndExpenseReport(request: costAndExpenseRequest): ByteArray { | |||||
| fun genCostAndExpenseReport(request: costAndExpenseRequest): ByteArray{ | |||||
| val costAndExpenseList = getCostAndExpense(request.clientId, request.teamId) | val costAndExpenseList = getCostAndExpense(request.clientId, request.teamId) | ||||
| val workbook: Workbook = createCostAndExpenseWorkbook( | |||||
| COSTANDEXPENSE_REPORT, | |||||
| costAndExpenseList, | |||||
| request.teamId, | |||||
| request.clientId, | |||||
| request.budgetPercentage | |||||
| ) | |||||
| val workbook: Workbook = createCostAndExpenseWorkbook(COSTANDEXPENSE_REPORT, costAndExpenseList, request.teamId, request.clientId, request.budgetPercentage) | |||||
| val outputStream: ByteArrayOutputStream = ByteArrayOutputStream() | val outputStream: ByteArrayOutputStream = ByteArrayOutputStream() | ||||
| workbook.write(outputStream) | workbook.write(outputStream) | ||||