Kaynağa Gözat

Reprint Label 補印

stable1
kelvin.yau 2 hafta önce
ebeveyn
işleme
cab893b790
6 değiştirilmiş dosya ile 221 ekleme ve 53 silme
  1. +160
    -51
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DeliveryOrderService.kt
  2. +23
    -0
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/DeliveryOrderController.kt
  3. +6
    -0
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/models/DnCartonLabelSheetRow.kt
  4. +13
    -0
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/models/ExportDNLabelsReprintRequest.kt
  5. +15
    -0
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/models/PrintDNLabelsReprintRequest.kt
  6. +4
    -2
      src/main/resources/DeliveryNote/DeliveryNoteCartonLabelsPDF.jrxml

+ 160
- 51
src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DeliveryOrderService.kt Dosyayı Görüntüle

@@ -63,7 +63,10 @@ import com.ffii.fpsms.modules.deliveryOrder.entity.DoPickOrderLineRepository
import com.ffii.fpsms.modules.deliveryOrder.entity.DoPickOrderRecordRepository
import com.ffii.fpsms.modules.deliveryOrder.entity.DoPickOrderRepository
import com.ffii.fpsms.modules.deliveryOrder.web.models.ExportDNLabelsRequest
import com.ffii.fpsms.modules.deliveryOrder.web.models.ExportDNLabelsReprintRequest
import com.ffii.fpsms.modules.deliveryOrder.web.models.DnCartonLabelSheetRow
import com.ffii.fpsms.modules.deliveryOrder.web.models.PrintDNLabelsRequest
import com.ffii.fpsms.modules.deliveryOrder.web.models.PrintDNLabelsReprintRequest
import com.ffii.fpsms.modules.purchaseOrder.entity.PurchaseOrderRepository
import com.ffii.fpsms.modules.stock.entity.InventoryLotRepository
import com.ffii.fpsms.modules.stock.service.InventoryLotService
@@ -1444,62 +1447,36 @@ open class DeliveryOrderService(

//Carton Labels
open fun exportDNLabels(request: ExportDNLabelsRequest): Map<String, Any> {
val DNLABELS_PDF = "DeliveryNote/DeliveryNoteCartonLabelsPDF.jrxml"
val resource = ClassPathResource(DNLABELS_PDF)
if (!resource.exists()) {
throw FileNotFoundException("Label file not found: $DNLABELS_PDF")
}

val doPickOrderRecord = doPickOrderRecordRepository.findById(request.doPickOrderId).orElseThrow {
NoSuchElementException("DoPickOrderRecord not found with ID: ${request.doPickOrderId}")
}

val doPickOrderLineRecords = doPickOrderLineRecordRepository.findByDoPickOrderId(doPickOrderRecord.recordId)

val deliveryOrderIds = doPickOrderLineRecords.mapNotNull { it.doOrderId }.distinct()
if (deliveryOrderIds.isEmpty()) {
throw IllegalStateException("DoPickOrderRecord ${request.doPickOrderId} has no associated delivery orders")
}

val inputStream = resource.inputStream
val cartonLabel = JasperCompileManager.compileReport(inputStream)
val cartonLabelInfo = deliveryOrderIds.flatMap { deliveryOrderId ->
deliveryOrderRepository.findDeliveryOrderInfoById(deliveryOrderId)
}.toMutableList()

val params = mutableMapOf<String, Any>()
val fields = mutableListOf<MutableMap<String, Any>>()

for (info in cartonLabelInfo) {
val field = mutableMapOf<String, Any>()
}

if (cartonLabelInfo.size > 1) {
val context = buildDNLabelContext(request.doPickOrderId)
val rows = buildDnLabelRows(
startCarton = 1,
endCarton = request.numOfCarton,
totalCartonsOnShipment = request.numOfCarton,
)

}
return mapOf(
"report" to PdfUtils.fillReport(context.cartonLabelTemplate, rows, context.params),
"filename" to context.filename,
)
}

params["shopPurchaseOrderNo"] = if (deliveryOrderIds.size > 0) {
"請查閲送貨單(採購單共${deliveryOrderIds.size}張)"
} else {
doPickOrderRecord.deliveryOrderCode ?: cartonLabelInfo[0].code
}
params["deliveryNoteCode"] = doPickOrderRecord.deliveryNoteCode ?: ""
params["shopAddress"] = cartonLabelInfo[0].shopAddress ?: ""
val rawShopLabel = doPickOrderRecord.shopName ?: cartonLabelInfo[0].shopName ?: ""
val parsedShopLabel = parseShopLabelForCartonLabel(rawShopLabel)
params["shopCode"] = parsedShopLabel.shopCode
params["shopCodeAbbr"] = parsedShopLabel.shopCodeAbbr
params["shopName"] = parsedShopLabel.shopNameForLabel
params["truckNo"] = doPickOrderRecord.truckLanceCode ?: ""
open fun exportDNLabelsReprint(request: ExportDNLabelsReprintRequest): Map<String, Any> {
validateCartonReprintRange(
fromCarton = request.fromCarton,
toCarton = request.toCarton,
totalCartonsOnShipment = request.totalCartonsOnShipment,
)

for (cartonNumber in 1..request.numOfCarton) {
val field = mutableMapOf<String, Any>()
fields.add(field)
}
val context = buildDNLabelContext(request.doPickOrderId)
val rows = buildDnLabelRows(
startCarton = request.fromCarton,
endCarton = request.toCarton,
totalCartonsOnShipment = request.totalCartonsOnShipment,
)

return mapOf(
"report" to PdfUtils.fillReport(cartonLabel, fields, params),
"filename" to "${cartonLabelInfo[0].code}_carton_labels"
"report" to PdfUtils.fillReport(context.cartonLabelTemplate, rows, context.params),
"filename" to "${context.filename}_reprint_${request.fromCarton}-${request.toCarton}",
)
}

@@ -1586,6 +1563,138 @@ open class DeliveryOrderService(

}

@Transactional
open fun printDNLabelsReprint(request: PrintDNLabelsReprintRequest) {
validateCartonReprintRange(
fromCarton = request.fromCarton,
toCarton = request.toCarton,
totalCartonsOnShipment = request.totalCartonsOnShipment,
)

val printer =
printerService.findById(request.printerId) ?: throw java.util.NoSuchElementException("No such printer")

val pdf = exportDNLabelsReprint(
ExportDNLabelsReprintRequest(
doPickOrderId = request.doPickOrderId,
fromCarton = request.fromCarton,
toCarton = request.toCarton,
totalCartonsOnShipment = request.totalCartonsOnShipment,
)
)

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
)
}
}

