diff --git a/src/main/java/com/ffii/tsms/modules/data/service/DashboardService.kt b/src/main/java/com/ffii/tsms/modules/data/service/DashboardService.kt index 388d397..5a03276 100644 --- a/src/main/java/com/ffii/tsms/modules/data/service/DashboardService.kt +++ b/src/main/java/com/ffii/tsms/modules/data/service/DashboardService.kt @@ -7,15 +7,13 @@ import com.ffii.tsms.modules.data.entity.CustomerType import com.ffii.tsms.modules.data.entity.CustomerRepository import com.ffii.tsms.modules.data.entity.CustomerTypeRepository import com.ffii.tsms.modules.data.web.models.FinancialSummaryByClient +import com.ffii.tsms.modules.data.web.models.FinancialSummaryByProject import com.ffii.tsms.modules.data.web.models.SaveCustomerResponse import com.ffii.tsms.modules.project.entity.Invoice import com.ffii.tsms.modules.project.entity.Project import com.ffii.tsms.modules.project.web.models.SaveCustomerRequest import com.ffii.tsms.modules.timesheet.entity.Timesheet -import org.apache.poi.ss.usermodel.BorderStyle -import org.apache.poi.ss.usermodel.HorizontalAlignment -import org.apache.poi.ss.usermodel.Sheet -import org.apache.poi.ss.usermodel.Workbook +import org.apache.poi.ss.usermodel.* import org.apache.poi.ss.util.CellRangeAddress import org.apache.poi.ss.util.CellUtil import org.apache.poi.xssf.usermodel.XSSFWorkbook @@ -42,7 +40,7 @@ open class DashboardService( private val FORMATTED_TODAY = LocalDate.now().format(DATE_FORMATTER) private val FINANCIAL_SUMMARY_FOR_CLIENT = "templates/report/[Dashboard] Financial Summary for client.xlsx" - private val FINANCIAL_SUMMARY_FOR_PROJET = "templates/report/[Dashboard] Financial Summary for project.xlsx" + private val FINANCIAL_SUMMARY_FOR_PROJECT = "templates/report/[Dashboard] Financial Summary for project.xlsx" fun CustomerSubsidiary(args: Map): List> { val sql = StringBuilder("select" @@ -2163,9 +2161,9 @@ open class DashboardService( fontName = "Times New Roman" } - val normalFontStyle = workbook.createCellStyle().apply { - setFont(normalFont) - } +// val normalFontStyle = workbook.createCellStyle().apply { +// setFont(normalFont) +// } var rowIndex = 1 // Assuming the location is in (1,2), which is the report date field var columnIndex = 1 @@ -2178,19 +2176,25 @@ open class DashboardService( sheet.createRow(rowIndex++).apply { createCell(0).apply { setCellValue(financialSummaryByClient.customerCode) - cellStyle = normalFontStyle + cellStyle.apply { + setFont(normalFont) + } CellUtil.setAlignment(this, HorizontalAlignment.LEFT) } createCell(1).apply { setCellValue(financialSummaryByClient.customerName) - cellStyle = normalFontStyle + cellStyle.apply { + setFont(normalFont) + dataFormat = accountingStyle + } CellUtil.setAlignment(this, HorizontalAlignment.LEFT) } createCell(2).apply { setCellValue(financialSummaryByClient.projectNo) - cellStyle = normalFontStyle.apply { + cellStyle.apply { + setFont(normalFont) dataFormat = accountingStyle } CellUtil.setAlignment(this, HorizontalAlignment.LEFT) @@ -2198,13 +2202,16 @@ open class DashboardService( createCell(3).apply { cellFormula = "IF(E${rowIndex}>=1,\"Positive\",\"Negative\")" - cellStyle = normalFontStyle + cellStyle.apply { + setFont(normalFont) + } CellUtil.setAlignment(this, HorizontalAlignment.CENTER) } createCell(4).apply { - cellFormula = "IFERROR(IF(K${rowIndex}=1, 0, K${rowIndex}/J${rowIndex}),0)" - cellStyle = normalFontStyle.apply { + cellFormula = "IFERROR(IF(K${rowIndex}=0, 0, K${rowIndex}/J${rowIndex}),0)" + cellStyle.apply { + setFont(normalFont) dataFormat = accountingStyle } CellUtil.setAlignment(this, HorizontalAlignment.RIGHT) @@ -2212,13 +2219,16 @@ open class DashboardService( createCell(5).apply { cellFormula = "IF(G${rowIndex}>=1,\"Positive\",\"Negative\")" - cellStyle = normalFontStyle + cellStyle.apply { + setFont(normalFont) + } CellUtil.setAlignment(this, HorizontalAlignment.CENTER) } createCell(6).apply { cellFormula = "IFERROR(H${rowIndex}/J${rowIndex},0)" - cellStyle = normalFontStyle.apply { + cellStyle.apply { + setFont(normalFont) dataFormat = accountingStyle } CellUtil.setAlignment(this, HorizontalAlignment.RIGHT) @@ -2226,7 +2236,8 @@ open class DashboardService( createCell(7).apply { setCellValue(financialSummaryByClient.totalFee) - cellStyle = normalFontStyle.apply { + cellStyle.apply { + setFont(normalFont) dataFormat = accountingStyle } CellUtil.setAlignment(this, HorizontalAlignment.RIGHT) @@ -2234,7 +2245,8 @@ open class DashboardService( createCell(8).apply { cellFormula = "H${rowIndex}*80%" - cellStyle = normalFontStyle.apply { + cellStyle.apply { + setFont(normalFont) dataFormat = accountingStyle } CellUtil.setAlignment(this, HorizontalAlignment.RIGHT) @@ -2242,7 +2254,8 @@ open class DashboardService( createCell(9).apply { setCellValue(financialSummaryByClient.cumulativeExpenditure) - cellStyle = normalFontStyle.apply { + cellStyle.apply { + setFont(normalFont) dataFormat = accountingStyle } CellUtil.setAlignment(this, HorizontalAlignment.RIGHT) @@ -2250,7 +2263,8 @@ open class DashboardService( createCell(10).apply { setCellValue(financialSummaryByClient.totalInvoiced) - cellStyle = normalFontStyle.apply { + cellStyle.apply { + setFont(normalFont) dataFormat = accountingStyle } CellUtil.setAlignment(this, HorizontalAlignment.RIGHT) @@ -2258,7 +2272,8 @@ open class DashboardService( createCell(11).apply { cellFormula = "IF(H${rowIndex}-K${rowIndex}<0,0,H${rowIndex}-K${rowIndex})" - cellStyle = normalFontStyle.apply { + cellStyle.apply { + setFont(normalFont) dataFormat = accountingStyle } CellUtil.setAlignment(this, HorizontalAlignment.RIGHT) @@ -2266,7 +2281,185 @@ open class DashboardService( createCell(12).apply { setCellValue(financialSummaryByClient.totalReceived) - cellStyle = normalFontStyle.apply { + cellStyle.apply { + setFont(normalFont) + dataFormat = accountingStyle + } + CellUtil.setAlignment(this, HorizontalAlignment.RIGHT) + } + } + } + + return workbook + } + + @Throws(IOException::class) + fun exportFinancialSummaryByProjectExcel( + financialSummaryByProjects: List, + ): ByteArray { + // Generate the Excel report with query results + val workbook: Workbook = + createFinancialSummaryByProjectExcel(financialSummaryByProjects, FINANCIAL_SUMMARY_FOR_PROJECT) + + // Write the workbook to a ByteArrayOutputStream + val outputStream: ByteArrayOutputStream = ByteArrayOutputStream() + workbook.write(outputStream) + workbook.close() + + return outputStream.toByteArray() + } + + @Throws(IOException::class) + private fun createFinancialSummaryByProjectExcel( + financialSummaryByProjects: List, + 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) + + // accounting style + comma style + val accountingStyle = workbook.createDataFormat().getFormat("_(* #,##0.00_);_(* (#,##0.00);_(* \"-\"??_);_(@_)") + + // normal font + val normalFont = workbook.createFont().apply { + fontName = "Times New Roman" + } + +// val normalFontStyle = workbook.createCellStyle().apply { +// setFont(normalFont) +// } + + var rowIndex = 1 // Assuming the location is in (1,2), which is the report date field + var columnIndex = 1 + sheet.getRow(rowIndex).createCell(columnIndex).apply { + setCellValue(FORMATTED_TODAY) + } + + rowIndex = 4 + financialSummaryByProjects.forEach { financialSummaryByProject: FinancialSummaryByProject -> + sheet.createRow(rowIndex++).apply { + createCell(0).apply { + setCellValue(financialSummaryByProject.projectCode) + cellStyle.apply { + setFont(normalFont) + } + CellUtil.setAlignment(this, HorizontalAlignment.LEFT) + } + + createCell(1).apply { + setCellValue(financialSummaryByProject.projectName) + cellStyle.apply { + setFont(normalFont) + dataFormat = accountingStyle + } + CellUtil.setAlignment(this, HorizontalAlignment.LEFT) + } + + createCell(2).apply { + setCellValue(financialSummaryByProject.customerName) + cellStyle.apply { + setFont(normalFont) + dataFormat = accountingStyle + } + CellUtil.setAlignment(this, HorizontalAlignment.LEFT) + } + + createCell(3).apply { + setCellValue(financialSummaryByProject.subsidiaryName ?: "N/A") + cellStyle.apply { + setFont(normalFont) + dataFormat = accountingStyle + } + CellUtil.setAlignment(this, HorizontalAlignment.LEFT) + } + + createCell(4).apply { + cellFormula = "IF(F${rowIndex}>=1,\"Positive\",\"Negative\")" + cellStyle.apply { + setFont(normalFont) + } + CellUtil.setAlignment(this, HorizontalAlignment.CENTER) + } + + createCell(5).apply { + cellFormula = "IFERROR(IF(L${rowIndex}=0, 0, K${rowIndex}/J${rowIndex}),0)" + cellStyle.apply { + setFont(normalFont) + dataFormat = accountingStyle + } + CellUtil.setAlignment(this, HorizontalAlignment.RIGHT) + } + + createCell(6).apply { + cellFormula = "IF(H${rowIndex}>=1,\"Positive\",\"Negative\")" + cellStyle.apply { + setFont(normalFont) + } + CellUtil.setAlignment(this, HorizontalAlignment.CENTER) + } + + createCell(7).apply { + cellFormula = "IFERROR(I${rowIndex}/K${rowIndex},0)" + cellStyle.apply { + setFont(normalFont) + dataFormat = accountingStyle + } + CellUtil.setAlignment(this, HorizontalAlignment.RIGHT) + } + + createCell(8).apply { + setCellValue(financialSummaryByProject.totalFee) + cellStyle.apply { + setFont(normalFont) + dataFormat = accountingStyle + } + CellUtil.setAlignment(this, HorizontalAlignment.RIGHT) + } + + createCell(9).apply { + cellFormula = "I${rowIndex}*80%" + cellStyle.apply { + setFont(normalFont) + dataFormat = accountingStyle + } + CellUtil.setAlignment(this, HorizontalAlignment.RIGHT) + } + + createCell(10).apply { + setCellValue(financialSummaryByProject.cumulativeExpenditure) + cellStyle.apply { + setFont(normalFont) + dataFormat = accountingStyle + } + CellUtil.setAlignment(this, HorizontalAlignment.RIGHT) + } + + createCell(11).apply { + setCellValue(financialSummaryByProject.totalInvoiced) + cellStyle.apply { + setFont(normalFont) + dataFormat = accountingStyle + } + CellUtil.setAlignment(this, HorizontalAlignment.RIGHT) + } + + createCell(12).apply { + cellFormula = "IF(I${rowIndex}-L${rowIndex}<0,0,I${rowIndex}-L${rowIndex})" + cellStyle.apply { + setFont(normalFont) + dataFormat = accountingStyle + } + CellUtil.setAlignment(this, HorizontalAlignment.RIGHT) + } + + createCell(13).apply { + setCellValue(financialSummaryByProject.totalReceived) + cellStyle.apply { + setFont(normalFont) dataFormat = accountingStyle } CellUtil.setAlignment(this, HorizontalAlignment.RIGHT) diff --git a/src/main/java/com/ffii/tsms/modules/data/web/DashboardController.kt b/src/main/java/com/ffii/tsms/modules/data/web/DashboardController.kt index 615af9f..e8a4d66 100644 --- a/src/main/java/com/ffii/tsms/modules/data/web/DashboardController.kt +++ b/src/main/java/com/ffii/tsms/modules/data/web/DashboardController.kt @@ -17,6 +17,7 @@ import com.ffii.core.response.RecordsRes import com.ffii.core.utils.CriteriaArgsBuilder import com.ffii.tsms.modules.data.service.* import com.ffii.tsms.modules.data.web.models.ExportFinancialSummaryByClientExcelRequest +import com.ffii.tsms.modules.data.web.models.ExportFinancialSummaryByProjectExcelRequest import org.springframework.core.io.ByteArrayResource import org.springframework.core.io.Resource import org.springframework.http.ResponseEntity @@ -450,4 +451,12 @@ class DashboardController( .header("filename", "Financial Summary for Client - " + LocalDate.now() + ".xlsx") .body(ByteArrayResource(reportResult)) } + + @PostMapping("/exportFinancialSummaryByProjectExcel") + fun exportFinancialSummaryByProjectExcel(@Valid @RequestBody request: ExportFinancialSummaryByProjectExcelRequest): ResponseEntity { + val reportResult: ByteArray = dashboardService.exportFinancialSummaryByProjectExcel(request.financialSummaryByProjects) + return ResponseEntity.ok() + .header("filename", "Financial Summary for Project - " + LocalDate.now() + ".xlsx") + .body(ByteArrayResource(reportResult)) + } } \ No newline at end of file diff --git a/src/main/java/com/ffii/tsms/modules/data/web/models/ExportDashboardExcelRequest.kt b/src/main/java/com/ffii/tsms/modules/data/web/models/ExportDashboardExcelRequest.kt index 54b71b6..bc45465 100644 --- a/src/main/java/com/ffii/tsms/modules/data/web/models/ExportDashboardExcelRequest.kt +++ b/src/main/java/com/ffii/tsms/modules/data/web/models/ExportDashboardExcelRequest.kt @@ -12,4 +12,19 @@ data class FinancialSummaryByClient ( data class ExportFinancialSummaryByClientExcelRequest ( val financialSummaryByClients: List +) + +data class FinancialSummaryByProject ( + val projectCode: String, + val projectName: String, + val customerName: String, + val subsidiaryName: String?, + val totalFee: Double, + val cumulativeExpenditure: Double, + val totalInvoiced: Double, + val totalReceived: Double, +) + +data class ExportFinancialSummaryByProjectExcelRequest ( + val financialSummaryByProjects: List ) \ No newline at end of file diff --git a/src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt b/src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt index 86a957c..a9a6b25 100644 --- a/src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt +++ b/src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt @@ -2985,25 +2985,22 @@ open class ReportService( grade.id )]?.sumOf { it.getValue("salary") } ?: 0.0 - cellStyle = normalFontWithBorderStyle.apply { - dataFormat = accountingStyle - } + cellStyle = normalFontWithBorderStyle + cellStyle.dataFormat = accountingStyle } } createCell(columnIndex++).apply { val lastCellLetter = CellReference.convertNumToColString(this.columnIndex - 1) cellFormula = "sum(B${this.rowIndex + 1}:${lastCellLetter}${this.rowIndex + 1})" - cellStyle = boldFontWithBorderStyle.apply { - dataFormat = accountingStyle - } + cellStyle = boldFontWithBorderStyle + cellStyle.dataFormat = accountingStyle } createCell(columnIndex).apply { setCellValue(totalSalary) - cellStyle = boldFontWithBorderStyle.apply { - dataFormat = accountingStyle - } + cellStyle = boldFontWithBorderStyle + cellStyle.dataFormat = accountingStyle } } } @@ -3021,9 +3018,8 @@ open class ReportService( createCell(columnIndex++).apply { val currentCellLetter = CellReference.convertNumToColString(this.columnIndex) cellFormula = "sum(${currentCellLetter}${startRow}:${currentCellLetter}${endRow})" - cellStyle = normalFontWithBorderStyle.apply { - dataFormat = accountingStyle - } + cellStyle = normalFontWithBorderStyle + cellStyle.dataFormat = accountingStyle } } diff --git a/src/main/resources/templates/report/[Dashboard] Financial Summary for client.xlsx b/src/main/resources/templates/report/[Dashboard] Financial Summary for client.xlsx index d2674ba..7eb2f65 100644 Binary files a/src/main/resources/templates/report/[Dashboard] Financial Summary for client.xlsx and b/src/main/resources/templates/report/[Dashboard] Financial Summary for client.xlsx differ