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; |