// Reprint should not update cartonQty persisted on the record.
println("Reprint PDF saved to: ${tempPdfFile.absolutePath}")
} finally {
//tempPdfFile.delete()
}
}

private data class DnLabelExportContext(
val cartonLabelTemplate: net.sf.jasperreports.engine.JasperReport,
val params: MutableMap<String, Any>,
val filename: String,
)

private fun buildDNLabelContext(doPickOrderId: Long): DnLabelExportContext {
val dnLabelsPdf = "DeliveryNote/DeliveryNoteCartonLabelsPDF.jrxml"
val resource = ClassPathResource(dnLabelsPdf)
if (!resource.exists()) {
throw FileNotFoundException("Label file not found: $dnLabelsPdf")
}

val doPickOrderRecord = doPickOrderRecordRepository.findById(doPickOrderId).orElseThrow {
NoSuchElementException("DoPickOrderRecord not found with ID: $doPickOrderId")
}
val doPickOrderLineRecords = doPickOrderLineRecordRepository.findByDoPickOrderId(doPickOrderRecord.recordId)
val deliveryOrderIds = doPickOrderLineRecords.mapNotNull { it.doOrderId }.distinct()
if (deliveryOrderIds.isEmpty()) {
throw IllegalStateException("DoPickOrderRecord $doPickOrderId has no associated delivery orders")
}

val cartonLabelTemplate = JasperCompileManager.compileReport(resource.inputStream)
val cartonLabelInfo = deliveryOrderIds.flatMap { deliveryOrderId ->
deliveryOrderRepository.findDeliveryOrderInfoById(deliveryOrderId)
}.toMutableList()
if (cartonLabelInfo.isEmpty()) {
throw IllegalStateException("No delivery order info found for DoPickOrderRecord $doPickOrderId")
}

val params = mutableMapOf<String, Any>()
params["shopPurchaseOrderNo"] = "請查閲送貨單(採購單共${deliveryOrderIds.size}張)"
params["deliveryNoteCode"] = doPickOrderRecord.deliveryNoteCode ?: ""
params["shopAddress"] = cartonLabelInfo[0].shopAddress ?: ""

val rawShopLabel = doPickOrderRecord.shopName ?: cartonLabelInfo[0].shopName ?: ""
val parsedShopLabel = parseShopLabelForCartonLabel(rawShopLabel)
params["shopCode"] = parsedShopLabel.shopCode
params["shopCodeAbbr"] = parsedShopLabel.shopCodeAbbr
params["shopName"] = parsedShopLabel.shopNameForLabel
params["truckNo"] = doPickOrderRecord.truckLanceCode ?: ""

return DnLabelExportContext(
cartonLabelTemplate = cartonLabelTemplate,
params = params,
filename = "${cartonLabelInfo[0].code}_carton_labels",
)
}

private fun buildDnLabelRows(
startCarton: Int,
endCarton: Int,
totalCartonsOnShipment: Int,
): List<DnCartonLabelSheetRow> {
if (endCarton < startCarton) {
return emptyList()
}

return (startCarton..endCarton).map { cartonIndex ->
DnCartonLabelSheetRow(
cartonIndex = cartonIndex,
cartonTotal = totalCartonsOnShipment,
)
}
}

private fun validateCartonReprintRange(
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"
}
}

