diff --git a/src/main/java/com/ffii/tsms/modules/claim/service/ClaimService.kt b/src/main/java/com/ffii/tsms/modules/claim/service/ClaimService.kt index 68675bd..31cd335 100644 --- a/src/main/java/com/ffii/tsms/modules/claim/service/ClaimService.kt +++ b/src/main/java/com/ffii/tsms/modules/claim/service/ClaimService.kt @@ -36,20 +36,22 @@ open class ClaimService( private val fileRepository: FileRepository, private val userRepository: UserRepository, private val staffsService: StaffsService, - ) : AbstractBaseEntityService(jdbcDao, claimRepository) { +) : AbstractBaseEntityService(jdbcDao, claimRepository) { open fun allClaims(): List> { - val sql = StringBuilder("select " + - "c.id, " + - "c.created, " + - "c.code, " + - "sum(cd.amount) as amount, " + - "c.type, " + - "c.status, " + - "c.remark " + - "from claim c " + - "left join claim_detail cd on cd.claimId = c.id " + - "where c.deleted = false " + - "group by c.id") + val sql = StringBuilder( + "select " + + "c.id, " + + "c.created, " + + "c.code, " + + "sum(cd.amount) as amount, " + + "c.type, " + + "c.status, " + + "c.remark " + + "from claim c " + + "left join claim_detail cd on cd.claimId = c.id " + + "where c.deleted = false " + + "group by c.id" + ) return jdbcDao.queryForList(sql.toString()) } diff --git a/src/main/java/com/ffii/tsms/modules/claim/web/ClaimController.kt b/src/main/java/com/ffii/tsms/modules/claim/web/ClaimController.kt index ffa6735..ebc9048 100644 --- a/src/main/java/com/ffii/tsms/modules/claim/web/ClaimController.kt +++ b/src/main/java/com/ffii/tsms/modules/claim/web/ClaimController.kt @@ -14,6 +14,7 @@ import org.apache.logging.log4j.core.config.plugins.validation.constraints.Requi import org.springframework.web.bind.ServletRequestBindingException import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.ModelAttribute +import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RequestMapping @@ -34,6 +35,11 @@ class ClaimController(private val claimService: ClaimService) { return claimService.allClaims() } + @GetMapping("/{id}") + fun findClaim(@PathVariable id: Long?): List> { + return claimService.allClaims() + } + @PostMapping("/save") fun saveClaim( @RequestParam(required = false) id: Long?, diff --git a/src/main/java/com/ffii/tsms/modules/common/service/ExcelReportService.kt b/src/main/java/com/ffii/tsms/modules/common/service/ExcelReportService.kt new file mode 100644 index 0000000..6441c0f --- /dev/null +++ b/src/main/java/com/ffii/tsms/modules/common/service/ExcelReportService.kt @@ -0,0 +1,97 @@ +package com.ffii.tsms.modules.common.service + +import com.ffii.tsms.modules.project.entity.Project +import org.apache.poi.ss.usermodel.Cell +import org.apache.poi.ss.usermodel.CellStyle +import org.apache.poi.ss.usermodel.HorizontalAlignment +import org.apache.poi.ss.usermodel.Row +import org.apache.poi.ss.usermodel.Sheet +import org.apache.poi.ss.usermodel.Workbook +import org.apache.poi.ss.util.CellRangeAddress +import org.apache.poi.ss.util.CellUtil +import org.apache.poi.xssf.usermodel.XSSFWorkbook +import org.springframework.core.io.ClassPathResource +import org.springframework.stereotype.Service +import java.io.ByteArrayOutputStream +import java.io.IOException +import java.time.LocalDate +import java.time.LocalDateTime +import java.time.format.DateTimeFormatter + +@Service +open class ExcelReportService { + private val DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy/MM/dd") + private val FORMATTED_TODAY = LocalDate.now().format(DATE_FORMATTER) + + private val EX02_PROJECT_CASH_FLOW_REPORT = "templates/report/EX02_Project Cash Flow Report.xlsx" + + // ==============================|| GENERATE REPORT ||============================== // + @Throws(IOException::class) + fun generateEX02ProjectCashFlowReport(project: Project): ByteArray { + // Generate the Excel report with query results + val workbook: Workbook = createEX02ProjectCashFlowReport(project, EX02_PROJECT_CASH_FLOW_REPORT) + + // 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 createEX02ProjectCashFlowReport( + project: Project, + templatePath: String, + ): Workbook { + // please create a new function for each report template + val resource = ClassPathResource(templatePath) + val templateInputStream = resource.inputStream + val workbook: Workbook = XSSFWorkbook(templateInputStream) + + val sheet: Sheet = workbook.getSheetAt(0) + +// val alignLeftStyle: CellStyle = workbook.createCellStyle().apply { +// alignment = HorizontalAlignment.LEFT // Set the alignment to left +// } +// +// val alignRightStyle: CellStyle = workbook.createCellStyle().apply { +// alignment = HorizontalAlignment.RIGHT // Set the alignment to right +// } + + var rowIndex = 1 // Assuming the location is in (1,2), which is the report date field + var columnIndex = 2 + sheet.getRow(rowIndex).getCell(columnIndex).apply { + setCellValue(FORMATTED_TODAY) + } + + rowIndex = 2 + sheet.getRow(rowIndex).getCell(columnIndex).apply { + setCellValue(project.code) + } + + rowIndex = 3 + sheet.getRow(rowIndex).getCell(columnIndex).apply { + setCellValue(project.name) + } + + rowIndex = 4 + sheet.getRow(rowIndex).getCell(columnIndex).apply { + setCellValue(if (project.customer?.name == null) "N/A" else project.customer?.name) + } + + rowIndex = 5 + sheet.getRow(rowIndex).getCell(columnIndex).apply { + setCellValue(if (project.teamLead?.team?.name == null) "N/A" else project.teamLead?.team?.name) + } + + rowIndex = 9 + sheet.getRow(rowIndex).apply { + getCell(1).setCellValue(project.expectedTotalFee!! * 0.8) + getCell(2).setCellValue(project.expectedTotalFee!!) + } + + return workbook + } +} \ 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 new file mode 100644 index 0000000..30dddaa --- /dev/null +++ b/src/main/java/com/ffii/tsms/modules/report/web/ReportController.kt @@ -0,0 +1,34 @@ +package com.ffii.tsms.modules.report.web + +import com.ffii.tsms.modules.common.service.ExcelReportService +import com.ffii.tsms.modules.project.entity.ProjectRepository +import com.ffii.tsms.modules.report.web.model.EX02ProjectCashFlowReportRequest +import jakarta.validation.Valid +import org.springframework.core.io.ByteArrayResource +import org.springframework.core.io.Resource +import org.springframework.http.MediaType +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.ServletRequestBindingException +import org.springframework.web.bind.annotation.PostMapping +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController +import java.io.IOException +import java.time.LocalDate + +@RestController +@RequestMapping("/reports") +class ReportController(private val excelReportService: ExcelReportService, private val projectRepository: ProjectRepository) { + + @PostMapping("/EX02-ProjectCashFlowReport") + @Throws(ServletRequestBindingException::class, IOException::class) + fun getEx02ProjectCashFlowReport(@RequestBody @Valid request: EX02ProjectCashFlowReportRequest): ResponseEntity { + + val project = projectRepository.findById(request.projectId).orElseThrow() + + val reportResult: ByteArray = excelReportService.generateEX02ProjectCashFlowReport(project) + return ResponseEntity.ok() + .header("filename", "EX02 - Project Cash Flow Report" + LocalDate.now() + ".xlsx") + .body(ByteArrayResource(reportResult)) + } +} \ No newline at end of file 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 new file mode 100644 index 0000000..083368a --- /dev/null +++ b/src/main/java/com/ffii/tsms/modules/report/web/model/ReportRequest.kt @@ -0,0 +1,5 @@ +package com.ffii.tsms.modules.report.web.model + +data class EX02ProjectCashFlowReportRequest ( + val projectId: Long +) \ No newline at end of file diff --git a/src/main/resources/templates/report/AR01_Late Start Report v01.xlsx b/src/main/resources/templates/report/AR01_Late Start Report v01.xlsx new file mode 100644 index 0000000..dc6da0d Binary files /dev/null and b/src/main/resources/templates/report/AR01_Late Start Report v01.xlsx differ diff --git a/src/main/resources/templates/report/AR02_Delay Report v02.xlsx b/src/main/resources/templates/report/AR02_Delay Report v02.xlsx new file mode 100644 index 0000000..fe0d493 Binary files /dev/null and b/src/main/resources/templates/report/AR02_Delay Report v02.xlsx differ diff --git a/src/main/resources/templates/report/AR03_Resource Overconsumption.xlsx b/src/main/resources/templates/report/AR03_Resource Overconsumption.xlsx new file mode 100644 index 0000000..dc4f048 Binary files /dev/null and b/src/main/resources/templates/report/AR03_Resource Overconsumption.xlsx differ diff --git a/src/main/resources/templates/report/AR04_Cost and Expense Report v02.xlsx b/src/main/resources/templates/report/AR04_Cost and Expense Report v02.xlsx new file mode 100644 index 0000000..cb9ba8e Binary files /dev/null and b/src/main/resources/templates/report/AR04_Cost and Expense Report v02.xlsx differ diff --git a/src/main/resources/templates/report/AR05_Project Completion Report.xlsx b/src/main/resources/templates/report/AR05_Project Completion Report.xlsx new file mode 100644 index 0000000..d5bd3cc Binary files /dev/null and b/src/main/resources/templates/report/AR05_Project Completion Report.xlsx differ diff --git a/src/main/resources/templates/report/AR06_Project Completion Report with Outstanding Accounts Receivable v02.xlsx b/src/main/resources/templates/report/AR06_Project Completion Report with Outstanding Accounts Receivable v02.xlsx new file mode 100644 index 0000000..25a4a74 Binary files /dev/null and b/src/main/resources/templates/report/AR06_Project Completion Report with Outstanding Accounts Receivable v02.xlsx differ diff --git a/src/main/resources/templates/report/AR07_Project P&L Report v02.xlsx b/src/main/resources/templates/report/AR07_Project P&L Report v02.xlsx new file mode 100644 index 0000000..d0e8182 Binary files /dev/null and b/src/main/resources/templates/report/AR07_Project P&L Report v02.xlsx differ diff --git a/src/main/resources/templates/report/AR08_Monthly Work Hours Analysis Report.xlsx b/src/main/resources/templates/report/AR08_Monthly Work Hours Analysis Report.xlsx new file mode 100644 index 0000000..9570eda Binary files /dev/null and b/src/main/resources/templates/report/AR08_Monthly Work Hours Analysis Report.xlsx differ diff --git a/src/main/resources/templates/report/EX01_Financial Status Report.xlsx b/src/main/resources/templates/report/EX01_Financial Status Report.xlsx new file mode 100644 index 0000000..aa036fa Binary files /dev/null and b/src/main/resources/templates/report/EX01_Financial Status Report.xlsx differ diff --git a/src/main/resources/templates/report/EX02_Project Cash Flow Report.xlsx b/src/main/resources/templates/report/EX02_Project Cash Flow Report.xlsx new file mode 100644 index 0000000..ac160ab Binary files /dev/null and b/src/main/resources/templates/report/EX02_Project Cash Flow Report.xlsx differ