| @@ -66,7 +66,7 @@ public class Staff extends BaseEntity<Long> { | |||||
| @NotNull | @NotNull | ||||
| @ManyToOne | @ManyToOne | ||||
| @JoinColumn(name = "salaryId") | |||||
| @JoinColumn(name = "salaryId", referencedColumnName="salaryPoint") | |||||
| private Salary salary; | private Salary salary; | ||||
| @ManyToOne | @ManyToOne | ||||
| @@ -4,6 +4,7 @@ import com.ffii.core.support.AbstractBaseEntityService | |||||
| import com.ffii.core.support.AbstractIdEntityService | import com.ffii.core.support.AbstractIdEntityService | ||||
| import com.ffii.core.support.JdbcDao | import com.ffii.core.support.JdbcDao | ||||
| import com.ffii.core.utils.ExcelUtils | import com.ffii.core.utils.ExcelUtils | ||||
| import com.ffii.core.utils.NumberUtils | |||||
| import com.ffii.tsms.modules.data.entity.Salary | import com.ffii.tsms.modules.data.entity.Salary | ||||
| import com.ffii.tsms.modules.data.entity.SalaryRepository | import com.ffii.tsms.modules.data.entity.SalaryRepository | ||||
| import com.ffii.tsms.modules.data.entity.projections.SalarySearchInfo | import com.ffii.tsms.modules.data.entity.projections.SalarySearchInfo | ||||
| @@ -25,7 +26,7 @@ open class SalaryService( | |||||
| open fun combo(args: Map<String, Any>): List<Map<String, Any>> { | open fun combo(args: Map<String, Any>): List<Map<String, Any>> { | ||||
| val sql = StringBuilder("select" | val sql = StringBuilder("select" | ||||
| + " id, " | |||||
| + " salaryPoint as id, " | |||||
| + " concat(salaryPoint, ' (', lowerLimit,' - ', upperLimit, ') ') as label " | + " concat(salaryPoint, ' (', lowerLimit,' - ', upperLimit, ') ') as label " | ||||
| + " from salary s " | + " from salary s " | ||||
| ) | ) | ||||
| @@ -50,19 +51,26 @@ open class SalaryService( | |||||
| "SET FOREIGN_KEY_CHECKS = 1" | "SET FOREIGN_KEY_CHECKS = 1" | ||||
| ) | ) | ||||
| val resetAutoIncrement = StringBuilder( | |||||
| "ALTER TABLE salary AUTO_INCREMENT = 1" | |||||
| ) | |||||
| jdbcDao.executeUpdate(disableForeignKeyChecks.toString()) | jdbcDao.executeUpdate(disableForeignKeyChecks.toString()) | ||||
| jdbcDao.executeUpdate(resetAutoIncrement.toString()) | |||||
| jdbcDao.executeUpdate(deleteDataInSalary.toString()) | jdbcDao.executeUpdate(deleteDataInSalary.toString()) | ||||
| val sheet: Sheet = workbook.getSheetAt(0) | val sheet: Sheet = workbook.getSheetAt(0) | ||||
| // val sheetValues: MutableList<Map<String, Any>> = ArrayList() | // val sheetValues: MutableList<Map<String, Any>> = ArrayList() | ||||
| val evaluator = sheet.workbook.creationHelper.createFormulaEvaluator() | |||||
| for (i in 2..sheet.lastRowNum){ | for (i in 2..sheet.lastRowNum){ | ||||
| val salary = Salary().apply { | val salary = Salary().apply { | ||||
| salaryPoint = ExcelUtils.getIntValue(ExcelUtils.getCell(sheet, i, 0)) | salaryPoint = ExcelUtils.getIntValue(ExcelUtils.getCell(sheet, i, 0)) | ||||
| lowerLimit = ExcelUtils.getIntValue(ExcelUtils.getCell(sheet, i, 1)) | |||||
| upperLimit = ExcelUtils.getIntValue(ExcelUtils.getCell(sheet, i, 2)) | |||||
| lowerLimit = evaluator.evaluate(ExcelUtils.getCell(sheet, i, 1)).numberValue.toInt() | |||||
| upperLimit = evaluator.evaluate(ExcelUtils.getCell(sheet, i, 2)).numberValue.toInt() | |||||
| increment = ExcelUtils.getIntValue(ExcelUtils.getCell(sheet, i, 3)) | increment = ExcelUtils.getIntValue(ExcelUtils.getCell(sheet, i, 3)) | ||||
| hourlyRate = ExcelUtils.getDecimalValue(ExcelUtils.getCell(sheet, i, 4)) | |||||
| hourlyRate = evaluator.evaluate(ExcelUtils.getCell(sheet, i, 4)).numberValue.toBigDecimal() | |||||
| } | } | ||||
| saveAndFlush(salary) | saveAndFlush(salary) | ||||
| // println("Lower Limit: " + ExcelUtils.getIntValue(ExcelUtils.getCell(sheet, i, 1))) | // println("Lower Limit: " + ExcelUtils.getIntValue(ExcelUtils.getCell(sheet, i, 1))) | ||||
| @@ -2,6 +2,7 @@ package com.ffii.tsms.modules.data.web | |||||
| import com.ffii.core.response.RecordsRes | import com.ffii.core.response.RecordsRes | ||||
| import com.ffii.core.utils.CriteriaArgsBuilder | import com.ffii.core.utils.CriteriaArgsBuilder | ||||
| import com.ffii.tsms.modules.data.entity.Salary | |||||
| import com.ffii.tsms.modules.data.entity.projections.SalarySearchInfo | import com.ffii.tsms.modules.data.entity.projections.SalarySearchInfo | ||||
| import com.ffii.tsms.modules.data.service.DepartmentService | import com.ffii.tsms.modules.data.service.DepartmentService | ||||
| import com.ffii.tsms.modules.data.service.SalaryService | import com.ffii.tsms.modules.data.service.SalaryService | ||||
| @@ -65,8 +66,8 @@ class SalaryController( | |||||
| @PostMapping("/export") | @PostMapping("/export") | ||||
| @Throws(ServletRequestBindingException::class, IOException::class) | @Throws(ServletRequestBindingException::class, IOException::class) | ||||
| fun exportSalaryList(): ResponseEntity<Resource> { | fun exportSalaryList(): ResponseEntity<Resource> { | ||||
| val reportResult: ByteArray = excelReportService.exportSalaryList() | |||||
| val salarys: List<Salary> = salaryService.listAll() | |||||
| val reportResult: ByteArray = excelReportService.exportSalaryList(salarys) | |||||
| // val mediaType: MediaType = MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") | // val mediaType: MediaType = MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") | ||||
| return ResponseEntity.ok() | return ResponseEntity.ok() | ||||
| // .contentType(mediaType) | // .contentType(mediaType) | ||||
| @@ -1,5 +1,7 @@ | |||||
| package com.ffii.tsms.modules.report.service | package com.ffii.tsms.modules.report.service | ||||
| import com.ffii.tsms.modules.data.entity.Salary | |||||
| import com.ffii.tsms.modules.data.entity.projections.SalarySearchInfo | |||||
| import com.ffii.tsms.modules.project.entity.Invoice | import com.ffii.tsms.modules.project.entity.Invoice | ||||
| import com.ffii.tsms.modules.project.entity.Project | import com.ffii.tsms.modules.project.entity.Project | ||||
| import org.apache.poi.ss.usermodel.Sheet | import org.apache.poi.ss.usermodel.Sheet | ||||
| @@ -36,9 +38,9 @@ open class ReportService { | |||||
| } | } | ||||
| @Throws(IOException::class) | @Throws(IOException::class) | ||||
| fun exportSalaryList(): ByteArray { | |||||
| fun exportSalaryList(salarys: List<Salary>): ByteArray { | |||||
| // Generate the Excel report with query results | // Generate the Excel report with query results | ||||
| val workbook: Workbook = createSalaryList(SALART_LIST_TEMPLATE) | |||||
| val workbook: Workbook = createSalaryList(salarys, SALART_LIST_TEMPLATE) | |||||
| // Write the workbook to a ByteArrayOutputStream | // Write the workbook to a ByteArrayOutputStream | ||||
| val outputStream: ByteArrayOutputStream = ByteArrayOutputStream() | val outputStream: ByteArrayOutputStream = ByteArrayOutputStream() | ||||
| @@ -174,13 +176,37 @@ open class ReportService { | |||||
| @Throws(IOException::class) | @Throws(IOException::class) | ||||
| private fun createSalaryList( | private fun createSalaryList( | ||||
| salarys : List<Salary>, | |||||
| templatePath: String, | templatePath: String, | ||||
| ): Workbook { | ): Workbook { | ||||
| val resource = ClassPathResource(templatePath) | val resource = ClassPathResource(templatePath) | ||||
| val templateInputStream = resource.inputStream | val templateInputStream = resource.inputStream | ||||
| val workbook: Workbook = XSSFWorkbook(templateInputStream) | val workbook: Workbook = XSSFWorkbook(templateInputStream) | ||||
| val accountingStyle = workbook.createDataFormat().getFormat("_(* #,##0.00_);_(* (#,##0.00);_(* \"-\"??_);_(@_)") | |||||
| val sheet: Sheet = workbook.getSheetAt(0) | val sheet: Sheet = workbook.getSheetAt(0) | ||||
| var rowIndex = 2 | |||||
| salarys.forEachIndexed { index, salary -> | |||||
| sheet.getRow(rowIndex++).apply { | |||||
| getCell(0).setCellValue(salary.salaryPoint.toDouble()) | |||||
| when (index){ | |||||
| 0 -> getCell(1).setCellValue(salary.lowerLimit.toDouble()) | |||||
| else -> getCell(1).cellFormula = "(C{previousRow}+1)".replace("{previousRow}", (rowIndex - 1).toString()) | |||||
| } | |||||
| getCell(2).cellFormula = "(B{currentRow}+D{currentRow})-1".replace("{currentRow}", rowIndex.toString()) | |||||
| // getCell(2).cellStyle.dataFormat = accountingStyle | |||||
| getCell(3).setCellValue(salary.increment.toDouble()) | |||||
| getCell(4).cellFormula = "(((C{currentRow}+B{currentRow})/2)/20)/8".replace("{currentRow}", rowIndex.toString()) | |||||
| // getCell(4).cellStyle.dataFormat = accountingStyle | |||||
| } | |||||
| } | |||||
| // println(salarys.size) | |||||
| return workbook | return workbook | ||||
| } | } | ||||
| @@ -0,0 +1,4 @@ | |||||
| -- liquibase formatted sql | |||||
| -- changeset jasonT:alter_hourlyRate | |||||
| ALTER TABLE tsmsdb.salary MODIFY COLUMN hourlyRate decimal(7,2) NULL; | |||||
| @@ -0,0 +1,12 @@ | |||||
| -- liquibase formatted sql | |||||
| -- changeset jasonT:Update_FK | |||||
| ALTER TABLE tsmsdb.staff DROP FOREIGN KEY FK_STAFF_ON_SALARYID; | |||||
| ALTER TABLE tsmsdb.salary_effective DROP FOREIGN KEY FK_SALARY_EFFECTIVE_ON_SALARYID; | |||||
| ALTER TABLE `tsmsdb`.`salary` CHANGE COLUMN `id` `id` INT NOT NULL ; | |||||
| CREATE INDEX idx_referenced_column ON salary(salaryPoint); | |||||
| ALTER TABLE staff ADD CONSTRAINT FK_STAFF_ON_SALARYID FOREIGN KEY (salaryId) REFERENCES salary(salaryPoint); | |||||
| @@ -0,0 +1,6 @@ | |||||
| -- liquibase formatted sql | |||||
| -- changeset wayne:salary_data | |||||
| UPDATE salary | |||||
| SET hourlyRate = (lowerLimit + upperLimit) / 2 / 20 / 8; | |||||