ソースを参照

add excel report

tags/Baseline_30082024_BACKEND_UAT
cyril.tsui 1年前
コミット
311f4d7e78
15個のファイルの変更157行の追加13行の削除
  1. +15
    -13
      src/main/java/com/ffii/tsms/modules/claim/service/ClaimService.kt
  2. +6
    -0
      src/main/java/com/ffii/tsms/modules/claim/web/ClaimController.kt
  3. +97
    -0
      src/main/java/com/ffii/tsms/modules/common/service/ExcelReportService.kt
  4. +34
    -0
      src/main/java/com/ffii/tsms/modules/report/web/ReportController.kt
  5. +5
    -0
      src/main/java/com/ffii/tsms/modules/report/web/model/ReportRequest.kt
  6. バイナリ
      src/main/resources/templates/report/AR01_Late Start Report v01.xlsx
  7. バイナリ
      src/main/resources/templates/report/AR02_Delay Report v02.xlsx
  8. バイナリ
      src/main/resources/templates/report/AR03_Resource Overconsumption.xlsx
  9. バイナリ
      src/main/resources/templates/report/AR04_Cost and Expense Report v02.xlsx
  10. バイナリ
      src/main/resources/templates/report/AR05_Project Completion Report.xlsx
  11. バイナリ
      src/main/resources/templates/report/AR06_Project Completion Report with Outstanding Accounts Receivable v02.xlsx
  12. バイナリ
      src/main/resources/templates/report/AR07_Project P&L Report v02.xlsx
  13. バイナリ
      src/main/resources/templates/report/AR08_Monthly Work Hours Analysis Report.xlsx
  14. バイナリ
      src/main/resources/templates/report/EX01_Financial Status Report.xlsx
  15. バイナリ
      src/main/resources/templates/report/EX02_Project Cash Flow Report.xlsx

+ 15
- 13
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<Claim, Long, ClaimRepository>(jdbcDao, claimRepository) {
) : AbstractBaseEntityService<Claim, Long, ClaimRepository>(jdbcDao, claimRepository) {
open fun allClaims(): List<Map<String, Any>> {
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())
}



+ 6
- 0
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<Map<String, Any>> {
return claimService.allClaims()
}

@PostMapping("/save")
fun saveClaim(
@RequestParam(required = false) id: Long?,


+ 97
- 0
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
}
}

+ 34
- 0
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<Resource> {

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

+ 5
- 0
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
)

バイナリ
src/main/resources/templates/report/AR01_Late Start Report v01.xlsx ファイルの表示


バイナリ
src/main/resources/templates/report/AR02_Delay Report v02.xlsx ファイルの表示


バイナリ
src/main/resources/templates/report/AR03_Resource Overconsumption.xlsx ファイルの表示


バイナリ
src/main/resources/templates/report/AR04_Cost and Expense Report v02.xlsx ファイルの表示


バイナリ
src/main/resources/templates/report/AR05_Project Completion Report.xlsx ファイルの表示


バイナリ
src/main/resources/templates/report/AR06_Project Completion Report with Outstanding Accounts Receivable v02.xlsx ファイルの表示


バイナリ
src/main/resources/templates/report/AR07_Project P&L Report v02.xlsx ファイルの表示


バイナリ
src/main/resources/templates/report/AR08_Monthly Work Hours Analysis Report.xlsx ファイルの表示


バイナリ
src/main/resources/templates/report/EX01_Financial Status Report.xlsx ファイルの表示


バイナリ
src/main/resources/templates/report/EX02_Project Cash Flow Report.xlsx ファイルの表示


読み込み中…
キャンセル
保存