private fun updateRecordCartonQty(doPickOrderRecordId: Long, cartonQty: Int) {
if (cartonQty <= 0) return
val record = doPickOrderRecordRepository.findById(doPickOrderRecordId).orElse(null) ?: return


+ 23
- 0
src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/DeliveryOrderController.kt Dosyayı Görüntüle

@@ -16,8 +16,10 @@ import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
import com.ffii.fpsms.modules.deliveryOrder.web.models.DoDetailResponse
import com.ffii.fpsms.modules.deliveryOrder.web.models.ExportDNLabelsRequest
import com.ffii.fpsms.modules.deliveryOrder.web.models.ExportDNLabelsReprintRequest
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.PrintDNLabelsReprintRequest
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
@@ -261,6 +263,27 @@ class DeliveryOrderController(
fun printDN(@ModelAttribute request: PrintDNLabelsRequest) {
deliveryOrderService.printDNLabels(request)
}

@PostMapping("/DNLabels/reprint")
@Throws(UnsupportedEncodingException::class, NoSuchMessageException::class, ParseException::class, Exception::class)
fun printDNLabelsReprint(
@Valid @RequestBody request: ExportDNLabelsReprintRequest,
response: HttpServletResponse
) {
response.characterEncoding = "utf-8"
response.contentType = "application/pdf"
val out: OutputStream = response.outputStream
val pdf = deliveryOrderService.exportDNLabelsReprint(request)
val jasperPrint = pdf["report"] as JasperPrint
response.addHeader("filename", "${pdf["filename"]}.pdf")
out.write(JasperExportManager.exportReportToPdf(jasperPrint))
}

@GetMapping("print-DNLabels-reprint")
fun printDNLabelsReprint(@ModelAttribute request: PrintDNLabelsReprintRequest) {
deliveryOrderService.printDNLabelsReprint(request)
}

@GetMapping("/batchPrintQrCode")
fun printQrCodeForDeliveryOrder(@ModelAttribute request: PrintQrCodeForDoRequest) {
stockInLineService.printQrCodeForDeliveryOrder(request)


+ 6
- 0
src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/models/DnCartonLabelSheetRow.kt Dosyayı Görüntüle

@@ -0,0 +1,6 @@
package com.ffii.fpsms.modules.deliveryOrder.web.models

data class DnCartonLabelSheetRow(
val cartonIndex: Int,
val cartonTotal: Int,
)

+ 13
- 0
src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/models/ExportDNLabelsReprintRequest.kt Dosyayı Görüntüle

@@ -0,0 +1,13 @@
package com.ffii.fpsms.modules.deliveryOrder.web.models

import jakarta.validation.constraints.Min

data class ExportDNLabelsReprintRequest(
val doPickOrderId: Long,
@field:Min(1)
val fromCarton: Int,
@field:Min(1)
val toCarton: Int,
@field:Min(1)
val totalCartonsOnShipment: Int,
)

+ 15
- 0
src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/models/PrintDNLabelsReprintRequest.kt Dosyayı Görüntüle

@@ -0,0 +1,15 @@
package com.ffii.fpsms.modules.deliveryOrder.web.models

import jakarta.validation.constraints.Min

data class PrintDNLabelsReprintRequest(
val doPickOrderId: Long,
val printerId: Long,
val printQty: Int?,
@field:Min(1)
val fromCarton: Int,
@field:Min(1)
val toCarton: Int,
@field:Min(1)
val totalCartonsOnShipment: Int,
)

+ 4
- 2
src/main/resources/DeliveryNote/DeliveryNoteCartonLabelsPDF.jrxml Dosyayı Görüntüle

@@ -20,6 +20,8 @@
<queryString>
<![CDATA[]]>
</queryString>
<field name="cartonIndex" class="java.lang.Integer"/>
<field name="cartonTotal" class="java.lang.Integer"/>
<background>
<band splitType="Stretch"/>
</background>
@@ -153,7 +155,7 @@
<textElement textAlignment="Center" verticalAlignment="Middle">
<font size="16"/>
</textElement>
<textFieldExpression><![CDATA[$V{PAGE_NUMBER}]]></textFieldExpression>
<textFieldExpression><![CDATA[$F{cartonIndex}]]></textFieldExpression>
</textField>
<textField evaluationTime="Report">
<reportElement x="230" y="106" width="40" height="30" uuid="66d50bad-7b39-49c1-b127-4d763133ee0c">
@@ -163,7 +165,7 @@
<textElement textAlignment="Center" verticalAlignment="Middle">
<font size="16"/>
</textElement>
<textFieldExpression><![CDATA[$V{PAGE_NUMBER}]]></textFieldExpression>
<textFieldExpression><![CDATA[$F{cartonTotal}]]></textFieldExpression>
</textField>
<staticText>
<reportElement x="195" y="106" width="35" height="30" uuid="73c18ae5-a07b-4215-a753-fa72d6db87eb">


Yükleniyor…
İptal
Kaydet