|
|
@@ -2766,147 +2766,184 @@ open class ReportService( |
|
|
|
setCellValue(convertReportMonth) |
|
|
|
} |
|
|
|
|
|
|
|
if (timesheets.isNotEmpty()) { |
|
|
|
val combinedTeamCodeColNumber = grades.size |
|
|
|
val sortedGrades = grades.sortedBy { it.id } |
|
|
|
val sortedTeams = teams.sortedBy { it.id } |
|
|
|
|
|
|
|
val groupedTimesheets = timesheets |
|
|
|
.filter { it.project?.teamLead?.team?.id != it.staff?.team?.id } |
|
|
|
.groupBy { timesheetEntry -> |
|
|
|
Triple( |
|
|
|
timesheetEntry.project?.teamLead?.team?.id, |
|
|
|
timesheetEntry.staff?.team?.id, |
|
|
|
timesheetEntry.staff?.grade?.id |
|
|
|
) |
|
|
|
} |
|
|
|
.mapValues { (_, timesheetEntries) -> |
|
|
|
timesheetEntries.map { timesheet -> |
|
|
|
if (timesheet.normalConsumed != null) { |
|
|
|
timesheet.normalConsumed!!.plus(timesheet.otConsumed ?: 0.0) |
|
|
|
} else if (timesheet.otConsumed != null) { |
|
|
|
timesheet.otConsumed!!.plus(timesheet.normalConsumed ?: 0.0) |
|
|
|
} else { |
|
|
|
0.0 |
|
|
|
// if (timesheets.isNotEmpty()) { |
|
|
|
val combinedTeamCodeColNumber = grades.size |
|
|
|
val sortedGrades = grades.sortedBy { it.id } |
|
|
|
val sortedTeams = teams.sortedBy { it.id } |
|
|
|
|
|
|
|
val groupedTimesheets = timesheets |
|
|
|
.filter { it.project?.teamLead?.team?.id != it.staff?.team?.id } |
|
|
|
.groupBy { timesheetEntry -> |
|
|
|
Triple( |
|
|
|
timesheetEntry.project?.teamLead?.team?.id, |
|
|
|
timesheetEntry.staff?.team?.id, |
|
|
|
timesheetEntry.staff?.grade?.id |
|
|
|
) |
|
|
|
} |
|
|
|
.mapValues { (_, timesheetEntries) -> |
|
|
|
timesheetEntries.map { timesheet -> |
|
|
|
if (timesheet.normalConsumed != null) { |
|
|
|
mutableMapOf<String, Double>().apply { |
|
|
|
this["manHour"] = timesheet.normalConsumed!!.plus(timesheet.otConsumed ?: 0.0) |
|
|
|
this["salary"] = timesheet.normalConsumed!!.plus(timesheet.otConsumed ?: 0.0) |
|
|
|
.times(timesheet.staff!!.salary.hourlyRate.toDouble()) |
|
|
|
} |
|
|
|
} else if (timesheet.otConsumed != null) { |
|
|
|
mutableMapOf<String, Double>().apply { |
|
|
|
this["manHour"] = timesheet.otConsumed!!.plus(timesheet.normalConsumed ?: 0.0) |
|
|
|
this["salary"] = timesheet.otConsumed!!.plus(timesheet.normalConsumed ?: 0.0) |
|
|
|
.times(timesheet.staff!!.salary.hourlyRate.toDouble()) |
|
|
|
} |
|
|
|
} else { |
|
|
|
mutableMapOf<String, Double>().apply { |
|
|
|
this["manHour"] = 0.0 |
|
|
|
this["salary"] = 0.0 |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (sortedTeams.isNotEmpty() && sortedTeams.size > 1) { |
|
|
|
rowIndex = 3 |
|
|
|
sortedTeams.forEach { team: Team -> |
|
|
|
if (sortedTeams.isNotEmpty() && sortedTeams.size > 1) { |
|
|
|
rowIndex = 3 |
|
|
|
sortedTeams.forEach { team: Team -> |
|
|
|
|
|
|
|
// Team |
|
|
|
sheet.createRow(rowIndex++).apply { |
|
|
|
createCell(0).apply { |
|
|
|
setCellValue("Team to be charged:") |
|
|
|
cellStyle = boldFontWithBorderStyle.apply { |
|
|
|
alignment = HorizontalAlignment.LEFT |
|
|
|
} |
|
|
|
} |
|
|
|
// Team |
|
|
|
sheet.createRow(rowIndex++).apply { |
|
|
|
createCell(0).apply { |
|
|
|
setCellValue("Team to be charged:") |
|
|
|
cellStyle = boldFontWithBorderStyle |
|
|
|
CellUtil.setAlignment(this, HorizontalAlignment.LEFT) |
|
|
|
} |
|
|
|
|
|
|
|
val rangeAddress = CellRangeAddress(this.rowNum, this.rowNum, 1, 1 + combinedTeamCodeColNumber) |
|
|
|
sheet.addMergedRegion(rangeAddress) |
|
|
|
RegionUtil.setBorderTop(BorderStyle.THIN, rangeAddress, sheet) |
|
|
|
RegionUtil.setBorderLeft(BorderStyle.THIN, rangeAddress, sheet) |
|
|
|
RegionUtil.setBorderRight(BorderStyle.THIN, rangeAddress, sheet) |
|
|
|
RegionUtil.setBorderBottom(BorderStyle.THIN, rangeAddress, sheet) |
|
|
|
val rangeAddress = CellRangeAddress(this.rowNum, this.rowNum, 1, 2 + combinedTeamCodeColNumber) |
|
|
|
sheet.addMergedRegion(rangeAddress) |
|
|
|
RegionUtil.setBorderTop(BorderStyle.THIN, rangeAddress, sheet) |
|
|
|
RegionUtil.setBorderLeft(BorderStyle.THIN, rangeAddress, sheet) |
|
|
|
RegionUtil.setBorderRight(BorderStyle.THIN, rangeAddress, sheet) |
|
|
|
RegionUtil.setBorderBottom(BorderStyle.THIN, rangeAddress, sheet) |
|
|
|
|
|
|
|
createCell(1).apply { |
|
|
|
setCellValue(team.code) |
|
|
|
cellStyle = normalFontWithBorderStyle.apply { |
|
|
|
alignment = HorizontalAlignment.CENTER |
|
|
|
} |
|
|
|
} |
|
|
|
createCell(1).apply { |
|
|
|
setCellValue(team.code) |
|
|
|
cellStyle = normalFontWithBorderStyle |
|
|
|
CellUtil.setAlignment(this, HorizontalAlignment.CENTER) |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// Grades |
|
|
|
sheet.createRow(rowIndex++).apply { |
|
|
|
columnIndex = 0 |
|
|
|
createCell(columnIndex++).apply { |
|
|
|
setCellValue("") |
|
|
|
cellStyle = boldFontWithBorderStyle |
|
|
|
} |
|
|
|
|
|
|
|
// Grades |
|
|
|
sheet.createRow(rowIndex++).apply { |
|
|
|
columnIndex = 0 |
|
|
|
|
|
|
|
sortedGrades.forEach { grade: Grade -> |
|
|
|
createCell(columnIndex++).apply { |
|
|
|
setCellValue("") |
|
|
|
setCellValue(grade.name) |
|
|
|
cellStyle = boldFontWithBorderStyle |
|
|
|
CellUtil.setAlignment(this, HorizontalAlignment.CENTER) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
createCell(columnIndex++).apply { |
|
|
|
setCellValue("Total Manhour by Team") |
|
|
|
cellStyle = boldFontWithBorderStyle |
|
|
|
} |
|
|
|
|
|
|
|
sortedGrades.forEach { grade: Grade -> |
|
|
|
createCell(columnIndex).apply { |
|
|
|
setCellValue("Total Cost Adjusted by Salary Point by Team") |
|
|
|
cellStyle = boldFontWithBorderStyle |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Team + Manhour |
|
|
|
val startRow = rowIndex |
|
|
|
var endRow = rowIndex |
|
|
|
sortedTeams.forEach { chargedTeam: Team -> |
|
|
|
if (team.id != chargedTeam.id) { |
|
|
|
endRow++ |
|
|
|
sheet.createRow(rowIndex++).apply { |
|
|
|
columnIndex = 0 |
|
|
|
createCell(columnIndex++).apply { |
|
|
|
setCellValue(grade.name) |
|
|
|
cellStyle = boldFontWithBorderStyle.apply { |
|
|
|
alignment = HorizontalAlignment.CENTER |
|
|
|
} |
|
|
|
setCellValue(chargedTeam.code) |
|
|
|
cellStyle = normalFontWithBorderStyle |
|
|
|
CellUtil.setAlignment(this, HorizontalAlignment.CENTER) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
createCell(columnIndex).apply { |
|
|
|
setCellValue("Total Manhour by Team") |
|
|
|
cellStyle = boldFontWithBorderStyle |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Team + Manhour |
|
|
|
val startRow = rowIndex |
|
|
|
var endRow = rowIndex |
|
|
|
sortedTeams.forEach { chargedTeam: Team -> |
|
|
|
if (team.id != chargedTeam.id) { |
|
|
|
endRow++ |
|
|
|
sheet.createRow(rowIndex++).apply { |
|
|
|
columnIndex = 0 |
|
|
|
var totalSalary = 0.0 |
|
|
|
sortedGrades.forEach { grade: Grade -> |
|
|
|
createCell(columnIndex++).apply { |
|
|
|
setCellValue(chargedTeam.code) |
|
|
|
cellStyle = normalFontWithBorderStyle |
|
|
|
setCellValue( |
|
|
|
groupedTimesheets[Triple( |
|
|
|
team.id, |
|
|
|
chargedTeam.id, |
|
|
|
grade.id |
|
|
|
)]?.sumOf { it.getValue("manHour") } ?: 0.0) |
|
|
|
|
|
|
|
totalSalary += groupedTimesheets[Triple( |
|
|
|
team.id, |
|
|
|
chargedTeam.id, |
|
|
|
grade.id |
|
|
|
)]?.sumOf { it.getValue("salary") } ?: 0.0 |
|
|
|
|
|
|
|
cellStyle = normalFontWithBorderStyle.apply { |
|
|
|
dataFormat = accountingStyle |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
sortedGrades.forEach { grade: Grade -> |
|
|
|
createCell(columnIndex++).apply { |
|
|
|
setCellValue( |
|
|
|
groupedTimesheets[Triple(team.id, chargedTeam.id, grade.id)]?.sum() ?: 0.0 |
|
|
|
) |
|
|
|
cellStyle = normalFontWithBorderStyle.apply { |
|
|
|
dataFormat = accountingStyle |
|
|
|
} |
|
|
|
} |
|
|
|
createCell(columnIndex++).apply { |
|
|
|
val lastCellLetter = CellReference.convertNumToColString(this.columnIndex - 1) |
|
|
|
cellFormula = "sum(B${this.rowIndex + 1}:${lastCellLetter}${this.rowIndex + 1})" |
|
|
|
cellStyle = boldFontWithBorderStyle.apply { |
|
|
|
dataFormat = accountingStyle |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
createCell(columnIndex).apply { |
|
|
|
val lastCellLetter = CellReference.convertNumToColString(this.columnIndex - 1) |
|
|
|
cellFormula = "sum(B${this.rowIndex + 1}:${lastCellLetter}${this.rowIndex + 1})" |
|
|
|
cellStyle = boldFontWithBorderStyle.apply { |
|
|
|
dataFormat = accountingStyle |
|
|
|
} |
|
|
|
createCell(columnIndex).apply { |
|
|
|
setCellValue(totalSalary) |
|
|
|
cellStyle = boldFontWithBorderStyle.apply { |
|
|
|
dataFormat = accountingStyle |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Total Manhour by grade |
|
|
|
sheet.createRow(rowIndex).apply { |
|
|
|
columnIndex = 0 |
|
|
|
createCell(columnIndex++).apply { |
|
|
|
setCellValue("Total Manhour by Grade") |
|
|
|
cellStyle = boldFontWithBorderStyle |
|
|
|
} |
|
|
|
// Total Manhour by grade |
|
|
|
sheet.createRow(rowIndex).apply { |
|
|
|
columnIndex = 0 |
|
|
|
createCell(columnIndex++).apply { |
|
|
|
setCellValue("Total Manhour by Grade") |
|
|
|
cellStyle = boldFontWithBorderStyle |
|
|
|
} |
|
|
|
|
|
|
|
sortedGrades.forEach { grade: Grade -> |
|
|
|
createCell(columnIndex++).apply { |
|
|
|
val currentCellLetter = CellReference.convertNumToColString(this.columnIndex) |
|
|
|
cellFormula = "sum(${currentCellLetter}${startRow}:${currentCellLetter}${endRow})" |
|
|
|
cellStyle = normalFontWithBorderStyle.apply { |
|
|
|
dataFormat = accountingStyle |
|
|
|
} |
|
|
|
sortedGrades.forEach { grade: Grade -> |
|
|
|
createCell(columnIndex++).apply { |
|
|
|
val currentCellLetter = CellReference.convertNumToColString(this.columnIndex) |
|
|
|
cellFormula = "sum(${currentCellLetter}${startRow}:${currentCellLetter}${endRow})" |
|
|
|
cellStyle = normalFontWithBorderStyle.apply { |
|
|
|
dataFormat = accountingStyle |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
createCell(columnIndex).apply { |
|
|
|
setCellValue("") |
|
|
|
cellStyle = boldFontWithBorderStyle |
|
|
|
} |
|
|
|
createCell(columnIndex++).apply { |
|
|
|
setCellValue("") |
|
|
|
cellStyle = boldFontWithBorderStyle |
|
|
|
} |
|
|
|
|
|
|
|
createCell(columnIndex).apply { |
|
|
|
setCellValue("") |
|
|
|
cellStyle = boldFontWithBorderStyle |
|
|
|
} |
|
|
|
rowIndex += 2 |
|
|
|
} |
|
|
|
rowIndex += 2 |
|
|
|
} |
|
|
|
} |
|
|
|
// } |
|
|
|
|
|
|
|
return workbook |
|
|
|
} |