diff --git a/src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt b/src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt index 9ffa836..e3923cd 100644 --- a/src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt +++ b/src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt @@ -75,6 +75,7 @@ open class ReportService( private val CROSS_TEAM_CHARGE_REPORT = "templates/report/Cross Team Charge Report.xlsx" private val PROJECT_MANHOUR_SUMMARY = "templates/report/Project Manhour Summary.xlsx" private val PROJECT_MONTHLY_REPORT = "templates/report/AR09_Project Daily Work Hours Analysis Report.xlsx" + private val LAST_RECORD_REPORT = "templates/report/AR10_Staff Last Record Report.xlsx" private fun cellBorderArgs(top: Int, bottom: Int, left: Int, right: Int): MutableMap { var cellBorderArgs = mutableMapOf() @@ -5652,4 +5653,145 @@ open class ReportService( return outputStream.toByteArray() } + + data class StaffLastRecordData( + val staffId: String, + val staffName: String, + val email: String, + val team: String, + val lastRecordDate: String, + ) + private fun getStaffLastRecordDateByDate(date: LocalDate): List{ + val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd") + val sql = StringBuilder( + "with cte_lastRecordDate as ( " + + "select staffId, " + + "max( timesheet.recordDate ) as lastRecordDate " + + "from timesheet " + + "group by staffId " + + ") " + + "select " + + "s.staffId, " + + "s.name, " + + "COALESCE(s.email, '') as email, " + + "t.code as team, " + + "lmd.lastRecordDate " + + "from cte_lastRecordDate lmd " + + "left join staff s on s.id = lmd.staffid " + + "left join team t on s.teamId = t.id " + + "where s.staffId != 'B000' and s.teamId != 7 " + + "and lmd.lastrecorddate <= DATE_SUB(:searchDate, INTERVAL 7 DAY) " + + "order by lmd.lastrecorddate " + ) + + val results = jdbcDao.queryForList(sql.toString(), mapOf("searchDate" to date.format(formatter))).map { + result -> + StaffLastRecordData( + result["staffId"] as String, + result["name"] as String, + result["email"] as String, + result["team"] as String, + (result["lastRecordDate"] as java.sql.Date).toString() + ) + } + + return results + } + + @Throws(IOException::class) + private fun createLastRecordReportWorkbook( + date: LocalDate, + templatePath: String, + ): Workbook{ + val resource = ClassPathResource(templatePath) + val templateInputStream = resource.inputStream + val workbook: Workbook = XSSFWorkbook(templateInputStream) + + val result = getStaffLastRecordDateByDate(date) + println(result) + + var sheet: Sheet = workbook.getSheetAt(0) + var rowIndex = 1 // Assuming the location is in (1,2), which is the report date field + var columnIndex = 1 + + val blackFont = workbook.createFont().apply { + color = IndexedColors.BLACK.index + fontHeightInPoints = 12 + } + + val blackFontStyle = workbook.createCellStyle().apply { + setFont(blackFont) + borderTop = BorderStyle.THIN + borderBottom = BorderStyle.THIN + borderLeft = BorderStyle.THIN + borderRight = BorderStyle.THIN + } + + sheet.getRow(rowIndex).createCell(columnIndex+1).apply { + setCellValue(FORMATTED_TODAY) + } + + rowIndex = 2 + sheet.getRow(rowIndex).getCell(columnIndex+1).apply { + setCellValue(date.format(DATE_FORMATTER)) + } + + rowIndex = 3 + sheet.getRow(rowIndex).getCell(columnIndex+1).apply { + setCellValue( "${result.size}" ) + } + + var startRowIndex = 6 + val startColumnIndex = 1 + + result.forEach { + val row = if(sheet.getRow(startRowIndex) == null) sheet.createRow(startRowIndex) else sheet.getRow(startRowIndex) + val staffIdCell = row.createCell(0) + val staffNameCell = row.createCell(1) + val emailCell = row.createCell(2) + val teamCell = row.createCell(3) + val lastRecordDateCell = row.createCell(4) + + staffIdCell.apply { + setCellValue(it.staffId) + cellStyle =blackFontStyle + } + + staffNameCell.apply { + setCellValue(it.staffName) + cellStyle =blackFontStyle + } + + emailCell.apply { + setCellValue(it.email) + cellStyle =blackFontStyle + } + + teamCell.apply { + setCellValue(it.team) + cellStyle =blackFontStyle + } + + lastRecordDateCell.apply { + setCellValue(it.lastRecordDate) + cellStyle =blackFontStyle + } + + startRowIndex++ + } + + return workbook + } + + fun genLastRecordReport( + date: LocalDate, + ): ByteArray{ + val workbook = createLastRecordReportWorkbook(date, LAST_RECORD_REPORT) + + val outputStream: ByteArrayOutputStream = ByteArrayOutputStream() + workbook.write(outputStream) + workbook.close() + + return outputStream.toByteArray() + } } \ No newline at end of file diff --git a/src/main/java/com/ffii/tsms/modules/report/web/ReportController.kt b/src/main/java/com/ffii/tsms/modules/report/web/ReportController.kt index 6131df8..5221337 100644 --- a/src/main/java/com/ffii/tsms/modules/report/web/ReportController.kt +++ b/src/main/java/com/ffii/tsms/modules/report/web/ReportController.kt @@ -165,7 +165,6 @@ class ReportController( .header("filename", "Monthly Work Hours Analysis Report - " + staff.name + " - " + LocalDate.now() + ".xlsx") .body(ByteArrayResource(reportResult)) } - private val mapper = ObjectMapper().registerModule(KotlinModule()) @PostMapping("/ProjectResourceOverconsumptionReport") @Throws(ServletRequestBindingException::class, IOException::class) @@ -388,6 +387,18 @@ class ReportController( .body(ByteArrayResource(reportResult)) } + @PostMapping("/gen-staff-last-record-report") + fun genLastRecordReport(@RequestBody @Valid request: LastRecordReportRequest): ResponseEntity{ + println("================= ${request.dateString}") + val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd") + val date = LocalDate.parse(request.dateString, formatter) + val reportResult: ByteArray = excelReportService.genLastRecordReport(date) + + return ResponseEntity.ok() + .header("filename", "Staff Last Record Report - " + LocalDate.now() + ".xlsx") + .body(ByteArrayResource(reportResult)) + } + // API for testing data of total cumulative expenditure // @GetMapping("/test") // fun testApi(@RequestParam teamLeadId: Long): Map{ diff --git a/src/main/java/com/ffii/tsms/modules/report/web/model/ReportRequest.kt b/src/main/java/com/ffii/tsms/modules/report/web/model/ReportRequest.kt index 9df7f6b..4f20807 100644 --- a/src/main/java/com/ffii/tsms/modules/report/web/model/ReportRequest.kt +++ b/src/main/java/com/ffii/tsms/modules/report/web/model/ReportRequest.kt @@ -74,4 +74,8 @@ data class ProjectMonthlyRequest ( val projectId: Long, val yearMonth: YearMonth, val holidays: List +) + +data class LastRecordReportRequest ( + val dateString: String ) \ No newline at end of file diff --git a/src/main/resources/templates/report/AR10_Staff Last Record Report.xlsx b/src/main/resources/templates/report/AR10_Staff Last Record Report.xlsx new file mode 100644 index 0000000..37601e1 Binary files /dev/null and b/src/main/resources/templates/report/AR10_Staff Last Record Report.xlsx differ