From 537280bb34b23114b0311a3425d229cf147f57d9 Mon Sep 17 00:00:00 2001 From: "kelvin.yau" Date: Fri, 12 Dec 2025 15:48:10 +0800 Subject: [PATCH] fg stock in label update --- .../jobOrder/service/JobOrderService.kt | 121 ++-- .../jobOrder/web/JobOrderController.kt | 15 +- .../web/model/ExportFGStockInLabelRequest.kt | 5 + .../web/model/PrintFGStockInLabelRequest.kt | 7 + .../FGStockInLabel.jrxml} | 0 .../resources/PickRecord/PickRecordPDF.jrxml | 660 +++++++++--------- 6 files changed, 400 insertions(+), 408 deletions(-) create mode 100644 src/main/java/com/ffii/fpsms/modules/jobOrder/web/model/ExportFGStockInLabelRequest.kt create mode 100644 src/main/java/com/ffii/fpsms/modules/jobOrder/web/model/PrintFGStockInLabelRequest.kt rename src/main/resources/{PickRecord/FinishedGoodPickRecordLabelPDF.jrxml => FGStockInLabel/FGStockInLabel.jrxml} (100%) diff --git a/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JobOrderService.kt b/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JobOrderService.kt index 1c9d236..87b541d 100644 --- a/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JobOrderService.kt +++ b/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JobOrderService.kt @@ -57,6 +57,12 @@ import java.io.IOException import com.ffii.fpsms.modules.jobOrder.entity.projections.JobOrderInfoWithTypeName import com.ffii.fpsms.modules.jobOrder.entity.projections.JobTypeResponse import com.ffii.fpsms.modules.stock.entity.InventoryRepository +import com.ffii.fpsms.modules.stock.entity.StockInLineRepository +import com.ffii.fpsms.modules.stock.service.QrContent +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json +import kotlin.math.exp + @Service open class JobOrderService( @@ -74,7 +80,8 @@ open class JobOrderService( val stockOutLineRepository: StockOutLIneRepository, private val printerService: PrinterService, val jobTypeRepository: JobTypeRepository, - val inventoryRepository: InventoryRepository + val inventoryRepository: InventoryRepository, + val stockInLineRepository: StockInLineRepository ) { open fun allJobOrdersByPage(request: SearchJobOrderInfoRequest): RecordsRes { @@ -620,81 +627,52 @@ open class JobOrderService( } } - //New Print Pick Record - //Print Pick Record - @Transactional - open fun NewPrintPickRecord(request: PrintPickRecordRequest){ - val printer = printerService.findById(request.printerId) ?: throw java.util.NoSuchElementException("No such printer") - println("New DEBUG: Printer found: ${printer.name}") - println("New DEBUG: Exporting pick record for pick order ID: ${request.pickOrderId}") - val pdf = exportPickRecord( - ExportPickRecordRequest( - pickOrderIds = request.pickOrderId - ) - ) - println("New DEBUG: PDF exported: ${pdf}") - val jasperPrint = pdf["report"] as JasperPrint - println("New DEBUG: JasperPrint: ${jasperPrint}") - val tempPdfFile = File.createTempFile("print_job_",".pdf") - println("New DEBUG: Temporary PDF file created: ${tempPdfFile.absolutePath}") - try{ - JasperExportManager.exportReportToPdfFile(jasperPrint,tempPdfFile.absolutePath) - println("New DEBUG: JasperPrint exported to PDF file: ${tempPdfFile.absolutePath}") - val printQty = if (request.printQty == null || request.printQty <= 0) 1 else request.printQty - println("New DEBUG: Print quantity: $printQty") - // Auto-detect orientation and set duplex mode accordingly - val duplexMode = if (CanonPrinterUtil.isLandscape(tempPdfFile)) { - CanonPrinterUtil.DuplexMode.DUPLEX_SHORT_EDGE // Landscape: flip on short edge - } else { - CanonPrinterUtil.DuplexMode.DUPLEX_LONG_EDGE // Portrait: flip on long edge - } - - println("New DEBUG: PDF orientation detected - Landscape: ${CanonPrinterUtil.isLandscape(tempPdfFile)}, Duplex mode: $duplexMode") - - printer.ip?.let { ip -> - printer.port?.let { port -> - CanonPrinterUtil.printPdfToCanon( - tempPdfFile, - ip, - port, - printQty, - duplexMode - ) - } - } - } finally { - //tempPdfFile.delete() - } - } - - //FG Pick Record Label + //FG Stock In Label @Throws(IOException::class) @Transactional - // Hardcoded Request - open fun exportFGPickRecordLabel(request: ExportPickRecordRequest): Map { - val FG_PICKRECORD_LABEL_PDF = "PickRecord/FinishedGoodPickRecordLabelPDF.jrxml" - val resource = ClassPathResource(FG_PICKRECORD_LABEL_PDF) + open fun exportFGStockInLabel(request: ExportFGStockInLabelRequest): Map { + val FGSTOCKINLABEL_PDF = "FGStockInLabel/FGStockInLabel.jrxml" + val resource = ClassPathResource(FGSTOCKINLABEL_PDF) if(!resource.exists()){ - throw FileNotFoundException("Report file not found: $FG_PICKRECORD_LABEL_PDF") + throw FileNotFoundException("Report file not found: $FGSTOCKINLABEL_PDF") } val inputStream = resource.inputStream val fgPickRecordLabel = JasperCompileManager.compileReport(inputStream) val params = mutableMapOf() - // Hardcoded for demo on 6/11/2025 - params["jobOrderCode"] = "JO-20251106-0001" - params["finishedGoodItemCode"] = "PP2061" - params["finishedGoodItemName"] = "炒芝麻" - params["finishedGoodLotNo"] = "LT-20251106-0006A" - params["productionQty"] = "25.0" - params["productionDate"] = "2025-11-06" - params["expiryDate"] = "2026-02-06" - params["uom"] = "一包一磅" - params["shortName"] = "包" - - // Hardcoded QR code for demo on 6/11/2025 - val qrCodeContent = "JO-20241201-001|FG-001|LOT-20241201-001" + //GET STOCK IN LINE FROM REQUEST + val stockInLineId = request.stockInLineId + ?: throw BadRequestException("stockInLineId is required") + val stockInLineInfo = stockInLineRepository.findStockInLineInfoByIdAndDeletedFalse(stockInLineId) + + //LINK TO JOB ORDER + val jobOrderId = stockInLineInfo.jobOrderId + ?: throw BadRequestException("StockInLine does not have an associated JobOrder") + val jobOrder = jobOrderRepository.findById(jobOrderId).orElseThrow() + + //HANDLE UOM + val uom = stockInLineInfo.uom + val uomDesc = uom?.udfudesc ?: "" + val uomShortDesc = uom?.udfShortDesc ?: "" + + //HANDLE DATES + val dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd") + val productionDate = stockInLineInfo.productionDate?.toLocalDate()?.format(dateFormatter) ?: "" + val expiryDate = stockInLineInfo.expiryDate?.format(dateFormatter) ?: "" + + params["jobOrderCode"] = jobOrder.code ?: "N/A" + params["finishedGoodItemCode"] = stockInLineInfo.itemNo ?: "N/A" + params["finishedGoodItemName"] = stockInLineInfo.itemName ?: "N/A" + params["finishedGoodLotNo"] = stockInLineInfo.lotNo ?: "N/A" + params["productionQty"] = stockInLineInfo.acceptedQty?.toString() ?: "0" + params["productionDate"] = productionDate + params["expiryDate"] = expiryDate + params["uom"] = uomDesc + params["shortName"] = uomShortDesc + + val qrContent = QrContent(stockInLineInfo.itemId, stockInLineId) + val qrCodeContent = Json.encodeToString(qrContent) val qrCodeImage = QrCodeUtil.generateQRCodeImage(qrCodeContent) params["qrCode"] = qrCodeImage @@ -709,12 +687,12 @@ open class JobOrderService( @Transactional - open fun printFGPickRecordLabel(request: PrintPickRecordRequest){ + open fun printFGStockInLabel(request: PrintFGStockInLabelRequest){ val printer = printerService.findById(request.printerId) ?: throw java.util.NoSuchElementException("No such printer") - val pdf = exportFGPickRecordLabel( - ExportPickRecordRequest( - pickOrderIds = request.pickOrderId + val pdf = exportFGStockInLabel( + ExportFGStockInLabelRequest( + stockInLineId = request.stockInLineId ) ) @@ -743,6 +721,7 @@ open class JobOrderService( //tempPdfFile.delete } } + open fun getAllJobTypes(): List { return jobTypeRepository.findAll().map { JobTypeResponse(it.id, it.name) } } diff --git a/src/main/java/com/ffii/fpsms/modules/jobOrder/web/JobOrderController.kt b/src/main/java/com/ffii/fpsms/modules/jobOrder/web/JobOrderController.kt index db1fda7..ab9e4e5 100644 --- a/src/main/java/com/ffii/fpsms/modules/jobOrder/web/JobOrderController.kt +++ b/src/main/java/com/ffii/fpsms/modules/jobOrder/web/JobOrderController.kt @@ -39,6 +39,8 @@ import org.springframework.web.bind.annotation.RequestParam import com.ffii.fpsms.modules.jobOrder.web.model.UpdateJoPickOrderHandledByRequest import com.ffii.fpsms.modules.jobOrder.entity.projections.JobOrderInfo import com.ffii.fpsms.modules.jobOrder.entity.projections.JobOrderInfoWithTypeName +import com.ffii.fpsms.modules.jobOrder.web.model.ExportFGStockInLabelRequest + @RestController @RequestMapping("/jo") class JobOrderController( @@ -198,25 +200,22 @@ fun recordSecondScanIssue( fun printPickRecord(@ModelAttribute request: PrintPickRecordRequest){ jobOrderService.printPickRecord(request) } - @GetMapping("/newPrint-PickRecord") - fun NewprintPickRecord(@ModelAttribute request: PrintPickRecordRequest){ - jobOrderService.NewPrintPickRecord(request) - } + @PostMapping("/FGPickRecordLabel") @Throws(UnsupportedEncodingException::class, NoSuchMessageException::class, ParseException::class, Exception::class) - fun exportFGPickRecordLabel(@Valid @RequestBody request: ExportPickRecordRequest, response: HttpServletResponse){ + fun exportFGStockInLabel(@Valid @RequestBody request: ExportFGStockInLabelRequest, response: HttpServletResponse){ response.characterEncoding = "utf-8" response.contentType = "application/pdf" val out: OutputStream = response.outputStream - val pdf = jobOrderService.exportFGPickRecordLabel(request) + val pdf = jobOrderService.exportFGStockInLabel(request) val jasperPrint = pdf["report"] as JasperPrint response.addHeader("filename", "${pdf["filename"]}.pdf") out.write(JasperExportManager.exportReportToPdf(jasperPrint)) } @GetMapping("/print-FGPickRecordLabel") - fun printFGPickRecordLabel(@ModelAttribute request: PrintPickRecordRequest){ - jobOrderService.printFGPickRecordLabel(request) + fun printStockInLabel(@ModelAttribute request: PrintFGStockInLabelRequest){ + jobOrderService.printFGStockInLabel(request) } diff --git a/src/main/java/com/ffii/fpsms/modules/jobOrder/web/model/ExportFGStockInLabelRequest.kt b/src/main/java/com/ffii/fpsms/modules/jobOrder/web/model/ExportFGStockInLabelRequest.kt new file mode 100644 index 0000000..840af54 --- /dev/null +++ b/src/main/java/com/ffii/fpsms/modules/jobOrder/web/model/ExportFGStockInLabelRequest.kt @@ -0,0 +1,5 @@ +package com.ffii.fpsms.modules.jobOrder.web.model + +data class ExportFGStockInLabelRequest ( + val stockInLineId: Long? = null +) \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/jobOrder/web/model/PrintFGStockInLabelRequest.kt b/src/main/java/com/ffii/fpsms/modules/jobOrder/web/model/PrintFGStockInLabelRequest.kt new file mode 100644 index 0000000..ccab637 --- /dev/null +++ b/src/main/java/com/ffii/fpsms/modules/jobOrder/web/model/PrintFGStockInLabelRequest.kt @@ -0,0 +1,7 @@ +package com.ffii.fpsms.modules.jobOrder.web.model + +data class PrintFGStockInLabelRequest( + val stockInLineId: Long? = null, + val printerId: Long, + val printQty: Int? = 1 +) \ No newline at end of file diff --git a/src/main/resources/PickRecord/FinishedGoodPickRecordLabelPDF.jrxml b/src/main/resources/FGStockInLabel/FGStockInLabel.jrxml similarity index 100% rename from src/main/resources/PickRecord/FinishedGoodPickRecordLabelPDF.jrxml rename to src/main/resources/FGStockInLabel/FGStockInLabel.jrxml diff --git a/src/main/resources/PickRecord/PickRecordPDF.jrxml b/src/main/resources/PickRecord/PickRecordPDF.jrxml index d0fb600..b0dc32b 100644 --- a/src/main/resources/PickRecord/PickRecordPDF.jrxml +++ b/src/main/resources/PickRecord/PickRecordPDF.jrxml @@ -1,332 +1,334 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - <band splitType="Stretch"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + <band height="49" splitType="Stretch"> + <staticText> + <reportElement x="223" y="0" width="108" height="23" uuid="a8b42d41-fd8e-4071-a6ac-d29ae8817d5a"> + <property name="com.jaspersoft.studio.unit.width" value="px"/> + <property name="com.jaspersoft.studio.unit.height" value="px"/> + </reportElement> + <textElement textAlignment="Center" verticalAlignment="Middle"> + <font fontName="微軟正黑體" size="16"/> + </textElement> + <text><![CDATA[板頭紙]]></text> + </staticText> + </band> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +