diff --git a/src/main/java/com/ffii/fpsms/modules/report/service/ReportService.kt b/src/main/java/com/ffii/fpsms/modules/report/service/ReportService.kt new file mode 100644 index 0000000..01387b7 --- /dev/null +++ b/src/main/java/com/ffii/fpsms/modules/report/service/ReportService.kt @@ -0,0 +1,60 @@ +package com.ffii.fpsms.modules.report.service + +import org.springframework.stereotype.Service +import net.sf.jasperreports.engine.* +import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource +import java.io.InputStream +import com.ffii.core.support.JdbcDao + +@Service +open class ReportService( + private val jdbcDao: JdbcDao, +) { + /** + * Queries the database for inventory data based on dates and optional item type. + */ + fun searchReport1(fromDate: String, toDate: String, itemType: String?): List> { + val args = mutableMapOf( + "fromDate" to fromDate, + "toDate" to toDate + ) + + val itemTypeSql = if (!itemType.isNullOrBlank()) { + args["itemType"] = "%$itemType%" + "AND it.type LIKE :itemType" + } else "" + + val sql = """ + SELECT + -- fake value for demo + 8.8 * iv.onHandQty as stockValue, + iv.onHandQty, + it.code as itemCode, + it.name as itemName, + uc.code as uom, + it.type, iv.status + FROM inventory iv + LEFT JOIN items it ON iv.itemId = it.id + LEFT JOIN uom_conversion uc ON iv.uomId = uc.id + WHERE iv.created >= :fromDate AND iv.created < :toDate + $itemTypeSql + """.trimIndent() + + return jdbcDao.queryForList(sql, args) + } + + /** + * Compiles and fills a Jasper Report, returning the PDF as a ByteArray. + */ + fun createPdfResponse(templatePath: String, params: Map, dataList: List>): ByteArray { + val stream = this::class.java.getResourceAsStream(templatePath) + ?: throw RuntimeException("Report template not found: $templatePath") + + val jasperReport = JasperCompileManager.compileReport(stream) + + val dataSource = JRBeanCollectionDataSource(dataList) + + val jasperPrint = JasperFillManager.fillReport(jasperReport, params, dataSource) + return JasperExportManager.exportReportToPdf(jasperPrint) + } +} \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/report/web/ReportController.kt b/src/main/java/com/ffii/fpsms/modules/report/web/ReportController.kt new file mode 100644 index 0000000..46e974e --- /dev/null +++ b/src/main/java/com/ffii/fpsms/modules/report/web/ReportController.kt @@ -0,0 +1,47 @@ +package com.ffii.fpsms.modules.report.web + +import net.sf.jasperreports.engine.* +import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource +import org.springframework.http.* +import org.springframework.web.bind.annotation.* +import java.io.InputStream +import com.ffii.fpsms.modules.report.service.ReportService + +@RestController +@RequestMapping("/report") +class ReportController( + private val reportService: ReportService, +) { + + @GetMapping("/print-report1") + fun generateReport1( + @RequestParam fromDate: String, + @RequestParam toDate: String, + //this is an exampe of optional param + @RequestParam(required = false) itemType: String? + ): ResponseEntity { + val parameters = mutableMapOf() + parameters["fromDate"] = fromDate + parameters["toDate"] = toDate + // you may put more params to show + parameters["param1"] = "param1Value" + parameters["param2"] = "param2Value" + + // Query the DB to get a list of data + val dbData = reportService.searchReport1(fromDate, toDate, itemType) + + val pdfBytes = reportService.createPdfResponse( + "/jasper/report1.jrxml", + parameters, + dbData + ) + + val headers = HttpHeaders().apply { + contentType = MediaType.APPLICATION_PDF + setContentDispositionFormData("attachment", "Report1.pdf") + set("filename", "Report1.pdf") + } + + return ResponseEntity(pdfBytes, headers, HttpStatus.OK) + } +} \ No newline at end of file diff --git a/src/main/resources/jasper/report1.jrxml b/src/main/resources/jasper/report1.jrxml new file mode 100644 index 0000000..bdba57f --- /dev/null +++ b/src/main/resources/jasper/report1.jrxml @@ -0,0 +1,292 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/jasper/report2.jrxml b/src/main/resources/jasper/report2.jrxml new file mode 100644 index 0000000..d509085 --- /dev/null +++ b/src/main/resources/jasper/report2.jrxml @@ -0,0 +1,484 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/jasper/report2Sub1.jrxml b/src/main/resources/jasper/report2Sub1.jrxml new file mode 100644 index 0000000..907dfa0 --- /dev/null +++ b/src/main/resources/jasper/report2Sub1.jrxml @@ -0,0 +1,179 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +