import and export Salary Templatetags/Baseline_30082024_BACKEND_UAT
| @@ -6,6 +6,8 @@ import jakarta.persistence.Entity; | |||
| import jakarta.persistence.Table; | |||
| import jakarta.validation.constraints.NotNull; | |||
| import java.math.BigDecimal; | |||
| @Entity | |||
| @Table(name = "salary") | |||
| public class Salary extends IdEntity<Long> { | |||
| @@ -25,6 +27,9 @@ public class Salary extends IdEntity<Long> { | |||
| @Column(name = "increment") | |||
| private Integer increment; | |||
| @Column(name = "hourlyRate") | |||
| private BigDecimal hourlyRate; | |||
| public Integer getIncrement() { | |||
| return increment; | |||
| } | |||
| @@ -56,4 +61,12 @@ public class Salary extends IdEntity<Long> { | |||
| public Integer getSalaryPoint() { | |||
| return salaryPoint; | |||
| } | |||
| public BigDecimal getHourlyRate() { | |||
| return hourlyRate; | |||
| } | |||
| public void setHourlyRate(BigDecimal hourlyRate) { | |||
| this.hourlyRate = hourlyRate; | |||
| } | |||
| } | |||
| @@ -1,5 +1,7 @@ | |||
| package com.ffii.tsms.modules.data.entity.projections; | |||
| import java.math.BigDecimal; | |||
| /** | |||
| * Projection for {@link com.ffii.tsms.modules.data.entity.Salary} | |||
| */ | |||
| @@ -8,5 +10,5 @@ public interface SalarySearchInfo { | |||
| Integer getSalaryPoint(); | |||
| Integer getLowerLimit(); | |||
| Integer getUpperLimit(); | |||
| BigDecimal getHourlyRate(); | |||
| } | |||
| @@ -3,12 +3,15 @@ package com.ffii.tsms.modules.data.service | |||
| import com.ffii.core.support.AbstractBaseEntityService | |||
| import com.ffii.core.support.AbstractIdEntityService | |||
| import com.ffii.core.support.JdbcDao | |||
| import com.ffii.tsms.modules.data.entity.Department | |||
| import com.ffii.tsms.modules.data.entity.DepartmentRepository | |||
| import com.ffii.core.utils.ExcelUtils | |||
| import com.ffii.tsms.modules.data.entity.Salary | |||
| import com.ffii.tsms.modules.data.entity.SalaryRepository | |||
| import com.ffii.tsms.modules.data.entity.projections.SalarySearchInfo | |||
| import org.apache.poi.ss.usermodel.Sheet | |||
| import org.apache.poi.ss.usermodel.Workbook | |||
| import org.springframework.stereotype.Service | |||
| import org.springframework.transaction.annotation.Transactional | |||
| import java.math.BigDecimal | |||
| @Service | |||
| open class SalaryService( | |||
| @@ -28,4 +31,45 @@ open class SalaryService( | |||
| ) | |||
| return jdbcDao.queryForList(sql.toString(), args) | |||
| } | |||
| @Transactional(rollbackFor = [Exception::class]) | |||
| open fun importFile(workbook: Workbook?): String { | |||
| if (workbook == null) { | |||
| return "No Excel import" // if workbook is null | |||
| } | |||
| val deleteDataInSalary = StringBuilder( | |||
| "DELETE FROM salary" | |||
| ) | |||
| val disableForeignKeyChecks = StringBuilder( | |||
| "SET FOREIGN_KEY_CHECKS = 0" | |||
| ) | |||
| val enableForeignKeyChecks = StringBuilder( | |||
| "SET FOREIGN_KEY_CHECKS = 1" | |||
| ) | |||
| jdbcDao.executeUpdate(disableForeignKeyChecks.toString()) | |||
| jdbcDao.executeUpdate(deleteDataInSalary.toString()) | |||
| val sheet: Sheet = workbook.getSheetAt(0) | |||
| // val sheetValues: MutableList<Map<String, Any>> = ArrayList() | |||
| for (i in 2..sheet.lastRowNum){ | |||
| val salary = Salary().apply { | |||
| salaryPoint = ExcelUtils.getIntValue(ExcelUtils.getCell(sheet, i, 0)) | |||
| lowerLimit = ExcelUtils.getIntValue(ExcelUtils.getCell(sheet, i, 1)) | |||
| upperLimit = ExcelUtils.getIntValue(ExcelUtils.getCell(sheet, i, 2)) | |||
| increment = ExcelUtils.getIntValue(ExcelUtils.getCell(sheet, i, 3)) | |||
| hourlyRate = ExcelUtils.getDecimalValue(ExcelUtils.getCell(sheet, i, 4)) | |||
| } | |||
| saveAndFlush(salary) | |||
| // println("Lower Limit: " + ExcelUtils.getIntValue(ExcelUtils.getCell(sheet, i, 1))) | |||
| } | |||
| jdbcDao.executeUpdate(enableForeignKeyChecks.toString()) | |||
| return "OK" | |||
| } | |||
| } | |||
| @@ -5,17 +5,27 @@ import com.ffii.core.utils.CriteriaArgsBuilder | |||
| import com.ffii.tsms.modules.data.entity.projections.SalarySearchInfo | |||
| import com.ffii.tsms.modules.data.service.DepartmentService | |||
| import com.ffii.tsms.modules.data.service.SalaryService | |||
| import com.ffii.tsms.modules.report.service.ReportService | |||
| import com.ffii.tsms.modules.report.web.model.ProjectCashFlowReportRequest | |||
| import jakarta.servlet.http.HttpServletRequest | |||
| import jakarta.validation.Valid | |||
| import org.apache.poi.ss.usermodel.Workbook | |||
| import org.apache.poi.xssf.usermodel.XSSFWorkbook | |||
| import org.springframework.core.io.ByteArrayResource | |||
| import org.springframework.core.io.Resource | |||
| import org.springframework.http.ResponseEntity | |||
| import org.springframework.web.bind.ServletRequestBindingException | |||
| import org.springframework.web.bind.annotation.GetMapping | |||
| import org.springframework.web.bind.annotation.RequestMapping | |||
| import org.springframework.web.bind.annotation.RestController | |||
| import org.springframework.web.bind.annotation.* | |||
| import org.springframework.web.multipart.MultipartHttpServletRequest | |||
| import java.io.IOException | |||
| import java.time.LocalDate | |||
| @RestController | |||
| @RequestMapping("/salarys") | |||
| class SalaryController( | |||
| private val salaryService: SalaryService | |||
| private val salaryService: SalaryService, | |||
| private val excelReportService: ReportService | |||
| ) { | |||
| @GetMapping | |||
| @@ -34,4 +44,33 @@ class SalaryController( | |||
| ) | |||
| ) | |||
| } | |||
| @PostMapping("/import") | |||
| fun importFile(request: HttpServletRequest): ResponseEntity<*> { | |||
| var workbook: Workbook? = null | |||
| try { | |||
| val multipartFile = (request as MultipartHttpServletRequest).getFile("multipartFileList") | |||
| if (multipartFile != null) { | |||
| workbook = XSSFWorkbook(multipartFile.inputStream) | |||
| } | |||
| } catch (e: Exception) { | |||
| println("Excel Wrong") | |||
| println(e) | |||
| } | |||
| return ResponseEntity.ok(salaryService.importFile(workbook)) | |||
| } | |||
| @PostMapping("/export") | |||
| @Throws(ServletRequestBindingException::class, IOException::class) | |||
| fun exportSalaryList(): ResponseEntity<Resource> { | |||
| val reportResult: ByteArray = excelReportService.exportSalaryList() | |||
| // val mediaType: MediaType = MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") | |||
| return ResponseEntity.ok() | |||
| // .contentType(mediaType) | |||
| .header("filename", "Salary Point List - " + LocalDate.now() + ".xlsx") | |||
| .body(ByteArrayResource(reportResult)) | |||
| } | |||
| } | |||
| @@ -19,6 +19,7 @@ open class ReportService { | |||
| private val FORMATTED_TODAY = LocalDate.now().format(DATE_FORMATTER) | |||
| private val PROJECT_CASH_FLOW_REPORT = "templates/report/EX02_Project Cash Flow Report.xlsx" | |||
| private val SALART_LIST_TEMPLATE = "templates/report/Salary Template.xlsx" | |||
| // ==============================|| GENERATE REPORT ||============================== // | |||
| @Throws(IOException::class) | |||
| @@ -34,6 +35,19 @@ open class ReportService { | |||
| return outputStream.toByteArray() | |||
| } | |||
| @Throws(IOException::class) | |||
| fun exportSalaryList(): ByteArray { | |||
| // Generate the Excel report with query results | |||
| val workbook: Workbook = createSalaryList(SALART_LIST_TEMPLATE) | |||
| // Write the workbook to a ByteArrayOutputStream | |||
| val outputStream: ByteArrayOutputStream = ByteArrayOutputStream() | |||
| workbook.write(outputStream) | |||
| workbook.close() | |||
| return outputStream.toByteArray() | |||
| } | |||
| // ==============================|| CREATE REPORT ||============================== // | |||
| @Throws(IOException::class) | |||
| private fun createProjectCashFlowReport( | |||
| @@ -157,4 +171,18 @@ open class ReportService { | |||
| return workbook | |||
| } | |||
| @Throws(IOException::class) | |||
| private fun createSalaryList( | |||
| templatePath: String, | |||
| ): Workbook { | |||
| val resource = ClassPathResource(templatePath) | |||
| val templateInputStream = resource.inputStream | |||
| val workbook: Workbook = XSSFWorkbook(templateInputStream) | |||
| val sheet: Sheet = workbook.getSheetAt(0) | |||
| return workbook | |||
| } | |||
| } | |||
| @@ -0,0 +1,4 @@ | |||
| -- liquibase formatted sql | |||
| -- changeset jasonT:hourlyRate | |||
| ALTER TABLE tsmsdb.salary ADD hourlyRate DECIMAL(5,2) NULL; | |||