From fcee2542211cd1b59fa9c6d5dfa394cc9a8b1b7c Mon Sep 17 00:00:00 2001 From: "CANCERYS\\kw093" Date: Tue, 28 Apr 2026 11:19:46 +0800 Subject: [PATCH] fix do reprint and jo suggestion list --- .../service/DoWorkbenchMainService.kt | 130 ++++++++++++++++-- .../web/DoWorkbenchController.kt | 5 +- .../service/JoWorkbenchMainService.kt | 6 +- 3 files changed, 122 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoWorkbenchMainService.kt b/src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoWorkbenchMainService.kt index 0a12eb1..6bba72d 100644 --- a/src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoWorkbenchMainService.kt +++ b/src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoWorkbenchMainService.kt @@ -70,10 +70,12 @@ import com.ffii.fpsms.modules.master.print.A4PrintDriverRegistry import com.ffii.fpsms.modules.master.service.PrinterService import com.ffii.fpsms.modules.master.entity.ItemsRepository import com.ffii.fpsms.modules.deliveryOrder.entity.DeliveryOrderPickOrder +import com.ffii.fpsms.modules.deliveryOrder.entity.models.DeliveryOrderInfo import com.ffii.fpsms.modules.deliveryOrder.web.models.PrintDeliveryNoteRequest import com.ffii.fpsms.modules.deliveryOrder.web.models.ExportDeliveryNoteRequest import com.ffii.fpsms.modules.deliveryOrder.web.models.PrintDNLabelsRequest import com.ffii.fpsms.modules.deliveryOrder.web.models.ExportDNLabelsRequest +import com.ffii.fpsms.modules.deliveryOrder.web.models.PrintDNLabelsReprintRequest import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentLinkedQueue import java.util.concurrent.CountDownLatch @@ -2531,6 +2533,27 @@ return MessageResponse( } } + private fun workbenchCartonLabelParams( + ctx: WorkbenchPrintContext, + cartonLabelInfo: MutableList, + ): MutableMap { + val params = mutableMapOf() + params["shopPurchaseOrderNo"] = if (ctx.deliveryOrderIds.size > 1) { + "請查閲送貨單(採購單共${ctx.deliveryOrderIds.size}張)" + } else { + cartonLabelInfo[0].code + } + params["deliveryNoteCode"] = ctx.header.deliveryNoteCode ?: "" + params["shopAddress"] = cartonLabelInfo[0].shopAddress ?: "" + val rawShopLabel = ctx.header.shopName ?: cartonLabelInfo[0].shopName ?: "" + val parsedShopLabel = deliveryOrderService.parseShopLabelForCartonLabel(rawShopLabel) + params["shopCode"] = parsedShopLabel.shopCode + params["shopCodeAbbr"] = parsedShopLabel.shopCodeAbbr + params["shopName"] = parsedShopLabel.shopNameForLabel + params["truckNo"] = ctx.header.truckLanceCode ?: "" + return params + } + private fun exportDNLabelsWorkbench(request: ExportDNLabelsRequest): Map { val DNLABELS_PDF = "DeliveryNote/DeliveryNoteCartonLabelsPDF.jrxml" val resource = ClassPathResource(DNLABELS_PDF) @@ -2548,23 +2571,9 @@ return MessageResponse( throw NoSuchElementException("Delivery orders not found for IDs: ${ctx.deliveryOrderIds}") } - val params = mutableMapOf() + val params = workbenchCartonLabelParams(ctx, cartonLabelInfo) val fields = mutableListOf>() - params["shopPurchaseOrderNo"] = if (ctx.deliveryOrderIds.size > 1) { - "請查閲送貨單(採購單共${ctx.deliveryOrderIds.size}張)" - } else { - cartonLabelInfo[0].code - } - params["deliveryNoteCode"] = ctx.header.deliveryNoteCode ?: "" - params["shopAddress"] = cartonLabelInfo[0].shopAddress ?: "" - val rawShopLabel = ctx.header.shopName ?: cartonLabelInfo[0].shopName ?: "" - val parsedShopLabel = deliveryOrderService.parseShopLabelForCartonLabel(rawShopLabel) - params["shopCode"] = parsedShopLabel.shopCode - params["shopCodeAbbr"] = parsedShopLabel.shopCodeAbbr - params["shopName"] = parsedShopLabel.shopNameForLabel - params["truckNo"] = ctx.header.truckLanceCode ?: "" - for (cartonNumber in 1..request.numOfCarton) { fields.add( mutableMapOf( @@ -2580,11 +2589,102 @@ return MessageResponse( ) } + private fun validateWorkbenchCartonReprintRange( + fromCarton: Int, + toCarton: Int, + totalCartonsOnShipment: Int, + ) { + require(totalCartonsOnShipment >= 1) { + "totalCartonsOnShipment must be at least 1" + } + require(fromCarton >= 1) { + "fromCarton must be at least 1" + } + require(toCarton >= fromCarton) { + "toCarton must be greater than or equal to fromCarton" + } + require(toCarton <= totalCartonsOnShipment) { + "toCarton must be less than or equal to totalCartonsOnShipment" + } + } + + /** + * Carton label reprint for workbench: [request.doPickOrderId] is [delivery_order_pick_order.id], + * same as [getWorkbenchPrintContext]. Legacy [DeliveryOrderService.printDNLabelsReprint] expects + * [do_pick_order_record.recordId] and must not be used here. + */ + private fun exportDNLabelsReprintWorkbench(request: PrintDNLabelsReprintRequest): Map { + validateWorkbenchCartonReprintRange( + fromCarton = request.fromCarton, + toCarton = request.toCarton, + totalCartonsOnShipment = request.totalCartonsOnShipment, + ) + + val DNLABELS_PDF = "DeliveryNote/DeliveryNoteCartonLabelsPDF.jrxml" + val resource = ClassPathResource(DNLABELS_PDF) + if (!resource.exists()) { + throw FileNotFoundException("Label file not found: $DNLABELS_PDF") + } + + val ctx = getWorkbenchPrintContext(request.doPickOrderId) + val inputStream = resource.inputStream + val cartonLabel = JasperCompileManager.compileReport(inputStream) + val cartonLabelInfo = ctx.deliveryOrderIds.flatMap { deliveryOrderId -> + deliveryOrderRepository.findDeliveryOrderInfoById(deliveryOrderId) + }.toMutableList() + if (cartonLabelInfo.isEmpty()) { + throw NoSuchElementException("Delivery orders not found for IDs: ${ctx.deliveryOrderIds}") + } + + val params = workbenchCartonLabelParams(ctx, cartonLabelInfo) + val fields = mutableListOf>() + + for (cartonNumber in request.fromCarton..request.toCarton) { + fields.add( + mutableMapOf( + "cartonIndex" to cartonNumber, + "cartonTotal" to request.totalCartonsOnShipment, + ), + ) + } + + return mapOf( + "report" to PdfUtils.fillReport(cartonLabel, fields, params), + "filename" to "${cartonLabelInfo[0].code}_carton_labels_reprint_${request.fromCarton}-${request.toCarton}", + ) + } + private fun updateWorkbenchCartonQty(deliveryOrderPickOrderId: Long, cartonQty: Int) { if (cartonQty <= 0) return val workbenchHeader = deliveryOrderPickOrderRepository.findById(deliveryOrderPickOrderId).orElse(null) ?: return workbenchHeader.cartonQty = cartonQty deliveryOrderPickOrderRepository.save(workbenchHeader) } + @Transactional + open fun printDNLabelsReprint(request: PrintDNLabelsReprintRequest) { + val printer = + printerService.findById(request.printerId) ?: throw java.util.NoSuchElementException("No such printer") + val pdf = exportDNLabelsReprintWorkbench(request) + val jasperPrint = pdf["report"] as JasperPrint + val tempPdfFile = File.createTempFile("print_job_", ".pdf") + 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, + printer.dpi, + ) + } + } + } finally { + // tempPdfFile.delete() + } + } } diff --git a/src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/DoWorkbenchController.kt b/src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/DoWorkbenchController.kt index 4672629..3a2d8a4 100644 --- a/src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/DoWorkbenchController.kt +++ b/src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/DoWorkbenchController.kt @@ -207,7 +207,10 @@ class DoWorkbenchController( fun printWorkbenchDNLabels(@ModelAttribute request: PrintDNLabelsRequest) { doWorkbenchMainService.printDNLabelsWorkbench(request) } - + @GetMapping("/print-DNLabels-reprint") + fun printWorkbenchDNLabelsReprint(@ModelAttribute request: PrintDNLabelsReprintRequest) { + doWorkbenchMainService.printDNLabelsReprint(request) + } @GetMapping("/truck-routing-summary/store-options") fun getWorkbenchTruckRoutingStoreOptions(): List> = workbenchTruckRoutingSummaryService.getStoreOptions() diff --git a/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JoWorkbenchMainService.kt b/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JoWorkbenchMainService.kt index cde8ee4..69eebf7 100644 --- a/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JoWorkbenchMainService.kt +++ b/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JoWorkbenchMainService.kt @@ -51,8 +51,8 @@ open class JoWorkbenchMainService( ) { // Keep aligned with SuggestedPickLotWorkbenchService default excludes for diagnosis logs. private val workbenchDefaultExcludeWarehouseCodes: Set = setOf( - "2F-W202-01-00", - "2F-W200-#A-00", + //"2F-W202-01-00", + //"2F-W200-#A-00", ) private fun debugPrintSuggestionNullReasons(pickOrderId: Long) { @@ -522,7 +522,7 @@ open class JoWorkbenchMainService( suggestedPickLotWorkbenchService.primeNextSingleLotSuggestionsForPickOrder( pickOrderId = pickOrderId, storeId = null, - excludeWarehouseCodes = null, + excludeWarehouseCodes = workbenchDefaultExcludeWarehouseCodes.toList() ) stockOutLineWorkbenchService.ensureStockOutLinesForPickOrderNoHold(pickOrderId, userId) val splAfter = loadSplDebugRowsByPol(pickOrderId)