|
@@ -178,8 +178,8 @@ open class ReportService( |
|
|
searchedClient: String, |
|
|
searchedClient: String, |
|
|
projects: List<Project>, |
|
|
projects: List<Project>, |
|
|
timesheets: List<Timesheet>, |
|
|
timesheets: List<Timesheet>, |
|
|
numberOfDays: Int, |
|
|
|
|
|
projectCompletion: Int, |
|
|
|
|
|
|
|
|
daysUntilCurrentStageEnd: Int, |
|
|
|
|
|
resourceUtilizationPercentage: Int, |
|
|
): ByteArray { |
|
|
): ByteArray { |
|
|
// Generate the Excel report with query results |
|
|
// Generate the Excel report with query results |
|
|
val workbook: Workbook = createProjectPotentialDelayReport( |
|
|
val workbook: Workbook = createProjectPotentialDelayReport( |
|
@@ -187,8 +187,8 @@ open class ReportService( |
|
|
searchedClient, |
|
|
searchedClient, |
|
|
projects, |
|
|
projects, |
|
|
timesheets, |
|
|
timesheets, |
|
|
numberOfDays, |
|
|
|
|
|
projectCompletion, |
|
|
|
|
|
|
|
|
daysUntilCurrentStageEnd, |
|
|
|
|
|
resourceUtilizationPercentage, |
|
|
PROJECT_POTENTIAL_DELAY_REPORT |
|
|
PROJECT_POTENTIAL_DELAY_REPORT |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
@@ -673,15 +673,30 @@ open class ReportService( |
|
|
|
|
|
|
|
|
rowIndex = 4 |
|
|
rowIndex = 4 |
|
|
sheet.getRow(rowIndex).createCell(columnIndex).apply { |
|
|
sheet.getRow(rowIndex).createCell(columnIndex).apply { |
|
|
setCellValue(if (project.customer?.name == null) "N/A" else project.customer?.name) |
|
|
|
|
|
|
|
|
setCellValue( |
|
|
|
|
|
if (project.customer?.code != null && project.customer?.name != null) project.customer!!.code + " - " + project.customer!!.name |
|
|
|
|
|
else if (project.customer?.code != null) project.customer!!.code |
|
|
|
|
|
else if (project.customer?.name != null) project.customer!!.name |
|
|
|
|
|
else "N/A" |
|
|
|
|
|
) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
rowIndex = 5 |
|
|
rowIndex = 5 |
|
|
|
|
|
sheet.getRow(rowIndex).createCell(columnIndex).apply { |
|
|
|
|
|
setCellValue( |
|
|
|
|
|
if (project.customerSubsidiary?.code != null && project.customerSubsidiary?.name != null) project.customerSubsidiary!!.code + " - " + project.customerSubsidiary!!.name |
|
|
|
|
|
else if (project.customerSubsidiary?.code != null) project.customerSubsidiary!!.code |
|
|
|
|
|
else if (project.customerSubsidiary?.name != null) project.customerSubsidiary!!.name |
|
|
|
|
|
else "N/A" |
|
|
|
|
|
) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
rowIndex = 6 |
|
|
sheet.getRow(rowIndex).createCell(columnIndex).apply { |
|
|
sheet.getRow(rowIndex).createCell(columnIndex).apply { |
|
|
setCellValue(if (project.teamLead?.team?.name == null) "N/A" else project.teamLead?.team?.name) |
|
|
setCellValue(if (project.teamLead?.team?.name == null) "N/A" else project.teamLead?.team?.name) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
rowIndex = 9 |
|
|
|
|
|
|
|
|
rowIndex = 10 |
|
|
sheet.getRow(rowIndex).apply { |
|
|
sheet.getRow(rowIndex).apply { |
|
|
createCell(1).apply { |
|
|
createCell(1).apply { |
|
|
setCellValue(project.expectedTotalFee!! * 0.8) |
|
|
setCellValue(project.expectedTotalFee!! * 0.8) |
|
@@ -694,7 +709,7 @@ open class ReportService( |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
rowIndex = 10 |
|
|
|
|
|
|
|
|
rowIndex = 11 |
|
|
val actualIncome = invoices.sumOf { invoice -> invoice.paidAmount!! } |
|
|
val actualIncome = invoices.sumOf { invoice -> invoice.paidAmount!! } |
|
|
val actualExpenditure = timesheets.sumOf { timesheet -> |
|
|
val actualExpenditure = timesheets.sumOf { timesheet -> |
|
|
timesheet.staff!!.salary.hourlyRate.toDouble() * ((timesheet.normalConsumed ?: 0.0) + (timesheet.otConsumed |
|
|
timesheet.staff!!.salary.hourlyRate.toDouble() * ((timesheet.normalConsumed ?: 0.0) + (timesheet.otConsumed |
|
@@ -712,21 +727,20 @@ open class ReportService( |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
rowIndex = 11 |
|
|
|
|
|
|
|
|
rowIndex = 12 |
|
|
sheet.getRow(rowIndex).apply { |
|
|
sheet.getRow(rowIndex).apply { |
|
|
createCell(1).apply { |
|
|
createCell(1).apply { |
|
|
cellFormula = "B10-B11" |
|
|
|
|
|
|
|
|
cellFormula = "B11-B12" |
|
|
cellStyle.dataFormat = accountingStyle |
|
|
cellStyle.dataFormat = accountingStyle |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
createCell(2).apply { |
|
|
createCell(2).apply { |
|
|
cellFormula = "C10-C11" |
|
|
|
|
|
|
|
|
cellFormula = "C11-C12" |
|
|
cellStyle.dataFormat = accountingStyle |
|
|
cellStyle.dataFormat = accountingStyle |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
rowIndex = 15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rowIndex = 16 |
|
|
|
|
|
|
|
|
val dateFormatter = |
|
|
val dateFormatter = |
|
|
if (dateType == "Date") DateTimeFormatter.ofPattern("yyyy/MM/dd") else DateTimeFormatter.ofPattern("MMM YYYY") |
|
|
if (dateType == "Date") DateTimeFormatter.ofPattern("yyyy/MM/dd") else DateTimeFormatter.ofPattern("MMM YYYY") |
|
@@ -796,7 +810,7 @@ open class ReportService( |
|
|
|
|
|
|
|
|
createCell(3).apply { |
|
|
createCell(3).apply { |
|
|
val lastRow = rowIndex - 1 |
|
|
val lastRow = rowIndex - 1 |
|
|
if (lastRow == 15) { |
|
|
|
|
|
|
|
|
if (lastRow == 16) { |
|
|
cellFormula = |
|
|
cellFormula = |
|
|
"C{currentRow}-B{currentRow}".replace("{currentRow}", rowIndex.toString()) |
|
|
"C{currentRow}-B{currentRow}".replace("{currentRow}", rowIndex.toString()) |
|
|
} else { |
|
|
} else { |
|
@@ -835,7 +849,7 @@ open class ReportService( |
|
|
|
|
|
|
|
|
createCell(3).apply { |
|
|
createCell(3).apply { |
|
|
val lastRow = rowIndex - 1 |
|
|
val lastRow = rowIndex - 1 |
|
|
if (lastRow == 15) { |
|
|
|
|
|
|
|
|
if (lastRow == 16) { |
|
|
cellFormula = "C{currentRow}-B{currentRow}".replace("{currentRow}", rowIndex.toString()) |
|
|
cellFormula = "C{currentRow}-B{currentRow}".replace("{currentRow}", rowIndex.toString()) |
|
|
} else { |
|
|
} else { |
|
|
cellFormula = |
|
|
cellFormula = |
|
@@ -863,8 +877,8 @@ open class ReportService( |
|
|
searchedClient: String, |
|
|
searchedClient: String, |
|
|
projects: List<Project>, |
|
|
projects: List<Project>, |
|
|
timesheets: List<Timesheet>, |
|
|
timesheets: List<Timesheet>, |
|
|
numberOfDays: Int, |
|
|
|
|
|
projectCompletion: Int, |
|
|
|
|
|
|
|
|
daysUntilCurrentStageEnd: Int, |
|
|
|
|
|
resourceUtilizationPercentage: Int, |
|
|
templatePath: String, |
|
|
templatePath: String, |
|
|
): Workbook { |
|
|
): Workbook { |
|
|
// please create a new function for each report template |
|
|
// please create a new function for each report template |
|
@@ -939,15 +953,29 @@ open class ReportService( |
|
|
|
|
|
|
|
|
createCell(4).apply { |
|
|
createCell(4).apply { |
|
|
val currentClient = project.customer |
|
|
val currentClient = project.customer |
|
|
val currentSubsidiary = project.customerSubsidiary |
|
|
|
|
|
setCellValue(if (currentSubsidiary != null) currentSubsidiary.code + " - " + currentSubsidiary.name else currentClient?.code + " - " + currentClient?.name) |
|
|
|
|
|
|
|
|
setCellValue( |
|
|
|
|
|
if (currentClient?.code != null && currentClient.name != null) currentClient.code + " - " + currentClient.name |
|
|
|
|
|
else if (currentClient?.code != null) currentClient.code |
|
|
|
|
|
else if (currentClient?.name != null) currentClient.name |
|
|
|
|
|
else "N/A" |
|
|
|
|
|
) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
createCell(5).apply { |
|
|
createCell(5).apply { |
|
|
setCellValue(project.actualStart?.format(DATE_FORMATTER)) |
|
|
|
|
|
|
|
|
val currentSubsidiary = project.customerSubsidiary |
|
|
|
|
|
setCellValue( |
|
|
|
|
|
if (currentSubsidiary?.code != null && currentSubsidiary.name != null) currentSubsidiary.code + " - " + currentSubsidiary.name |
|
|
|
|
|
else if (currentSubsidiary?.code != null) currentSubsidiary.code |
|
|
|
|
|
else if (currentSubsidiary?.name != null) currentSubsidiary.name |
|
|
|
|
|
else "N/A" |
|
|
|
|
|
) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
createCell(6).apply { |
|
|
createCell(6).apply { |
|
|
|
|
|
setCellValue(project.actualStart?.format(DATE_FORMATTER)) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
createCell(7).apply { |
|
|
setCellValue(project.planEnd?.format(DATE_FORMATTER)) |
|
|
setCellValue(project.planEnd?.format(DATE_FORMATTER)) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@@ -958,22 +986,22 @@ open class ReportService( |
|
|
val manHoursSpent = groupedTimesheets[Pair(project.id, milestone.id)]?.sum() ?: 0.0 |
|
|
val manHoursSpent = groupedTimesheets[Pair(project.id, milestone.id)]?.sum() ?: 0.0 |
|
|
val resourceUtilization = manHoursSpent / (milestone.stagePercentAllocation!! / 100 * project.totalManhour!!) |
|
|
val resourceUtilization = manHoursSpent / (milestone.stagePercentAllocation!! / 100 * project.totalManhour!!) |
|
|
// logger.info(project.name + " : " + milestone.taskGroup?.name + " : " + ChronoUnit.DAYS.between(LocalDate.now(), milestone.endDate)) |
|
|
// logger.info(project.name + " : " + milestone.taskGroup?.name + " : " + ChronoUnit.DAYS.between(LocalDate.now(), milestone.endDate)) |
|
|
// logger.info(numberOfDays) |
|
|
|
|
|
if (ChronoUnit.DAYS.between(LocalDate.now(), milestone.endDate) <= numberOfDays.toLong() && resourceUtilization <= projectCompletion.toDouble() / 100.0) { |
|
|
|
|
|
|
|
|
// logger.info(daysUntilCurrentStageEnd) |
|
|
|
|
|
if (ChronoUnit.DAYS.between(LocalDate.now(), milestone.endDate) <= daysUntilCurrentStageEnd.toLong() && resourceUtilization <= resourceUtilizationPercentage.toDouble() / 100.0) { |
|
|
milestoneCount++ |
|
|
milestoneCount++ |
|
|
val tempRow = sheet.getRow(rowIndex) ?: sheet.createRow(rowIndex) |
|
|
val tempRow = sheet.getRow(rowIndex) ?: sheet.createRow(rowIndex) |
|
|
rowIndex++ |
|
|
rowIndex++ |
|
|
|
|
|
|
|
|
tempRow.apply { |
|
|
tempRow.apply { |
|
|
createCell(7).apply { |
|
|
|
|
|
|
|
|
createCell(8).apply { |
|
|
setCellValue(milestone.taskGroup?.name ?: "N/A") |
|
|
setCellValue(milestone.taskGroup?.name ?: "N/A") |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
createCell(8).apply { |
|
|
|
|
|
|
|
|
createCell(9).apply { |
|
|
setCellValue(milestone.endDate?.format(DATE_FORMATTER) ?: "N/A") |
|
|
setCellValue(milestone.endDate?.format(DATE_FORMATTER) ?: "N/A") |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
createCell(9).apply { |
|
|
|
|
|
|
|
|
createCell(10).apply { |
|
|
cellStyle.dataFormat = workbook.createDataFormat().getFormat("0.00%") |
|
|
cellStyle.dataFormat = workbook.createDataFormat().getFormat("0.00%") |
|
|
|
|
|
|
|
|
// if (groupedTimesheets.containsKey(Pair(project.id, milestone.id))) { |
|
|
// if (groupedTimesheets.containsKey(Pair(project.id, milestone.id))) { |
|
|