Parcourir la source

update "export financial status by proejct excel"

tags/Baseline_30082024_BACKEND_UAT
cyril.tsui il y a 1 an
Parent
révision
f82cb5f3ae
5 fichiers modifiés avec 247 ajouts et 34 suppressions
  1. +215
    -22
      src/main/java/com/ffii/tsms/modules/data/service/DashboardService.kt
  2. +9
    -0
      src/main/java/com/ffii/tsms/modules/data/web/DashboardController.kt
  3. +15
    -0
      src/main/java/com/ffii/tsms/modules/data/web/models/ExportDashboardExcelRequest.kt
  4. +8
    -12
      src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt
  5. BIN
      src/main/resources/templates/report/[Dashboard] Financial Summary for client.xlsx

+ 215
- 22
src/main/java/com/ffii/tsms/modules/data/service/DashboardService.kt Voir le fichier

@@ -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<String, Any>): List<Map<String, Any>> {
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<FinancialSummaryByProject>,
): 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<FinancialSummaryByProject>,
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)


+ 9
- 0
src/main/java/com/ffii/tsms/modules/data/web/DashboardController.kt Voir le fichier

@@ -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<Resource> {
val reportResult: ByteArray = dashboardService.exportFinancialSummaryByProjectExcel(request.financialSummaryByProjects)
return ResponseEntity.ok()
.header("filename", "Financial Summary for Project - " + LocalDate.now() + ".xlsx")
.body(ByteArrayResource(reportResult))
}
}

+ 15
- 0
src/main/java/com/ffii/tsms/modules/data/web/models/ExportDashboardExcelRequest.kt Voir le fichier

@@ -12,4 +12,19 @@ data class FinancialSummaryByClient (

data class ExportFinancialSummaryByClientExcelRequest (
val financialSummaryByClients: List<FinancialSummaryByClient>
)

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<FinancialSummaryByProject>
)

+ 8
- 12
src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt Voir le fichier

@@ -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
}
}



BIN
src/main/resources/templates/report/[Dashboard] Financial Summary for client.xlsx Voir le fichier


Chargement…
Annuler
Enregistrer