@@ -36,20 +36,22 @@ open class ClaimService( | |||||
private val fileRepository: FileRepository, | private val fileRepository: FileRepository, | ||||
private val userRepository: UserRepository, | private val userRepository: UserRepository, | ||||
private val staffsService: StaffsService, | private val staffsService: StaffsService, | ||||
) : AbstractBaseEntityService<Claim, Long, ClaimRepository>(jdbcDao, claimRepository) { | |||||
) : AbstractBaseEntityService<Claim, Long, ClaimRepository>(jdbcDao, claimRepository) { | |||||
open fun allClaims(): List<Map<String, Any>> { | 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()) | return jdbcDao.queryForList(sql.toString()) | ||||
} | } | ||||
@@ -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.ServletRequestBindingException | ||||
import org.springframework.web.bind.annotation.GetMapping | import org.springframework.web.bind.annotation.GetMapping | ||||
import org.springframework.web.bind.annotation.ModelAttribute | 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.PostMapping | ||||
import org.springframework.web.bind.annotation.RequestBody | import org.springframework.web.bind.annotation.RequestBody | ||||
import org.springframework.web.bind.annotation.RequestMapping | import org.springframework.web.bind.annotation.RequestMapping | ||||
@@ -34,6 +35,11 @@ class ClaimController(private val claimService: ClaimService) { | |||||
return claimService.allClaims() | return claimService.allClaims() | ||||
} | } | ||||
@GetMapping("/{id}") | |||||
fun findClaim(@PathVariable id: Long?): List<Map<String, Any>> { | |||||
return claimService.allClaims() | |||||
} | |||||
@PostMapping("/save") | @PostMapping("/save") | ||||
fun saveClaim( | fun saveClaim( | ||||
@RequestParam(required = false) id: Long?, | @RequestParam(required = false) id: Long?, | ||||
@@ -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 | |||||
} | |||||
} |
@@ -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)) | |||||
} | |||||
} |
@@ -0,0 +1,5 @@ | |||||
package com.ffii.tsms.modules.report.web.model | |||||
data class EX02ProjectCashFlowReportRequest ( | |||||
val projectId: Long | |||||
) |