|
@@ -855,6 +855,46 @@ open class ReportService( |
|
|
combinedResults.forEach { result: String -> |
|
|
combinedResults.forEach { result: String -> |
|
|
|
|
|
|
|
|
if (groupedInvoices.containsKey(result)) { |
|
|
if (groupedInvoices.containsKey(result)) { |
|
|
|
|
|
if (dateType == "Date") { |
|
|
|
|
|
groupedInvoices[result]!!.forEachIndexed { _, invoice -> |
|
|
|
|
|
sheet.createRow(rowIndex++).apply { |
|
|
|
|
|
createCell(0).apply { |
|
|
|
|
|
setCellValue(result) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
createCell(1).apply { |
|
|
|
|
|
setCellValue(0.0) |
|
|
|
|
|
cellStyle.dataFormat = accountingStyle |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
createCell(2).apply { |
|
|
|
|
|
setCellValue(invoice["paidAmount"] as Double? ?: 0.0) |
|
|
|
|
|
cellStyle.dataFormat = accountingStyle |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
createCell(3).apply { |
|
|
|
|
|
val lastRow = rowIndex - 1 |
|
|
|
|
|
if (lastRow == 16) { |
|
|
|
|
|
cellFormula = |
|
|
|
|
|
"C{currentRow}-B{currentRow}".replace("{currentRow}", rowIndex.toString()) |
|
|
|
|
|
} else { |
|
|
|
|
|
cellFormula = |
|
|
|
|
|
"IF(B{currentRow}>0,D{lastRow}-B{currentRow},D{lastRow}+C{currentRow})".replace( |
|
|
|
|
|
"{currentRow}", |
|
|
|
|
|
rowIndex.toString() |
|
|
|
|
|
).replace("{lastRow}", lastRow.toString()) |
|
|
|
|
|
} |
|
|
|
|
|
cellStyle.dataFormat = accountingStyle |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
createCell(4)?.apply { |
|
|
|
|
|
setCellValue( |
|
|
|
|
|
"Invoice Receipt: " + (invoice["invoiceNo"] as String? ?: "N/A").toString() |
|
|
|
|
|
) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
// groupedInvoices[result]!!.forEachIndexed { _, invoice -> |
|
|
// groupedInvoices[result]!!.forEachIndexed { _, invoice -> |
|
|
sheet.createRow(rowIndex++).apply { |
|
|
sheet.createRow(rowIndex++).apply { |
|
|
createCell(0).apply { |
|
|
createCell(0).apply { |
|
@@ -888,9 +928,16 @@ open class ReportService( |
|
|
|
|
|
|
|
|
createCell(4)?.apply { |
|
|
createCell(4)?.apply { |
|
|
// setCellValue(invoice["description"].toString()) |
|
|
// setCellValue(invoice["description"].toString()) |
|
|
setCellValue("Invoice Receipt: " + (groupedInvoices[result]?.map { it["invoiceNo"] }?.joinToString() ?: "N/A").toString()) |
|
|
|
|
|
|
|
|
val invoiceNos = groupedInvoices[result]?.map { it["invoiceNo"] } |
|
|
|
|
|
if (invoiceNos?.size != null && invoiceNos.size > 1) { |
|
|
|
|
|
// setCellValue("Invoice Receipt: " + (groupedInvoices[result]?.map { it["invoiceNo"] }?.joinToString() ?: "N/A").toString()) |
|
|
|
|
|
setCellValue("Multiple Invoices") |
|
|
|
|
|
} else { |
|
|
|
|
|
setCellValue("Invoice Receipt: " + (invoiceNos?.joinToString() ?: "N/A").toString()) |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
// } |
|
|
// } |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@@ -1353,7 +1400,7 @@ open class ReportService( |
|
|
for (i in 0 until rowSize) { |
|
|
for (i in 0 until rowSize) { |
|
|
tempCell = sheet.getRow(8 + i).createCell(columnIndex + index) |
|
|
tempCell = sheet.getRow(8 + i).createCell(columnIndex + index) |
|
|
tempCell.setCellValue(0.0) |
|
|
tempCell.setCellValue(0.0) |
|
|
if ( 8+i in holidayIndexList) { |
|
|
|
|
|
|
|
|
if (8 + i in holidayIndexList) { |
|
|
tempCell.cellStyle = fillOrange |
|
|
tempCell.cellStyle = fillOrange |
|
|
} |
|
|
} |
|
|
tempCell.cellStyle.dataFormat = accountingStyle |
|
|
tempCell.cellStyle.dataFormat = accountingStyle |
|
@@ -1365,7 +1412,7 @@ open class ReportService( |
|
|
dayInt = temp[index]["date"].toString().toInt() |
|
|
dayInt = temp[index]["date"].toString().toInt() |
|
|
tempCell = sheet.getRow(dayInt.plus(7)).createCell(columnIndex) |
|
|
tempCell = sheet.getRow(dayInt.plus(7)).createCell(columnIndex) |
|
|
tempCell.setCellValue((temp[index]["normalConsumed"] as Double) + (temp[index]["otConsumed"] as Double)) |
|
|
tempCell.setCellValue((temp[index]["normalConsumed"] as Double) + (temp[index]["otConsumed"] as Double)) |
|
|
if ( dayInt.plus(7) in holidayIndexList) { |
|
|
|
|
|
|
|
|
if (dayInt.plus(7) in holidayIndexList) { |
|
|
tempCell.cellStyle = fillOrange |
|
|
tempCell.cellStyle = fillOrange |
|
|
tempCell.cellStyle.dataFormat = accountingStyle |
|
|
tempCell.cellStyle.dataFormat = accountingStyle |
|
|
} |
|
|
} |
|
@@ -1377,7 +1424,7 @@ open class ReportService( |
|
|
for (i in 0 until rowSize) { |
|
|
for (i in 0 until rowSize) { |
|
|
tempCell = sheet.getRow(8 + i).createCell(columnIndex) |
|
|
tempCell = sheet.getRow(8 + i).createCell(columnIndex) |
|
|
tempCell.setCellValue(0.0) |
|
|
tempCell.setCellValue(0.0) |
|
|
if ( 8+i in holidayIndexList) { |
|
|
|
|
|
|
|
|
if (8 + i in holidayIndexList) { |
|
|
tempCell.cellStyle = fillOrange |
|
|
tempCell.cellStyle = fillOrange |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
@@ -1388,7 +1435,7 @@ open class ReportService( |
|
|
dayInt = leave["recordDate"].toString().toInt() |
|
|
dayInt = leave["recordDate"].toString().toInt() |
|
|
tempCell = sheet.getRow(dayInt.plus(7)).createCell(columnIndex) |
|
|
tempCell = sheet.getRow(dayInt.plus(7)).createCell(columnIndex) |
|
|
tempCell.setCellValue(leave["leaveHours"] as Double) |
|
|
tempCell.setCellValue(leave["leaveHours"] as Double) |
|
|
if ( dayInt.plus(7) in holidayIndexList) { |
|
|
|
|
|
|
|
|
if (dayInt.plus(7) in holidayIndexList) { |
|
|
tempCell.cellStyle = fillOrange |
|
|
tempCell.cellStyle = fillOrange |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
@@ -1420,7 +1467,7 @@ open class ReportService( |
|
|
tempCell = sheet.getRow(rowIndex).createCell(columnIndex) |
|
|
tempCell = sheet.getRow(rowIndex).createCell(columnIndex) |
|
|
tempCell.cellFormula = |
|
|
tempCell.cellFormula = |
|
|
"SUM(${getColumnAlphabet(2)}${rowIndex + 1}:${getColumnAlphabet(columnIndex - 2)}${rowIndex + 1})" // should columnIndex - 2 |
|
|
"SUM(${getColumnAlphabet(2)}${rowIndex + 1}:${getColumnAlphabet(columnIndex - 2)}${rowIndex + 1})" // should columnIndex - 2 |
|
|
if ( rowIndex in holidayIndexList) { |
|
|
|
|
|
|
|
|
if (rowIndex in holidayIndexList) { |
|
|
tempCell.cellStyle = fillOrange |
|
|
tempCell.cellStyle = fillOrange |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
@@ -1495,21 +1542,21 @@ open class ReportService( |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
val cell2 = getCell(2) ?: createCell(2) |
|
|
val cell2 = getCell(2) ?: createCell(2) |
|
|
cell2.cellFormula = "(B{currentRow}+D{currentRow})-1".replace("{currentRow}", (rowIndex+1).toString()) |
|
|
|
|
|
|
|
|
cell2.cellFormula = "(B{currentRow}+D{currentRow})-1".replace("{currentRow}", (rowIndex + 1).toString()) |
|
|
CellUtil.setAlignment(cell2, HorizontalAlignment.CENTER) |
|
|
CellUtil.setAlignment(cell2, HorizontalAlignment.CENTER) |
|
|
cell2.cellStyle.dataFormat = defaultStyle |
|
|
cell2.cellStyle.dataFormat = defaultStyle |
|
|
// getCell(2).cellStyle.dataFormat = accountingStyle |
|
|
// getCell(2).cellStyle.dataFormat = accountingStyle |
|
|
|
|
|
|
|
|
val cell3 = getCell(3)?:createCell(3) |
|
|
|
|
|
|
|
|
val cell3 = getCell(3) ?: createCell(3) |
|
|
cell3.setCellValue(salary.increment.toDouble()) |
|
|
cell3.setCellValue(salary.increment.toDouble()) |
|
|
cell3.cellStyle = fillOrange |
|
|
cell3.cellStyle = fillOrange |
|
|
cell3.cellStyle.dataFormat = defaultStyle |
|
|
cell3.cellStyle.dataFormat = defaultStyle |
|
|
CellUtil.setAlignment(cell3, HorizontalAlignment.CENTER) |
|
|
CellUtil.setAlignment(cell3, HorizontalAlignment.CENTER) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val cell4 = getCell(4)?:createCell(4) |
|
|
|
|
|
|
|
|
val cell4 = getCell(4) ?: createCell(4) |
|
|
cell4.cellFormula = |
|
|
cell4.cellFormula = |
|
|
"(((C{currentRow}+B{currentRow})/2)/20)/8".replace("{currentRow}", (rowIndex+1).toString()) |
|
|
|
|
|
|
|
|
"(((C{currentRow}+B{currentRow})/2)/20)/8".replace("{currentRow}", (rowIndex + 1).toString()) |
|
|
// getCell(4).cellStyle.dataFormat = accountingStyle |
|
|
// getCell(4).cellStyle.dataFormat = accountingStyle |
|
|
cell4.cellStyle.dataFormat = accountingStyle |
|
|
cell4.cellStyle.dataFormat = accountingStyle |
|
|
CellUtil.setAlignment(cell4, HorizontalAlignment.CENTER) |
|
|
CellUtil.setAlignment(cell4, HorizontalAlignment.CENTER) |
|
@@ -1979,52 +2026,53 @@ open class ReportService( |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
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" |
|
|
|
|
|
+ " 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," |
|
|
|
|
|
+ " 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' " |
|
|
) |
|
|
) |
|
|
if (args != null) { |
|
|
if (args != null) { |
|
|
var statusFilter: String = "" |
|
|
var statusFilter: String = "" |
|
@@ -2041,6 +2089,7 @@ open class ReportService( |
|
|
" and (COALESCE((tns.totalConsumed * sa.hourlyRate), 0) / p.expectedTotalFee) <= 1 " + |
|
|
" and (COALESCE((tns.totalConsumed * sa.hourlyRate), 0) / p.expectedTotalFee) <= 1 " + |
|
|
" or (COALESCE(tns.totalConsumed, 0) / COALESCE(p.totalManhour, 0)) >= :lowerLimit " + |
|
|
" or (COALESCE(tns.totalConsumed, 0) / COALESCE(p.totalManhour, 0)) >= :lowerLimit " + |
|
|
" and (COALESCE(tns.totalConsumed, 0) / COALESCE(p.totalManhour, 0)) <= 1 " |
|
|
" and (COALESCE(tns.totalConsumed, 0) / COALESCE(p.totalManhour, 0)) <= 1 " |
|
|
|
|
|
|
|
|
"All" -> " and " + |
|
|
"All" -> " and " + |
|
|
" (COALESCE((tns.totalConsumed * sa.hourlyRate), 0) / p.expectedTotalFee) >= :lowerLimit " + |
|
|
" (COALESCE((tns.totalConsumed * sa.hourlyRate), 0) / p.expectedTotalFee) >= :lowerLimit " + |
|
|
" or (COALESCE(tns.totalConsumed, 0) / COALESCE(p.totalManhour, 0)) >= :lowerLimit " |
|
|
" or (COALESCE(tns.totalConsumed, 0) / COALESCE(p.totalManhour, 0)) >= :lowerLimit " |
|
@@ -2105,17 +2154,17 @@ open class ReportService( |
|
|
+ " order by g.code, s.name, cte_ts.recordDate" |
|
|
+ " order by g.code, s.name, cte_ts.recordDate" |
|
|
) |
|
|
) |
|
|
val projectPlanStartEndMonth = projectRepository.findProjectPlanStartEndByIdAndDeletedFalse(projectId) |
|
|
val projectPlanStartEndMonth = projectRepository.findProjectPlanStartEndByIdAndDeletedFalse(projectId) |
|
|
val compareStartMonth= YearMonth.parse(startMonth) |
|
|
|
|
|
val compareEndMonth= YearMonth.parse(endMonth) |
|
|
|
|
|
|
|
|
val compareStartMonth = YearMonth.parse(startMonth) |
|
|
|
|
|
val compareEndMonth = YearMonth.parse(endMonth) |
|
|
val actualStartMonth: YearMonth |
|
|
val actualStartMonth: YearMonth |
|
|
(if (projectPlanStartEndMonth.actualStart == null){ |
|
|
|
|
|
|
|
|
(if (projectPlanStartEndMonth.actualStart == null) { |
|
|
YearMonth.now().plusMonths(1) |
|
|
YearMonth.now().plusMonths(1) |
|
|
}else{ |
|
|
|
|
|
|
|
|
} else { |
|
|
YearMonth.from(projectPlanStartEndMonth.actualStart) |
|
|
YearMonth.from(projectPlanStartEndMonth.actualStart) |
|
|
}).also { actualStartMonth = it } |
|
|
}).also { actualStartMonth = it } |
|
|
|
|
|
|
|
|
val queryStartMonth = if(compareStartMonth.isAfter(actualStartMonth)) compareStartMonth else actualStartMonth |
|
|
|
|
|
val queryEndMonth = if(compareEndMonth.isAfter(YearMonth.now())) YearMonth.now() else compareEndMonth |
|
|
|
|
|
|
|
|
val queryStartMonth = if (compareStartMonth.isAfter(actualStartMonth)) compareStartMonth else actualStartMonth |
|
|
|
|
|
val queryEndMonth = if (compareEndMonth.isAfter(YearMonth.now())) YearMonth.now() else compareEndMonth |
|
|
|
|
|
|
|
|
val args = mapOf( |
|
|
val args = mapOf( |
|
|
"projectId" to projectId, |
|
|
"projectId" to projectId, |
|
@@ -2251,7 +2300,8 @@ open class ReportService( |
|
|
|
|
|
|
|
|
val manhoursSpentList = getManhoursSpent(projectId, startMonth, endMonth) |
|
|
val manhoursSpentList = getManhoursSpent(projectId, startMonth, endMonth) |
|
|
|
|
|
|
|
|
val workbook: Workbook = createPandLReportWorkbook(PandL_REPORT, manhoursSpentList, startMonth, endMonth, projectId) |
|
|
|
|
|
|
|
|
val workbook: Workbook = |
|
|
|
|
|
createPandLReportWorkbook(PandL_REPORT, manhoursSpentList, startMonth, endMonth, projectId) |
|
|
|
|
|
|
|
|
val outputStream: ByteArrayOutputStream = ByteArrayOutputStream() |
|
|
val outputStream: ByteArrayOutputStream = ByteArrayOutputStream() |
|
|
workbook.write(outputStream) |
|
|
workbook.write(outputStream) |
|
@@ -2274,17 +2324,17 @@ open class ReportService( |
|
|
val accountingStyle = workbook.createDataFormat().getFormat("_(* #,##0.00_);_(* (#,##0.00);_(* \"-\"??_);_(@_)") |
|
|
val accountingStyle = workbook.createDataFormat().getFormat("_(* #,##0.00_);_(* (#,##0.00);_(* \"-\"??_);_(@_)") |
|
|
|
|
|
|
|
|
val projectPlanStartEndMonth = projectRepository.findProjectPlanStartEndByIdAndDeletedFalse(projectId) |
|
|
val projectPlanStartEndMonth = projectRepository.findProjectPlanStartEndByIdAndDeletedFalse(projectId) |
|
|
val compareStartMonth= YearMonth.parse(startMonth) |
|
|
|
|
|
val compareEndMonth= YearMonth.parse(endMonth) |
|
|
|
|
|
|
|
|
val compareStartMonth = YearMonth.parse(startMonth) |
|
|
|
|
|
val compareEndMonth = YearMonth.parse(endMonth) |
|
|
val actualStartMonth: YearMonth |
|
|
val actualStartMonth: YearMonth |
|
|
(if (projectPlanStartEndMonth.actualStart == null){ |
|
|
|
|
|
|
|
|
(if (projectPlanStartEndMonth.actualStart == null) { |
|
|
YearMonth.now().plusMonths(1) |
|
|
YearMonth.now().plusMonths(1) |
|
|
}else{ |
|
|
|
|
|
|
|
|
} else { |
|
|
YearMonth.from(projectPlanStartEndMonth.actualStart) |
|
|
YearMonth.from(projectPlanStartEndMonth.actualStart) |
|
|
}).also { actualStartMonth = it } |
|
|
}).also { actualStartMonth = it } |
|
|
|
|
|
|
|
|
val queryStartMonth = if(compareStartMonth.isAfter(actualStartMonth)) compareStartMonth else actualStartMonth |
|
|
|
|
|
val queryEndMonth = if(compareEndMonth.isAfter(YearMonth.now())) YearMonth.now() else compareEndMonth |
|
|
|
|
|
|
|
|
val queryStartMonth = if (compareStartMonth.isAfter(actualStartMonth)) compareStartMonth else actualStartMonth |
|
|
|
|
|
val queryEndMonth = if (compareEndMonth.isAfter(YearMonth.now())) YearMonth.now() else compareEndMonth |
|
|
|
|
|
|
|
|
val monthFormat = DateTimeFormatter.ofPattern("MMM yyyy", Locale.ENGLISH) |
|
|
val monthFormat = DateTimeFormatter.ofPattern("MMM yyyy", Locale.ENGLISH) |
|
|
val startDate = YearMonth.parse(queryStartMonth.toString(), DateTimeFormatter.ofPattern("yyyy-MM")) |
|
|
val startDate = YearMonth.parse(queryStartMonth.toString(), DateTimeFormatter.ofPattern("yyyy-MM")) |
|
@@ -2294,7 +2344,7 @@ open class ReportService( |
|
|
|
|
|
|
|
|
val monthRange: MutableList<Map<String, Any>> = ArrayList() |
|
|
val monthRange: MutableList<Map<String, Any>> = ArrayList() |
|
|
var currentDate = startDate |
|
|
var currentDate = startDate |
|
|
if (currentDate == endDate){ |
|
|
|
|
|
|
|
|
if (currentDate == endDate) { |
|
|
monthRange.add( |
|
|
monthRange.add( |
|
|
mapOf( |
|
|
mapOf( |
|
|
"display" to YearMonth.of(currentDate.year, currentDate.month).format(monthFormat), |
|
|
"display" to YearMonth.of(currentDate.year, currentDate.month).format(monthFormat), |
|
@@ -2575,7 +2625,7 @@ open class ReportService( |
|
|
} |
|
|
} |
|
|
// CellUtil.setCellStyleProperty(panlCellTitle, "borderBottom", BorderStyle.DOUBLE) |
|
|
// CellUtil.setCellStyleProperty(panlCellTitle, "borderBottom", BorderStyle.DOUBLE) |
|
|
// CellUtil.setCellStyleProperty(panlCell, "borderBottom", BorderStyle.DOUBLE) |
|
|
// CellUtil.setCellStyleProperty(panlCell, "borderBottom", BorderStyle.DOUBLE) |
|
|
val profitAndLossRowNum = rowNum+1 |
|
|
|
|
|
|
|
|
val profitAndLossRowNum = rowNum + 1 |
|
|
|
|
|
|
|
|
rowNum += 1 |
|
|
rowNum += 1 |
|
|
val uninvoicedAmountRow: Row = sheet.getRow(rowNum) ?: sheet.createRow(rowNum) |
|
|
val uninvoicedAmountRow: Row = sheet.getRow(rowNum) ?: sheet.createRow(rowNum) |
|
@@ -2585,7 +2635,7 @@ open class ReportService( |
|
|
} |
|
|
} |
|
|
val uninvoicedAmountCell = uninvoicedAmountRow.getCell(1) ?: uninvoicedAmountRow.createCell(1) |
|
|
val uninvoicedAmountCell = uninvoicedAmountRow.getCell(1) ?: uninvoicedAmountRow.createCell(1) |
|
|
uninvoicedAmountCell.apply { |
|
|
uninvoicedAmountCell.apply { |
|
|
setCellValue(if ((info.getValue("expectedTotalFee") as Double) < 0.0 ) 0.0 else info.getValue("expectedTotalFee") as Double) |
|
|
|
|
|
|
|
|
setCellValue(if ((info.getValue("expectedTotalFee") as Double) < 0.0) 0.0 else info.getValue("expectedTotalFee") as Double) |
|
|
cellStyle.dataFormat = accountingStyle |
|
|
cellStyle.dataFormat = accountingStyle |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@@ -2597,7 +2647,7 @@ open class ReportService( |
|
|
} |
|
|
} |
|
|
val projectedPnLCell = projectedPnLRow.getCell(1) ?: projectedPnLRow.createCell(1) |
|
|
val projectedPnLCell = projectedPnLRow.getCell(1) ?: projectedPnLRow.createCell(1) |
|
|
projectedPnLCell.apply { |
|
|
projectedPnLCell.apply { |
|
|
cellFormula = "B${profitAndLossRowNum}+B${profitAndLossRowNum+1}" |
|
|
|
|
|
|
|
|
cellFormula = "B${profitAndLossRowNum}+B${profitAndLossRowNum + 1}" |
|
|
cellStyle.dataFormat = accountingStyle |
|
|
cellStyle.dataFormat = accountingStyle |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@@ -3063,7 +3113,8 @@ open class ReportService( |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
createCell(columnIndex++).apply { |
|
|
createCell(columnIndex++).apply { |
|
|
val cellValue = grade.name.trim().substring(0,1) + grade.name.trim().substring(grade.name.length - 1) + " - Cost Adjusted by Salary Point" |
|
|
|
|
|
|
|
|
val cellValue = grade.name.trim().substring(0, 1) + grade.name.trim() |
|
|
|
|
|
.substring(grade.name.length - 1) + " - Cost Adjusted by Salary Point" |
|
|
setCellValue(cellValue) |
|
|
setCellValue(cellValue) |
|
|
val cloneStyle = workbook.createCellStyle() |
|
|
val cloneStyle = workbook.createCellStyle() |
|
|
cloneStyle.cloneStyleFrom(boldFontWithBorderStyle) |
|
|
cloneStyle.cloneStyleFrom(boldFontWithBorderStyle) |
|
|