|
|
@@ -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.service.PrinterService |
|
|
import com.ffii.fpsms.modules.master.entity.ItemsRepository |
|
|
import com.ffii.fpsms.modules.master.entity.ItemsRepository |
|
|
import com.ffii.fpsms.modules.deliveryOrder.entity.DeliveryOrderPickOrder |
|
|
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.PrintDeliveryNoteRequest |
|
|
import com.ffii.fpsms.modules.deliveryOrder.web.models.ExportDeliveryNoteRequest |
|
|
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.PrintDNLabelsRequest |
|
|
import com.ffii.fpsms.modules.deliveryOrder.web.models.ExportDNLabelsRequest |
|
|
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.ConcurrentHashMap |
|
|
import java.util.concurrent.ConcurrentLinkedQueue |
|
|
import java.util.concurrent.ConcurrentLinkedQueue |
|
|
import java.util.concurrent.CountDownLatch |
|
|
import java.util.concurrent.CountDownLatch |
|
|
@@ -2531,6 +2533,27 @@ return MessageResponse( |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private fun workbenchCartonLabelParams( |
|
|
|
|
|
ctx: WorkbenchPrintContext, |
|
|
|
|
|
cartonLabelInfo: MutableList<DeliveryOrderInfo>, |
|
|
|
|
|
): MutableMap<String, Any> { |
|
|
|
|
|
val params = mutableMapOf<String, Any>() |
|
|
|
|
|
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<String, Any> { |
|
|
private fun exportDNLabelsWorkbench(request: ExportDNLabelsRequest): Map<String, Any> { |
|
|
val DNLABELS_PDF = "DeliveryNote/DeliveryNoteCartonLabelsPDF.jrxml" |
|
|
val DNLABELS_PDF = "DeliveryNote/DeliveryNoteCartonLabelsPDF.jrxml" |
|
|
val resource = ClassPathResource(DNLABELS_PDF) |
|
|
val resource = ClassPathResource(DNLABELS_PDF) |
|
|
@@ -2548,23 +2571,9 @@ return MessageResponse( |
|
|
throw NoSuchElementException("Delivery orders not found for IDs: ${ctx.deliveryOrderIds}") |
|
|
throw NoSuchElementException("Delivery orders not found for IDs: ${ctx.deliveryOrderIds}") |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
val params = mutableMapOf<String, Any>() |
|
|
|
|
|
|
|
|
val params = workbenchCartonLabelParams(ctx, cartonLabelInfo) |
|
|
val fields = mutableListOf<MutableMap<String, Any>>() |
|
|
val fields = mutableListOf<MutableMap<String, Any>>() |
|
|
|
|
|
|
|
|
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) { |
|
|
for (cartonNumber in 1..request.numOfCarton) { |
|
|
fields.add( |
|
|
fields.add( |
|
|
mutableMapOf( |
|
|
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<String, Any> { |
|
|
|
|
|
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<MutableMap<String, Any>>() |
|
|
|
|
|
|
|
|
|
|
|
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) { |
|
|
private fun updateWorkbenchCartonQty(deliveryOrderPickOrderId: Long, cartonQty: Int) { |
|
|
if (cartonQty <= 0) return |
|
|
if (cartonQty <= 0) return |
|
|
val workbenchHeader = deliveryOrderPickOrderRepository.findById(deliveryOrderPickOrderId).orElse(null) ?: return |
|
|
val workbenchHeader = deliveryOrderPickOrderRepository.findById(deliveryOrderPickOrderId).orElse(null) ?: return |
|
|
workbenchHeader.cartonQty = cartonQty |
|
|
workbenchHeader.cartonQty = cartonQty |
|
|
deliveryOrderPickOrderRepository.save(workbenchHeader) |
|
|
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() |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |