| @@ -35,11 +35,16 @@ import java.math.RoundingMode | |||
| import java.time.Year | |||
| import javax.swing.plaf.synth.Region | |||
| import kotlin.collections.ArrayList | |||
| import kotlin.collections.HashMap | |||
| data class DayInfo(val date: String?, val weekday: String?) | |||
| data class TsData(var manhour: Double, var cost: Double) | |||
| data class InOut(var In: TsData, var Out: TsData) | |||
| data class CrossTeamP4InOut( | |||
| // String = "${staffCode} ${staffName} (${teamCode})" | |||
| var In: MutableMap<String, MutableMap<String, TsData>>, | |||
| ) | |||
| @Service | |||
| open class ReportService( | |||
| @@ -71,7 +76,14 @@ open class ReportService( | |||
| private fun cellBorderArgs(top: Int, bottom: Int, left: Int, right: Int): MutableMap<String, Any> { | |||
| var cellBorderArgs = mutableMapOf<String, Any>() | |||
| when (top) { | |||
| // val thicknessMap = mapOf( | |||
| // 1 to BorderStyle.THIN, | |||
| // 2 to BorderStyle.THICK, | |||
| // ) | |||
| // if (top > 0) { | |||
| // cellBorderArgs.put(CellUtil.BORDER_TOP, thicknessMap[top]) | |||
| // } | |||
| when (top ) { | |||
| 1 -> cellBorderArgs.put(CellUtil.BORDER_TOP, BorderStyle.THIN) | |||
| 2 -> cellBorderArgs.put(CellUtil.BORDER_TOP, BorderStyle.THICK) | |||
| } | |||
| @@ -90,22 +102,30 @@ open class ReportService( | |||
| return cellBorderArgs | |||
| } | |||
| private fun setRegionBorders(top: Int, bottom: Int, left: Int, right: Int, region: CellRangeAddress, sheet: Sheet) { | |||
| when (top) { | |||
| 1 -> RegionUtil.setBorderTop(BorderStyle.THIN, region, sheet) | |||
| 2 -> RegionUtil.setBorderTop(BorderStyle.THICK, region, sheet) | |||
| } | |||
| when (bottom) { | |||
| 1 -> RegionUtil.setBorderBottom(BorderStyle.THIN, region, sheet) | |||
| 2 -> RegionUtil.setBorderBottom(BorderStyle.THICK, region, sheet) | |||
| } | |||
| when (left) { | |||
| 1 -> RegionUtil.setBorderLeft(BorderStyle.THIN, region, sheet) | |||
| 2 -> RegionUtil.setBorderLeft(BorderStyle.THICK, region, sheet) | |||
| } | |||
| when (right) { | |||
| 1 -> RegionUtil.setBorderRight(BorderStyle.THIN, region, sheet) | |||
| 2 -> RegionUtil.setBorderRight(BorderStyle.THICK, region, sheet) | |||
| } | |||
| val thicknessMap = mapOf( | |||
| 1 to BorderStyle.THIN, | |||
| 2 to BorderStyle.THICK, | |||
| ) | |||
| RegionUtil.setBorderTop(thicknessMap[top], region, sheet) | |||
| RegionUtil.setBorderBottom(thicknessMap[bottom], region, sheet) | |||
| RegionUtil.setBorderLeft(thicknessMap[left], region, sheet) | |||
| RegionUtil.setBorderRight(thicknessMap[right], region, sheet) | |||
| // when (top) { | |||
| // 1 -> RegionUtil.setBorderTop(thicknessMap[1], region, sheet) | |||
| // 2 -> RegionUtil.setBorderTop(BorderStyle.THICK, region, sheet) | |||
| // } | |||
| // when (bottom) { | |||
| // 1 -> RegionUtil.setBorderBottom(BorderStyle.THIN, region, sheet) | |||
| // 2 -> RegionUtil.setBorderBottom(BorderStyle.THICK, region, sheet) | |||
| // } | |||
| // when (left) { | |||
| // 1 -> RegionUtil.setBorderLeft(BorderStyle.THIN, region, sheet) | |||
| // 2 -> RegionUtil.setBorderLeft(BorderStyle.THICK, region, sheet) | |||
| // } | |||
| // when (right) { | |||
| // 1 -> RegionUtil.setBorderRight(BorderStyle.THIN, region, sheet) | |||
| // 2 -> RegionUtil.setBorderRight(BorderStyle.THICK, region, sheet) | |||
| // } | |||
| } | |||
| private val chargeFee = 1.15 | |||
| @@ -3600,9 +3620,9 @@ open class ReportService( | |||
| return jdbcDao.queryForList(sql.toString(), args) | |||
| } | |||
| private fun generateTeamBlock( | |||
| private fun generateTeamsInOutMap( | |||
| teams: List<Team>, | |||
| sortedTeams: MutableList<Team>, | |||
| desiredTeam: MutableList<Team>, | |||
| grades: List<Grade>, | |||
| timesheets: List<Timesheet>, | |||
| gradeLog: List<GradeLog>, | |||
| @@ -3632,63 +3652,60 @@ open class ReportService( | |||
| }.toMutableMap() | |||
| } | |||
| } | |||
| println("teamsMap") | |||
| println(gradeMap) | |||
| // teamsMap["TW"]!!["1"]!!.In.manhour += 1000 | |||
| println(teamsMap) | |||
| sortedTeams.forEach { team -> | |||
| val currentTeam = team.code | |||
| val _timesheets = timesheets.filter { ts -> | |||
| // for after team log is implemented | |||
| // val thisStaffTeam = teamlog.filter { | |||
| // it.from.isBefore(ts.recordDate) | |||
| // && it.to != null | |||
| // && it.staff.id == ts.staff!!.id | |||
| // }.maxByOrNull { it.from } | |||
| // val thisProjectTeam = teamlog.filter { | |||
| // it.from.isBefore(ts.recordDate) | |||
| // && it.to != null | |||
| // && it.staff.id == ts.project!!.teamLead!!.team.id | |||
| // }.maxByOrNull { it.from } | |||
| var _timesheets: List<Timesheet> | |||
| // if have target team, desiredTeams should only be that team | |||
| if (desiredTeam.size == 1) { | |||
| val team = desiredTeam[0] | |||
| val targetTeam = team.code | |||
| _timesheets = timesheets.filter { ts -> | |||
| val staffTeam = ts.staff!!.team.code | |||
| val projectTeam = ts.project!!.teamLead!!.team.code | |||
| (staffTeam == currentTeam && projectTeam != staffTeam) | |||
| || (projectTeam == currentTeam && projectTeam != staffTeam) // check isCrossTeam | |||
| // ts.project!!.teamLead!!.team.id != thisStaffTeam!!.team.id // for team log | |||
| projectTeam != staffTeam && | |||
| (staffTeam == targetTeam || projectTeam == targetTeam ) | |||
| } | |||
| _timesheets.forEach {ts -> | |||
| // this team charging others | |||
| // get the grade and salary data of the record | |||
| val _grade = gradeLog.find { it.staff.id == ts.staff!!.id } | |||
| val gradeCode = _grade!!.grade.code | |||
| val otMultiplier = 1.15 | |||
| val thisSE = salaryEffective.filter { | |||
| it.staff.id == ts.staff!!.id | |||
| && | |||
| it.date.isBefore(ts.recordDate) | |||
| }.maxByOrNull { it.date } | |||
| val normalHour = ts.normalConsumed ?: 0.0 | |||
| val otHour = ts.otConsumed ?: 0.0 | |||
| val normalCost = normalHour.times(thisSE!!.salary.hourlyRate.toDouble()) | |||
| val otCost = otHour.times(thisSE.salary.hourlyRate.toDouble()).times(otMultiplier) | |||
| //assigning data | |||
| val projectTeam = ts.project!!.teamLead!!.team.code | |||
| } else { | |||
| _timesheets = timesheets.filter { ts -> | |||
| val staffTeam = ts.staff!!.team.code | |||
| // write in | |||
| println("putting in") | |||
| var tsInData = teamsMap[projectTeam]!![gradeCode]!!.In | |||
| println(tsInData) | |||
| tsInData.manhour += normalHour + otHour | |||
| tsInData.cost += normalCost + otCost | |||
| // write out | |||
| println("putting out") | |||
| val tsOutData = teamsMap[staffTeam]!!.get(gradeCode)!!.Out | |||
| tsOutData.manhour += normalHour + otHour | |||
| tsOutData.cost += normalCost + otCost | |||
| val projectTeam = ts.project!!.teamLead!!.team.code | |||
| projectTeam != staffTeam | |||
| } | |||
| } | |||
| println("all team - gradeMap") | |||
| println(teamsMap) | |||
| _timesheets.forEach {ts -> | |||
| // this team charging others | |||
| // get the grade and salary data of the record | |||
| val _grade = gradeLog.find { | |||
| it.staff.id == ts.staff!!.id | |||
| && | |||
| it.from.isBefore(ts.recordDate) && (it.to == null || it.to.isAfter(ts.recordDate)) | |||
| && | |||
| it.deleted == false | |||
| } | |||
| val gradeCode = _grade!!.grade.code | |||
| val otMultiplier = 1.15 | |||
| val thisSE = salaryEffective.find { | |||
| it.staff.id == ts.staff!!.id | |||
| && | |||
| it.startDate.isBefore(ts.recordDate) && (it.endDate.isAfter(ts.recordDate) || it.endDate == null) | |||
| } | |||
| val normalHour = ts.normalConsumed ?: 0.0 | |||
| val otHour = ts.otConsumed ?: 0.0 | |||
| val normalCost = normalHour.times(thisSE!!.salary.hourlyRate.toDouble()) | |||
| val otCost = otHour.times(thisSE.salary.hourlyRate.toDouble()).times(otMultiplier) | |||
| //assigning data | |||
| val projectTeam = ts.project!!.teamLead!!.team.code | |||
| val staffTeam = ts.staff!!.team.code | |||
| // write in | |||
| //println("putting in") | |||
| var tsInData = teamsMap[projectTeam]!![gradeCode]!!.In | |||
| tsInData.manhour += normalHour + otHour | |||
| tsInData.cost += normalCost + otCost | |||
| // write out | |||
| //println("putting out") | |||
| val tsOutData = teamsMap[staffTeam]!!.get(gradeCode)!!.Out | |||
| tsOutData.manhour += normalHour + otHour | |||
| tsOutData.cost += normalCost + otCost | |||
| } | |||
| return teamsMap | |||
| } | |||
| @@ -3697,6 +3714,23 @@ open class ReportService( | |||
| CellUtil.setVerticalAlignment(tempCell, VerticalAlignment.TOP) | |||
| CellUtil.setAlignment(tempCell, HorizontalAlignment.CENTER) | |||
| } | |||
| private fun setAlignment(cell: Cell, verticalAlignment: String, horizontalAlignment: String) { | |||
| val verticalAlignmentMap = mapOf( | |||
| "top" to VerticalAlignment.TOP, | |||
| "center" to VerticalAlignment.CENTER, | |||
| "bottom" to VerticalAlignment.BOTTOM, | |||
| ) | |||
| val horizontalAlignmentMap = mapOf( | |||
| "left" to HorizontalAlignment.LEFT, | |||
| "center" to HorizontalAlignment.CENTER, | |||
| "right" to HorizontalAlignment.RIGHT, | |||
| "fill" to HorizontalAlignment.FILL, | |||
| "justify" to HorizontalAlignment.JUSTIFY, | |||
| ) | |||
| CellUtil.setVerticalAlignment(cell, verticalAlignmentMap[verticalAlignment]) | |||
| CellUtil.setAlignment(cell, horizontalAlignmentMap[horizontalAlignment]) | |||
| } | |||
| private fun createCrossTeamForm( | |||
| workbook: Workbook, | |||
| sheet: Sheet, | |||
| @@ -3914,15 +3948,15 @@ open class ReportService( | |||
| sheet.getRow(rowIndex).getCell(columnIndex).apply { | |||
| setCellValue(convertReportMonth) | |||
| } | |||
| var sortedTeams = teams.toMutableList() | |||
| var desiredTeam = teams.toMutableList() | |||
| if (teamId.lowercase() != "all") { | |||
| // sortedTeams = teams.sortedWith(compareBy { if (it.id == teamId.toLong()) 0 else 1 }).toMutableList() | |||
| sortedTeams = mutableListOf(teams.find { teamId.toLong() == it.id }!!) | |||
| // desiredTeam = teams.sortedWith(compareBy { if (it.id == teamId.toLong()) 0 else 1 }).toMutableList() | |||
| desiredTeam = mutableListOf(teams.find { teamId.toLong() == it.id }!!) | |||
| } | |||
| //// generate info map ///// | |||
| val teamsInOutMap: MutableMap<String, MutableMap<String, InOut>> = generateTeamBlock( | |||
| val teamsInOutMap: MutableMap<String, MutableMap<String, InOut>> = generateTeamsInOutMap( | |||
| teams, | |||
| sortedTeams, | |||
| desiredTeam, | |||
| grades, | |||
| timesheets, | |||
| gradeLog, | |||
| @@ -3942,6 +3976,306 @@ open class ReportService( | |||
| sheet.setColumnWidth(i, 20 * 256) | |||
| } | |||
| } | |||
| private fun createCrossTeamForm4TH( | |||
| workbook: Workbook, | |||
| sheet: Sheet, | |||
| teamsMap: MutableMap<String, CrossTeamP4InOut> | |||
| ) { | |||
| var rowIndex = 2 | |||
| var columnIndex = 0 | |||
| var tempRow: Row | |||
| var tempCell: Cell | |||
| val accountingStyle = workbook.createDataFormat().getFormat("_(* #,##0.00_);_(* (#,##0.00);_(* \"-\"??_);_(@_)") | |||
| fun dataFormatArgs(accountingStyle: Short): MutableMap<String, Any> { | |||
| val dataFormatArgs = mutableMapOf<String, Any>( | |||
| CellUtil.DATA_FORMAT to accountingStyle | |||
| ) | |||
| return dataFormatArgs | |||
| } | |||
| fun fontArgs(fontName: String, isBold: Boolean, isWrap: Boolean): MutableMap<String, Any>{ | |||
| val font = sheet.workbook.createFont() | |||
| font.bold = isBold | |||
| font.fontName = fontName | |||
| val fontArgs = mutableMapOf<String, Any>( | |||
| CellUtil.FONT to font.index, | |||
| CellUtil.WRAP_TEXT to isWrap, | |||
| ) | |||
| return fontArgs | |||
| } | |||
| for ((teamCode, crossTeamP4InOut) in teamsMap) { | |||
| columnIndex = 0 | |||
| rowIndex++ | |||
| tempRow = getOrCreateRow(sheet, rowIndex) | |||
| tempCell = getOrCreateCell(tempRow, columnIndex) | |||
| tempCell.setCellValue("Team") | |||
| alignTopCenter(tempCell) | |||
| CellUtil.setCellStyleProperties( | |||
| tempCell, | |||
| fontArgs("Times New Roman", true, true) | |||
| + cellBorderArgs(2,2,1,1) | |||
| ) | |||
| columnIndex = 1 | |||
| tempCell = getOrCreateCell(tempRow, columnIndex) | |||
| tempCell.setCellValue("Cross Team Staffs") | |||
| alignTopCenter(tempCell) | |||
| CellUtil.setCellStyleProperties(tempCell, | |||
| fontArgs("Times New Roman", true, true) | |||
| + cellBorderArgs(2,2,1,1) | |||
| ) | |||
| ////// getting unique header list with columnIndex /////// | |||
| var projectList = mutableListOf<String>() | |||
| for ((_, projectTsDataMap) in crossTeamP4InOut.In) { | |||
| for(key in projectTsDataMap.keys) { | |||
| if (key !in projectList) { | |||
| projectList.add(key) | |||
| } | |||
| } | |||
| } | |||
| tempRow = getOrCreateRow(sheet, rowIndex) | |||
| columnIndex = 2 | |||
| projectList.forEach{ str -> | |||
| tempCell = getOrCreateCell(tempRow, columnIndex) | |||
| tempCell.setCellValue(str) | |||
| CellUtil.setCellStyleProperties(tempCell, fontArgs("Times New Roman", true, true)) | |||
| alignTopCenter(tempCell) | |||
| val titleRegion = CellRangeAddress(rowIndex, rowIndex,columnIndex,columnIndex+1) | |||
| sheet.addMergedRegion(titleRegion) | |||
| setRegionBorders(2,2,1,1,titleRegion, sheet) | |||
| columnIndex += 2 | |||
| } | |||
| tempCell = getOrCreateCell(tempRow, columnIndex) | |||
| tempCell.setCellValue("Total By Staff") | |||
| CellUtil.setCellStyleProperties(tempCell, fontArgs("Times New Roman", true, true)) | |||
| alignTopCenter(tempCell) | |||
| val titleRegion = CellRangeAddress(rowIndex, rowIndex,columnIndex,columnIndex+1) | |||
| sheet.addMergedRegion(titleRegion) | |||
| setRegionBorders(2,2,2,2,titleRegion, sheet) | |||
| alignTopCenter(tempCell) | |||
| /////////////////////////////////////////////////////////////////////////////////// | |||
| // total column = columnIndex + list.size | |||
| rowIndex++ | |||
| columnIndex = 0 | |||
| tempRow = getOrCreateRow(sheet, rowIndex) | |||
| tempCell = getOrCreateCell(tempRow, columnIndex) | |||
| tempCell.setCellValue(teamCode) // team column | |||
| CellUtil.setCellStyleProperties(tempCell, | |||
| fontArgs("Times New Roman", false, false) | |||
| ) | |||
| setAlignment(tempCell, "top", "center") | |||
| var startingRow = rowIndex | |||
| for ((staff, projectTsDataMap) in crossTeamP4InOut.In) { | |||
| columnIndex = 1 | |||
| tempRow = getOrCreateRow(sheet, rowIndex) | |||
| tempCell = getOrCreateCell(tempRow, columnIndex) | |||
| tempCell.setCellValue(staff) // team column | |||
| setAlignment(tempCell, "top", "center") | |||
| CellUtil.setCellStyleProperties(tempCell, | |||
| cellBorderArgs(1,1,1,1) | |||
| + fontArgs("Times New Roman", false, false) | |||
| ) | |||
| var pidx = 0 | |||
| var manhourFormula = mutableListOf<String>() | |||
| var costFormula = mutableListOf<String>() | |||
| while (pidx < projectList.size) { | |||
| var manhour = 0.0 | |||
| var cost = 0.0 | |||
| if (projectTsDataMap.containsKey(projectList[pidx])) { | |||
| manhour = projectTsDataMap[projectList[pidx]]?.manhour ?: 0.0 | |||
| cost = projectTsDataMap[projectList[pidx]]?.cost ?: 0.0 | |||
| } | |||
| columnIndex++ | |||
| val manhourLetter = CellReference.convertNumToColString(columnIndex) | |||
| tempCell = getOrCreateCell(tempRow, columnIndex) | |||
| tempCell.setCellValue(manhour) | |||
| CellUtil.setCellStyleProperties(tempCell, | |||
| cellBorderArgs(1,1,1,1) | |||
| + fontArgs("Times New Roman", false, false) | |||
| + dataFormatArgs(accountingStyle) | |||
| ) | |||
| manhourFormula.add("${manhourLetter}${rowIndex+1}") | |||
| columnIndex++ | |||
| val costLetter = CellReference.convertNumToColString(columnIndex) | |||
| tempCell = getOrCreateCell(tempRow, columnIndex) | |||
| tempCell.setCellValue(cost) | |||
| CellUtil.setCellStyleProperties(tempCell, | |||
| cellBorderArgs(1,1,1,1) | |||
| + fontArgs("Times New Roman", false, false) | |||
| + dataFormatArgs(accountingStyle) | |||
| ) | |||
| costFormula.add("${costLetter}${rowIndex+1}") | |||
| pidx++ | |||
| } | |||
| // total by staff | |||
| columnIndex++ | |||
| tempCell = getOrCreateCell(tempRow, columnIndex) | |||
| CellUtil.setCellStyleProperties(tempCell, | |||
| cellBorderArgs(1,1,2,1) | |||
| + fontArgs("Times New Roman", false, false) | |||
| + dataFormatArgs(accountingStyle) | |||
| ) | |||
| tempCell.cellFormula = manhourFormula.joinToString(separator = "+") | |||
| columnIndex++ | |||
| tempCell = getOrCreateCell(tempRow, columnIndex) | |||
| CellUtil.setCellStyleProperties(tempCell, | |||
| cellBorderArgs(1,1,1,1) | |||
| + fontArgs("Times New Roman", false, false) | |||
| + dataFormatArgs(accountingStyle) | |||
| ) | |||
| tempCell.cellFormula = costFormula.joinToString(separator = "+") | |||
| rowIndex++ | |||
| } | |||
| columnIndex = 0 | |||
| val teamCodeRegion = CellRangeAddress(startingRow, rowIndex, columnIndex, columnIndex) | |||
| sheet.addMergedRegion(teamCodeRegion) | |||
| setRegionBorders(2,2,1,1, teamCodeRegion, sheet) | |||
| columnIndex = 1 | |||
| tempRow = getOrCreateRow(sheet, rowIndex) | |||
| tempCell = getOrCreateCell(tempRow, columnIndex) | |||
| tempCell.setCellValue("Total by Project:") | |||
| setAlignment(tempCell, "top", "center") | |||
| CellUtil.setCellStyleProperties(tempCell, | |||
| cellBorderArgs(1,2,1,1) | |||
| + fontArgs("Times New Roman", true, false) | |||
| ) | |||
| // (project title + total by staff) * 2 | |||
| columnIndex = 2 | |||
| val numberOfColumns = (projectList.size + 1) * 2 | |||
| var i = 0 | |||
| while (i < numberOfColumns) { | |||
| var leftBorder = 1 | |||
| if (i == numberOfColumns - 2) { | |||
| leftBorder = 2 | |||
| } | |||
| tempCell = getOrCreateCell(tempRow, columnIndex) | |||
| val columnLetter = CellReference.convertNumToColString(columnIndex) | |||
| tempCell.cellFormula = "SUM(${columnLetter}${startingRow+1}:${columnLetter}${rowIndex})" | |||
| CellUtil.setCellStyleProperties(tempCell, | |||
| cellBorderArgs(1,2,leftBorder,1) | |||
| + fontArgs("Times New Roman", false, false) | |||
| + dataFormatArgs(accountingStyle) | |||
| ) | |||
| columnIndex++ | |||
| i++ | |||
| } | |||
| rowIndex++ | |||
| } | |||
| } | |||
| private fun generatePageFourTeamsInOutMap( | |||
| teams: List<Team>, | |||
| desiredTeams: MutableList<Team>, | |||
| grades: List<Grade>, | |||
| timesheets: List<Timesheet>, | |||
| gradeLog: List<GradeLog>, | |||
| salaryEffective: List<SalaryEffective>, | |||
| ): MutableMap<String, CrossTeamP4InOut> { | |||
| var teamsMap: MutableMap<String, CrossTeamP4InOut> = mutableMapOf() | |||
| // teams.forEach { team -> | |||
| // val key = team.code | |||
| // if (key !in teamsMap) { | |||
| // teamsMap[key] = CrossTeamP4InOut( | |||
| // In = mutableMapOf(), | |||
| // ) | |||
| // } | |||
| // } | |||
| var _timesheets: List<Timesheet> | |||
| // if have target team, desiredTeams should only be that team | |||
| if (desiredTeams.size == 1) { | |||
| val team = desiredTeams[0] | |||
| val targetTeam = team.code | |||
| _timesheets = timesheets.filter { ts -> | |||
| val staffTeam = ts.staff!!.team.code | |||
| val projectTeam = ts.project!!.teamLead!!.team.code | |||
| projectTeam != staffTeam && | |||
| (staffTeam == targetTeam || projectTeam == targetTeam ) | |||
| } | |||
| } else { | |||
| _timesheets = timesheets.filter { ts -> | |||
| val staffTeam = ts.staff!!.team.code | |||
| val projectTeam = ts.project!!.teamLead!!.team.code | |||
| projectTeam != staffTeam | |||
| } | |||
| } | |||
| _timesheets.forEach { ts -> | |||
| val otMultiplier = 1.15 | |||
| val thisSE = salaryEffective.filter { | |||
| it.staff.id == ts.staff!!.id | |||
| && | |||
| it.date.isBefore(ts.recordDate) | |||
| }.maxByOrNull { it.date } | |||
| val normalHour = ts.normalConsumed ?: 0.0 | |||
| val otHour = ts.otConsumed ?: 0.0 | |||
| val normalCost = normalHour.times(thisSE!!.salary.hourlyRate.toDouble()) | |||
| val otCost = otHour.times(thisSE.salary.hourlyRate.toDouble()).times(otMultiplier) | |||
| val staff = ts.staff!! | |||
| val project = ts.project!! | |||
| val projectNameCode = "${project.code}\n${project.name}" | |||
| val projectTeam = project.teamLead!!.team.code | |||
| val inOut_Key = "${staff.staffId} ${staff.name} (${staff.team.code})" | |||
| if (!teamsMap.containsKey(projectTeam)) { | |||
| teamsMap.put(projectTeam, CrossTeamP4InOut( | |||
| In = mutableMapOf(), | |||
| )) | |||
| } | |||
| val tsInData = teamsMap[projectTeam]!!.In | |||
| if (!tsInData.containsKey(inOut_Key)) { | |||
| tsInData.put(inOut_Key, mutableMapOf(projectNameCode to TsData(0.0, 0.0))) | |||
| } | |||
| if (!tsInData[inOut_Key]!!.containsKey(projectNameCode)) { | |||
| tsInData[inOut_Key]!!.put(projectNameCode, TsData(0.0, 0.0)) | |||
| } | |||
| tsInData[inOut_Key]!![projectNameCode]!!.manhour += normalHour + otHour | |||
| tsInData[inOut_Key]!![projectNameCode]!!.cost += normalCost + otCost | |||
| } | |||
| return teamsMap | |||
| } | |||
| private fun createFourthSheetTeamChargeReport( | |||
| month: String, | |||
| workbook: Workbook, | |||
| timesheets: List<Timesheet>, | |||
| teams: List<Team>, | |||
| grades: List<Grade>, | |||
| teamId: String, | |||
| gradeLog: List<GradeLog>, | |||
| salaryEffective: List<SalaryEffective>, | |||
| ) { | |||
| var sheet: Sheet = workbook.getSheetAt(3) | |||
| val rowIndex = 1 // Assuming the location is in (1,2), which is the report date field | |||
| val columnIndex = 2 | |||
| val monthFormat = DateTimeFormatter.ofPattern("MMMM yyyy", Locale.ENGLISH) | |||
| val reportMonth = YearMonth.parse(month, DateTimeFormatter.ofPattern("yyyy-MM")) | |||
| val convertReportMonth = YearMonth.of(reportMonth.year, reportMonth.month).format(monthFormat) | |||
| sheet.getRow(rowIndex).getCell(columnIndex).apply { | |||
| setCellValue(convertReportMonth) | |||
| } | |||
| val _teams = teams | |||
| var desiredTeams = teams.toMutableList() | |||
| if (teamId.lowercase() != "all") { | |||
| desiredTeams = mutableListOf(teams.find { teamId.toLong() == it.id }!!) | |||
| _teams.sortedWith(compareBy { if (it.id == teamId.toLong()) 0 else 1 }) | |||
| } | |||
| val teamsInOutMap: MutableMap<String, CrossTeamP4InOut> = generatePageFourTeamsInOutMap( | |||
| _teams, | |||
| desiredTeams, | |||
| grades, | |||
| timesheets, | |||
| gradeLog, | |||
| salaryEffective, | |||
| ) | |||
| println("4th ------- teamsInOutMap") | |||
| println(teamsInOutMap) | |||
| createCrossTeamForm4TH( | |||
| workbook, | |||
| sheet, | |||
| teamsInOutMap | |||
| ) | |||
| } | |||
| @Throws(IOException::class) | |||
| private fun createCrossTeamChargeReport( | |||
| month: String, | |||
| @@ -4530,6 +4864,17 @@ open class ReportService( | |||
| gradeLog, | |||
| salaryEffective | |||
| ) | |||
| // page 4 | |||
| createFourthSheetTeamChargeReport( | |||
| month, | |||
| workbook, | |||
| timesheets, | |||
| _teams, | |||
| grades, | |||
| teamId, | |||
| gradeLog, | |||
| salaryEffective | |||
| ) | |||
| return workbook | |||
| } | |||
| // Use to Calculate cummunlative expenditure | |||