From 97e8ea972ef09bb680bc9fc38961d1a962556423 Mon Sep 17 00:00:00 2001 From: "kelvin.yau" Date: Mon, 29 Sep 2025 19:45:42 +0800 Subject: [PATCH] update --- .../com/ffii/core/utils/ZebraPrinterUtil.kt | 35 +++++++++++++------ .../service/DeliveryOrderService.kt | 25 ++++++------- .../web/DeliveryOrderController.kt | 7 ++-- .../stock/entity/projection/InventoryInfo.kt | 12 ++++--- 4 files changed, 48 insertions(+), 31 deletions(-) diff --git a/src/main/java/com/ffii/core/utils/ZebraPrinterUtil.kt b/src/main/java/com/ffii/core/utils/ZebraPrinterUtil.kt index ea78295..8d72bc1 100644 --- a/src/main/java/com/ffii/core/utils/ZebraPrinterUtil.kt +++ b/src/main/java/com/ffii/core/utils/ZebraPrinterUtil.kt @@ -35,7 +35,6 @@ open class ZebraPrinterUtil { * @param printDirection Valid values: N (Normal), R (Rotated 90), I (Inverted 180), B (Bottom-up 270) * @throws Exception if there is an error during file processing or printing. */ - @JvmStatic fun printPdfToZebra(pdfFile: File, printerIp: String, printerPort: Int, printQty: Int? = 1, printDirection: PrintDirection = PrintDirection.NORMAL) { // Check if the file exists and is readable @@ -47,22 +46,36 @@ open class ZebraPrinterUtil { // 1. Load the PDF document PDDocument.load(pdfFile).use { document -> val renderer = PDFRenderer(document) + val totalPages = document.numberOfPages - // 2. Render the first page of the PDF as a monochrome image - // The '300 / 72f' scales the image to 300 DPI. - val image = renderer.renderImage(0, 300 / 72f, ImageType.BINARY) + println("DEBUG: PDF has $totalPages pages") - // 3. Convert the image to a ZPL format string - val zplCommand = convertImageToZpl(image, printDirection) + // Print each page for the specified quantity + repeat(printQty ?: 1) { copyIndex -> + println("DEBUG: Printing copy ${copyIndex + 1} of ${printQty ?: 1}") - // 4. Send the ZPL command to the printer via a network socket - val printData = zplCommand.toByteArray() - Socket(printerIp, printerPort).use { socket -> - val os: OutputStream = socket.getOutputStream() - repeat(printQty ?: 1) { index -> + // Iterate through all pages in the PDF + for (pageIndex in 0 until totalPages) { + println("DEBUG: Processing page ${pageIndex + 1} of $totalPages") + + // 2. Render each page of the PDF as a monochrome image + val image = renderer.renderImage(pageIndex, 300 / 72f, ImageType.BINARY) + + // 3. Convert the image to a ZPL format string + val zplCommand = convertImageToZpl(image, printDirection) + + // 4. Send each page as a separate print job + Socket(printerIp, printerPort).use { socket -> + val os: OutputStream = socket.getOutputStream() + val printData = zplCommand.toByteArray() os.write(printData) os.flush() + println("DEBUG: Page ${pageIndex + 1} sent to printer") } + + // Small delay between pages to ensure printer can process each page + Thread.sleep(100) + } } } } catch (e: Exception) { diff --git a/src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DeliveryOrderService.kt b/src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DeliveryOrderService.kt index 6f2b511..7a6cee8 100644 --- a/src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DeliveryOrderService.kt +++ b/src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DeliveryOrderService.kt @@ -695,7 +695,7 @@ open class DeliveryOrderService( //Print Delivery Note @Transactional open fun printDeliveryNote(request: PrintDeliveryNoteRequest){ - //val printer = printerService.findById(request.printerId) ?: throw java.util.NoSuchElementException("No such printer") + val printer = printerService.findById(request.printerId) ?: throw java.util.NoSuchElementException("No such printer") val pdf = exportDeliveryNote( ExportDeliveryNoteRequest( @@ -713,12 +713,12 @@ open class DeliveryOrderService( try{ JasperExportManager.exportReportToPdfFile(jasperPrint,tempPdfFile.absolutePath) - // val printQty = if (request.printQty == null || request.printQty <= 0) 1 else request.printQty - // printer.ip?.let { ip -> printer.port?.let { port -> - // ZebraPrinterUtil.printPdfToZebra(tempPdfFile, ip, port, printQty, ZebraPrinterUtil.PrintDirection.ROTATED) - // }} + val printQty = if (request.printQty == null || request.printQty <= 0) 1 else request.printQty + printer.ip?.let { ip -> printer.port?.let { port -> + ZebraPrinterUtil.printPdfToZebra(tempPdfFile, ip, port, printQty, ZebraPrinterUtil.PrintDirection.ROTATED) + }} } finally { - // tempPdfFile.delete() + //tempPdfFile.delete() } } @@ -754,14 +754,15 @@ open class DeliveryOrderService( "filename" to "${cartonLabelInfo[0].code}_carton_labels" ) - } + + //Print Carton Labels @Transactional open fun printDNLabels(request: PrintDNLabelsRequest){ - //val printer = printerService.findById(request.printerId) ?: throw java.util.NoSuchElementException("No such printer") + val printer = printerService.findById(request.printerId) ?: throw java.util.NoSuchElementException("No such printer") val pdf = exportDNLabels( ExportDNLabelsRequest( @@ -778,10 +779,10 @@ open class DeliveryOrderService( JasperExportManager.exportReportToPdfFile(jasperPrint,tempPdfFile.absolutePath) - //val printQty = if (request.printQty == null || request.printQty <= 0) 1 else request.printQty - //printer.ip?.let { ip -> printer.port?.let { port -> - // ZebraPrinterUtil.printPdfToZebra(tempPdfFile, ip, port, printQty, ZebraPrinterUtil.PrintDirection.ROTATED) - //}} + val printQty = if (request.printQty == null || request.printQty <= 0) 1 else request.printQty + printer.ip?.let { ip -> printer.port?.let { port -> + ZebraPrinterUtil.printPdfToZebra(tempPdfFile, ip, port, printQty, ZebraPrinterUtil.PrintDirection.ROTATED) + }} println("Test PDF saved to: ${tempPdfFile.absolutePath}") diff --git a/src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/DeliveryOrderController.kt b/src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/DeliveryOrderController.kt index 8ec75da..2eb7873 100644 --- a/src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/DeliveryOrderController.kt +++ b/src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/DeliveryOrderController.kt @@ -21,6 +21,7 @@ import com.ffii.fpsms.modules.deliveryOrder.web.models.PrintDNLabelsRequest import com.ffii.fpsms.modules.deliveryOrder.web.models.PrintDeliveryNoteRequest import com.ffii.fpsms.modules.deliveryOrder.web.models.ReleaseDoRequest import com.ffii.fpsms.modules.master.web.models.MessageResponse +import com.ffii.fpsms.modules.stock.web.model.PrintQrCodeForSilRequest import jakarta.servlet.http.HttpServletResponse import jakarta.validation.Valid import net.sf.jasperreports.engine.JasperExportManager @@ -195,8 +196,8 @@ class DeliveryOrderController( out.write(JasperExportManager.exportReportToPdf(jasperPrint)) } - @GetMapping("print-DN") - fun printDN(@RequestBody request: PrintDeliveryNoteRequest) { + @GetMapping("/print-DN") + fun printDN(@ModelAttribute request: PrintDeliveryNoteRequest) { deliveryOrderService.printDeliveryNote(request) } @@ -213,7 +214,7 @@ class DeliveryOrderController( } @GetMapping("print-DNLabels") - fun printDN(@RequestBody request: PrintDNLabelsRequest) { + fun printDN(@ModelAttribute request: PrintDNLabelsRequest) { deliveryOrderService.printDNLabels(request) } } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/InventoryInfo.kt b/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/InventoryInfo.kt index ceca671..39ed573 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/InventoryInfo.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/InventoryInfo.kt @@ -13,30 +13,32 @@ interface InventoryInfo{ val itemName: String? @get:Value("#{target.item.type}") val itemType: String? -// @get:Value("#{target.qty / (target.item.itemUoms.^[stockUnit == true && deleted == false]?.ratioN / target.item.itemUoms.^[stockUnit == true && deleted == false]?.ratioD)}") + // @get:Value("#{target.qty / (target.item.itemUoms.^[stockUnit == true && deleted == false]?.ratioN / target.item.itemUoms.^[stockUnit == true && deleted == false]?.ratioD)}") // @get:Value("#{target.onHandQty / (target.item.itemUoms.^[stockUnit == true && deleted == false]?.ratioN / target.item.itemUoms.^[stockUnit == true && deleted == false]?.ratioD)}") @get:Value("#{target.onHandQty}") val onHandQty: BigDecimal? -// @get:Value("#{target.onHoldQty / (target.item.itemUoms.^[stockUnit == true && deleted == false]?.ratioN / target.item.itemUoms.^[stockUnit == true && deleted == false]?.ratioD)}") + // @get:Value("#{target.onHoldQty / (target.item.itemUoms.^[stockUnit == true && deleted == false]?.ratioN / target.item.itemUoms.^[stockUnit == true && deleted == false]?.ratioD)}") @get:Value("#{target.onHoldQty}") val onHoldQty: BigDecimal? -// @get:Value("#{target.unavailableQty / (target.item.itemUoms.^[stockUnit == true && deleted == false]?.ratioN / target.item.itemUoms.^[stockUnit == true && deleted == false]?.ratioD)}") + // @get:Value("#{target.unavailableQty / (target.item.itemUoms.^[stockUnit == true && deleted == false]?.ratioN / target.item.itemUoms.^[stockUnit == true && deleted == false]?.ratioD)}") @get:Value("#{target.unavailableQty}") val unavailableQty: BigDecimal? -// @get:Value("#{(target.onHandQty - target.onHoldQty - target.unavailableQty) / (target.item.itemUoms.^[stockUnit == true && deleted == false]?.ratioN / target.item.itemUoms.^[stockUnit == true && deleted == false]?.ratioD)}") + // @get:Value("#{(target.onHandQty - target.onHoldQty - target.unavailableQty) / (target.item.itemUoms.^[stockUnit == true && deleted == false]?.ratioN / target.item.itemUoms.^[stockUnit == true && deleted == false]?.ratioD)}") @get:Value("#{(target.onHandQty - target.onHoldQty - target.unavailableQty)}") val availableQty: BigDecimal? @get:Value("#{target.item.itemUoms.^[stockUnit == true && deleted == false]?.uom.code}") val uomCode: String? @get:Value("#{target.item.itemUoms.^[stockUnit == true && deleted == false]?.uom?.udfudesc}") val uomUdfudesc: String? + @get:Value("#{target.item.itemUoms.^[stockUnit == true && deleted == false]?.uom?.udfShortDesc}") + val uomShortDesc: String? // @get:Value("#{target.qty * target.uom.gramPerSmallestUnit}") // val germPerSmallestUnit: BigDecimal? @get:Value("#{(target.onHandQty - target.onHoldQty - target.unavailableQty)}") val qtyPerSmallestUnit: BigDecimal? @get:Value("#{target.item.itemUoms.^[baseUnit == true && deleted == false]?.uom?.udfudesc}") val baseUom: String? -// @get:Value("#{target.qty * (target.uom.unit4 != '' ? target.uom.unit4Qty " + + // @get:Value("#{target.qty * (target.uom.unit4 != '' ? target.uom.unit4Qty " + // ": target.uom.unit3 != '' ? target.uom.unit3Qty " + // ": target.uom.unit2 != '' ? target.uom.unit2Qty " + // ": target.uom.unit1Qty)}")