import and export Salary Templatetags/Baseline_30082024_BACKEND_UAT
@@ -6,6 +6,8 @@ import jakarta.persistence.Entity; | |||||
import jakarta.persistence.Table; | import jakarta.persistence.Table; | ||||
import jakarta.validation.constraints.NotNull; | import jakarta.validation.constraints.NotNull; | ||||
import java.math.BigDecimal; | |||||
@Entity | @Entity | ||||
@Table(name = "salary") | @Table(name = "salary") | ||||
public class Salary extends IdEntity<Long> { | public class Salary extends IdEntity<Long> { | ||||
@@ -25,6 +27,9 @@ public class Salary extends IdEntity<Long> { | |||||
@Column(name = "increment") | @Column(name = "increment") | ||||
private Integer increment; | private Integer increment; | ||||
@Column(name = "hourlyRate") | |||||
private BigDecimal hourlyRate; | |||||
public Integer getIncrement() { | public Integer getIncrement() { | ||||
return increment; | return increment; | ||||
} | } | ||||
@@ -56,4 +61,12 @@ public class Salary extends IdEntity<Long> { | |||||
public Integer getSalaryPoint() { | public Integer getSalaryPoint() { | ||||
return salaryPoint; | 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; | package com.ffii.tsms.modules.data.entity.projections; | ||||
import java.math.BigDecimal; | |||||
/** | /** | ||||
* Projection for {@link com.ffii.tsms.modules.data.entity.Salary} | * Projection for {@link com.ffii.tsms.modules.data.entity.Salary} | ||||
*/ | */ | ||||
@@ -8,5 +10,5 @@ public interface SalarySearchInfo { | |||||
Integer getSalaryPoint(); | Integer getSalaryPoint(); | ||||
Integer getLowerLimit(); | Integer getLowerLimit(); | ||||
Integer getUpperLimit(); | 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.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.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.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 | ||||
import org.apache.poi.ss.usermodel.Sheet | |||||
import org.apache.poi.ss.usermodel.Workbook | |||||
import org.springframework.stereotype.Service | import org.springframework.stereotype.Service | ||||
import org.springframework.transaction.annotation.Transactional | |||||
import java.math.BigDecimal | |||||
@Service | @Service | ||||
open class SalaryService( | open class SalaryService( | ||||
@@ -28,4 +31,45 @@ open class SalaryService( | |||||
) | ) | ||||
return jdbcDao.queryForList(sql.toString(), args) | 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.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 | ||||
import com.ffii.tsms.modules.report.service.ReportService | |||||
import com.ffii.tsms.modules.report.web.model.ProjectCashFlowReportRequest | |||||
import jakarta.servlet.http.HttpServletRequest | 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.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 | @RestController | ||||
@RequestMapping("/salarys") | @RequestMapping("/salarys") | ||||
class SalaryController( | class SalaryController( | ||||
private val salaryService: SalaryService | |||||
private val salaryService: SalaryService, | |||||
private val excelReportService: ReportService | |||||
) { | ) { | ||||
@GetMapping | @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 FORMATTED_TODAY = LocalDate.now().format(DATE_FORMATTER) | ||||
private val PROJECT_CASH_FLOW_REPORT = "templates/report/EX02_Project Cash Flow Report.xlsx" | 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 ||============================== // | // ==============================|| GENERATE REPORT ||============================== // | ||||
@Throws(IOException::class) | @Throws(IOException::class) | ||||
@@ -34,6 +35,19 @@ open class ReportService { | |||||
return outputStream.toByteArray() | 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 ||============================== // | // ==============================|| CREATE REPORT ||============================== // | ||||
@Throws(IOException::class) | @Throws(IOException::class) | ||||
private fun createProjectCashFlowReport( | private fun createProjectCashFlowReport( | ||||
@@ -157,4 +171,18 @@ open class ReportService { | |||||
return workbook | 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; |