|
|
@@ -63,6 +63,30 @@ open class ReportService( |
|
|
|
private val COMPLETION_PROJECT = "templates/report/AR05_Project Completion Report.xlsx" |
|
|
|
|
|
|
|
// ==============================|| 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 { |
|
|
|
|
|
|
@@ -1298,20 +1322,8 @@ open class ReportService( |
|
|
|
|
|
|
|
rowIndex = 5 |
|
|
|
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 |
|
|
|
} |
|
|
|
|
|
|
@@ -1350,20 +1362,9 @@ open class ReportService( |
|
|
|
|
|
|
|
rowIndex = 6 |
|
|
|
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 rule1 = sheetCF.createConditionalFormattingRule("AND(J7 >= $lowerLimit, J7 <= 1)") |
|
|
@@ -1529,111 +1530,107 @@ open class ReportService( |
|
|
|
) |
|
|
|
return jdbcDao.queryForList(sql.toString(), args) |
|
|
|
} |
|
|
|
|
|
|
|
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) { |
|
|
|
sql.append(" result.projectFee - (result.totalBudget - COALESCE(i.issueAmount , 0) + COALESCE(i.issueAmount, 0) - COALESCE(i.paidAmount, 0)) as `Receivable Remained`, ") |
|
|
|
} |
|
|
|
sql.append( |
|
|
|
" 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) |
|
|
|
} |
|
|
|
|
|
|
|
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) { |
|
|
|
var statusFilter: String = "" |
|
|
@@ -2126,10 +2123,10 @@ open class ReportService( |
|
|
|
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( |
|
|
|
" 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" |
|
|
|
+ " from timesheet t" |
|
|
|
+ " 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" |
|
|
|
+ " where ISNULL(p.code) = False" |
|
|
|
) |
|
|
|
if (clientId != null) { |
|
|
|
if(clientId != null){ |
|
|
|
sql.append( |
|
|
|
" and c.id = :clientId " |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
if (teamId != null) { |
|
|
|
if(teamId != null){ |
|
|
|
sql.append( |
|
|
|
" and p.teamLead = :teamId " |
|
|
|
) |
|
|
@@ -2176,9 +2173,9 @@ open class ReportService( |
|
|
|
val queryList = jdbcDao.queryForList(sql.toString(), args) |
|
|
|
val costAndExpenseList = mutableListOf<Map<String, Any?>>() |
|
|
|
|
|
|
|
for (item in queryList) { |
|
|
|
for(item in queryList){ |
|
|
|
val hourlyRate = (item.getValue("hourlyRate") as BigDecimal).toDouble() |
|
|
|
if (item["code"] !in costAndExpenseList) { |
|
|
|
if(item["code"] !in costAndExpenseList){ |
|
|
|
costAndExpenseList.add( |
|
|
|
mapOf( |
|
|
|
"code" to item["code"], |
|
|
@@ -2186,27 +2183,22 @@ open class ReportService( |
|
|
|
"client" to item["client"], |
|
|
|
"teamLead" to item["teamLead"], |
|
|
|
"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"]) }!! |
|
|
|
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 budgetRemain = budget - (item["manhourExpenditure"] as? Double ?: 0.0) |
|
|
|
val remainingPercent = (budgetRemain / budget) |
|
|
@@ -2224,7 +2216,7 @@ open class ReportService( |
|
|
|
teamId: Long?, |
|
|
|
clientId: Long?, |
|
|
|
budgetPercentage: Double? |
|
|
|
): Workbook { |
|
|
|
): Workbook{ |
|
|
|
val resource = ClassPathResource(templatePath) |
|
|
|
val templateInputStream = resource.inputStream |
|
|
|
val workbook: Workbook = XSSFWorkbook(templateInputStream) |
|
|
@@ -2242,9 +2234,9 @@ open class ReportService( |
|
|
|
rowNum = 2 |
|
|
|
val row2: Row = sheet.getRow(rowNum) |
|
|
|
val row2Cell = row2.getCell(2) |
|
|
|
if (teamId == null) { |
|
|
|
if(teamId == null){ |
|
|
|
row2Cell.setCellValue("All") |
|
|
|
} else { |
|
|
|
}else{ |
|
|
|
val sql = StringBuilder( |
|
|
|
" 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 |
|
|
|
val row3: Row = sheet.getRow(rowNum) |
|
|
|
val row3Cell = row3.getCell(2) |
|
|
|
if (clientId == null) { |
|
|
|
if(clientId == null){ |
|
|
|
row3Cell.setCellValue("All") |
|
|
|
} else { |
|
|
|
}else{ |
|
|
|
val sql = StringBuilder( |
|
|
|
" 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?>> |
|
|
|
if (budgetPercentage != null) { |
|
|
|
if(budgetPercentage != null){ |
|
|
|
filterList = costAndExpenseList.filter { ((it["budgetPercentage"] as? Double) ?: 0.0) > budgetPercentage } |
|
|
|
} else { |
|
|
|
}else{ |
|
|
|
filterList = costAndExpenseList |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
rowNum = 6 |
|
|
|
for (item in filterList) { |
|
|
|
for(item in filterList){ |
|
|
|
val index = filterList.indexOf(item) |
|
|
|
val row: Row = sheet.getRow(rowNum) ?: sheet.createRow(rowNum) |
|
|
|
val cell = row.getCell(0) ?: row.createCell(0) |
|
|
@@ -2320,13 +2312,13 @@ open class ReportService( |
|
|
|
|
|
|
|
val cell7 = row.getCell(7) ?: row.createCell(7) |
|
|
|
cell7.apply { |
|
|
|
cellFormula = "F${rowNum + 1}-G${rowNum + 1}" |
|
|
|
cellFormula = "F${rowNum+1}-G${rowNum+1}" |
|
|
|
} |
|
|
|
CellUtil.setCellStyleProperty(cell7, "dataFormat", accountingStyle) |
|
|
|
|
|
|
|
val cell8 = row.getCell(8) ?: row.createCell(8) |
|
|
|
cell8.apply { |
|
|
|
cellFormula = "H${rowNum + 1}/F${rowNum + 1}" |
|
|
|
cellFormula = "H${rowNum+1}/F${rowNum+1}" |
|
|
|
} |
|
|
|
CellUtil.setCellStyleProperty(cell8, "dataFormat", percentStyle) |
|
|
|
|
|
|
@@ -2336,17 +2328,11 @@ open class ReportService( |
|
|
|
return workbook |
|
|
|
} |
|
|
|
|
|
|
|
fun genCostAndExpenseReport(request: costAndExpenseRequest): ByteArray { |
|
|
|
fun genCostAndExpenseReport(request: costAndExpenseRequest): ByteArray{ |
|
|
|
|
|
|
|
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() |
|
|
|
workbook.write(outputStream) |
|
|
|