diff --git a/src/main/java/com/ffii/tsms/modules/data/service/StaffsService.kt b/src/main/java/com/ffii/tsms/modules/data/service/StaffsService.kt index a3a8218..0013733 100644 --- a/src/main/java/com/ffii/tsms/modules/data/service/StaffsService.kt +++ b/src/main/java/com/ffii/tsms/modules/data/service/StaffsService.kt @@ -9,6 +9,7 @@ import com.ffii.tsms.modules.data.entity.projections.StaffSearchInfo import com.ffii.tsms.modules.data.web.models.NewStaffRequest import com.ffii.tsms.modules.data.web.models.NewStaffResponse import com.ffii.tsms.modules.data.web.models.SalaryEffectiveInfo +import com.ffii.tsms.modules.report.web.model.ExportCurrentStaffInfoRequest import com.ffii.tsms.modules.user.entity.User import com.ffii.tsms.modules.user.entity.UserRepository import org.springframework.scheduling.annotation.Scheduled @@ -398,4 +399,31 @@ open class StaffsService( ) return jdbcDao.queryForList(sql.toString(), args) } + + open fun getCurrentStaffInfo(args: List) : List>{ + val sql = StringBuilder( + "select" + + " s.staffId," + + " COALESCE(team.code, '') as team," + + " s.name," + + " coalesce (s.joinDate, '') as employmentDate," + + " g.code as grade," + + " p.description ," + + " s.salaryId," + + " coalesce (s.email , '') as email," + + " s.departDate" + + " from staff s" + + " left join team on team.id = s.teamId" + + " left join grade g on g.id = s.gradeId" + + " left join `position` p on p.id = s.currentPosition" + + " where s.deleted = false " + ) + if (args.isNotEmpty()){ + sql.append(" and s.id in (:ids)") + } + + sql.append(" order by s.staffId") + + return jdbcDao.queryForList(sql.toString(), mapOf("ids" to args)) + } } \ No newline at end of file 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 e3923cd..2f5428f 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 @@ -4,7 +4,9 @@ import com.ffii.core.support.JdbcDao import com.ffii.tsms.modules.data.entity.* import com.ffii.tsms.modules.data.service.SalaryEffectiveService import com.ffii.tsms.modules.data.service.SalaryEffectiveService.MonthlyStaffSalaryData +import com.ffii.tsms.modules.data.service.StaffsService import com.ffii.tsms.modules.project.entity.* +import com.ffii.tsms.modules.report.web.model.ExportCurrentStaffInfoRequest import com.ffii.tsms.modules.report.web.model.costAndExpenseRequest import com.ffii.tsms.modules.timesheet.entity.Timesheet import com.ffii.tsms.modules.timesheet.entity.TimesheetRepository @@ -54,7 +56,8 @@ open class ReportService( private val salaryRepository: SalaryRepository, private val timesheetRepository: TimesheetRepository, private val teamLogRepository: TeamLogRepository, - private val teamRepository: TeamRepository + private val teamRepository: TeamRepository, + private val staffService: StaffsService, ) { private val logger: Log = LogFactory.getLog(javaClass) private val DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy/MM/dd") @@ -76,6 +79,7 @@ open class ReportService( 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 val STAFF_INFORMATION = "templates/report/Staff Information.xlsx" private fun cellBorderArgs(top: Int, bottom: Int, left: Int, right: Int): MutableMap { var cellBorderArgs = mutableMapOf() @@ -5794,4 +5798,110 @@ open class ReportService( return outputStream.toByteArray() } + + @Throws(IOException::class) + private fun createStaffCurrentInfoWorkBook( + staffIds: List, + templatePath: String + ): Workbook{ + val resource = ClassPathResource(templatePath) + val templateInputStream = resource.inputStream + val workbook: Workbook = XSSFWorkbook(templateInputStream) + + val result = staffService.getCurrentStaffInfo(staffIds) + 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) + } + + var startRowIndex = 4 + result.forEach { + val row = + if (sheet.getRow(startRowIndex) == null) sheet.createRow(startRowIndex) else sheet.getRow(startRowIndex) + val staffIdCell = row.createCell(0) + val teamCell = row.createCell(1) + val staffNameCell = row.createCell(2) + val employmentDateCell = row.createCell(3) + val gradeCell = row.createCell(4) + val positionCell = row.createCell(5) + val salaryPointCell = row.createCell(6) + val emailCell = row.createCell(7) + + staffIdCell.apply { + setCellValue(it.getValue("staffId") as String) + cellStyle = blackFontStyle + } + + teamCell.apply { + setCellValue(it.getValue("team") as String) + cellStyle = blackFontStyle + } + + staffNameCell.apply { + setCellValue(it.getValue("name") as String) + cellStyle = blackFontStyle + } + + employmentDateCell.apply { + setCellValue(it.getValue("employmentDate") as String) + cellStyle = blackFontStyle + } + + gradeCell.apply { + val grade = it.getValue("grade") as String + val gradeCode = "GRADE $grade" + setCellValue(gradeCode) + cellStyle = blackFontStyle + } + + positionCell.apply { + setCellValue(it.getValue("description") as String) + cellStyle = blackFontStyle + } + + salaryPointCell.apply{ + setCellValue((it.getValue("salaryId") as Int).toString()) + cellStyle = blackFontStyle + } + + emailCell.apply { + setCellValue(it.getValue("email") as String) + cellStyle = blackFontStyle + } + + startRowIndex++ + } + + return workbook + } + + fun genStaffCurrentInfoFile( + request: ExportCurrentStaffInfoRequest, + ): ByteArray{ + val workbook = createStaffCurrentInfoWorkBook(request.staffIds, STAFF_INFORMATION) + + 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 5221337..d8c62e8 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 @@ -399,6 +399,15 @@ class ReportController( .body(ByteArrayResource(reportResult)) } + @PostMapping("/export-staff-current-info") + fun exportStaffCurrentInfo(@RequestBody @Valid request: ExportCurrentStaffInfoRequest): ResponseEntity{ + val reportResult: ByteArray = excelReportService.genStaffCurrentInfoFile(request) + + return ResponseEntity.ok() + .header("filename", "Staff Information - " + 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 4f20807..a379967 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 @@ -78,4 +78,8 @@ data class ProjectMonthlyRequest ( data class LastRecordReportRequest ( val dateString: String +) + +data class ExportCurrentStaffInfoRequest ( + val staffIds: List ) \ No newline at end of file diff --git a/src/main/resources/templates/report/Staff Information.xlsx b/src/main/resources/templates/report/Staff Information.xlsx new file mode 100644 index 0000000..c60fe27 Binary files /dev/null and b/src/main/resources/templates/report/Staff Information.xlsx differ