| @@ -33,6 +33,9 @@ class DoPickOrderRecord { | |||||
| @Column(name = "delivery_order_code", length = 50) | @Column(name = "delivery_order_code", length = 50) | ||||
| var deliveryOrderCode: String? = null | var deliveryOrderCode: String? = null | ||||
| @Column(name = "deliveryNoteCode", length = 50) | |||||
| var deliveryNoteCode: String? = null | |||||
| @Column(name = "loading_sequence") | @Column(name = "loading_sequence") | ||||
| var loadingSequence: Int? = null | var loadingSequence: Int? = null | ||||
| @Enumerated(EnumType.STRING) | @Enumerated(EnumType.STRING) | ||||
| @@ -117,6 +120,7 @@ var handlerName: String? = null | |||||
| modifiedBy: String? = null, | modifiedBy: String? = null, | ||||
| pickOrderCode: String? = null, | pickOrderCode: String? = null, | ||||
| deliveryOrderCode: String? = null, | deliveryOrderCode: String? = null, | ||||
| deliveryNoteCode: String? = null, | |||||
| loadingSequence: Int? = null, | loadingSequence: Int? = null, | ||||
| ) { | ) { | ||||
| this.recordId= recordId | this.recordId= recordId | ||||
| @@ -140,6 +144,7 @@ var handlerName: String? = null | |||||
| this.modifiedBy = modifiedBy | this.modifiedBy = modifiedBy | ||||
| this.pickOrderCode = pickOrderCode | this.pickOrderCode = pickOrderCode | ||||
| this.deliveryOrderCode = deliveryOrderCode | this.deliveryOrderCode = deliveryOrderCode | ||||
| this.deliveryNoteCode = deliveryNoteCode | |||||
| this.loadingSequence = loadingSequence | this.loadingSequence = loadingSequence | ||||
| } | } | ||||
| } | } | ||||
| @@ -15,4 +15,12 @@ import java.time.LocalDateTime | |||||
| interface DoPickOrderRecordRepository : JpaRepository<DoPickOrderRecord, Long> { | interface DoPickOrderRecordRepository : JpaRepository<DoPickOrderRecord, Long> { | ||||
| fun findByPickOrderId(pickOrderId: Long): List<DoPickOrderRecord> | fun findByPickOrderId(pickOrderId: Long): List<DoPickOrderRecord> | ||||
| fun findByTicketNoStartingWith(ticketPrefix: String): List<DoPickOrderRecord> | fun findByTicketNoStartingWith(ticketPrefix: String): List<DoPickOrderRecord> | ||||
| @Query(""" | |||||
| SELECT dpor.deliveryNoteCode from DoPickOrderRecord dpor | |||||
| WHERE dpor.deliveryNoteCode like :prefix% | |||||
| ORDER BY dpor.deliveryNoteCode desc limit 1 | |||||
| """) | |||||
| fun findLatestDeliveryNoteCodeByPrefix(prefix: String): String? | |||||
| } | } | ||||
| @@ -31,7 +31,24 @@ fun findByStoreIdAndRequiredDeliveryDateAndTicketStatusIn( | |||||
| status: List<DoPickOrderStatus> | status: List<DoPickOrderStatus> | ||||
| ): List<DoPickOrder> | ): List<DoPickOrder> | ||||
| @Query("SELECT d FROM DoPickOrder d WHERE d.deleted = false ORDER BY d.requiredDeliveryDate ASC, d.truckDepartureTime ASC") | |||||
| fun findAllByDeletedFalseOrderByTicketReleaseTimeDesc(): List<DoPickOrder> | |||||
| @Query("SELECT d FROM DoPickOrder d WHERE d.deleted = false ORDER BY d.requiredDeliveryDate ASC, d.truckDepartureTime ASC") | |||||
| fun findAllByDeletedFalseOrderByTicketReleaseTimeDesc(): List<DoPickOrder> | |||||
| @Query(""" | |||||
| SELECT COUNT(DISTINCT pol.id) | |||||
| FROM PickOrderLine pol | |||||
| WHERE pol.pickOrder.id IN ( | |||||
| SELECT DISTINCT dpol2.pickOrderId | |||||
| FROM DoPickOrderLine dpol2 | |||||
| WHERE dpol2.doPickOrderId IN ( | |||||
| SELECT DISTINCT dpol1.doPickOrderId | |||||
| FROM DoPickOrderLine dpol1 | |||||
| WHERE dpol1.pickOrderId = :pickOrderId | |||||
| AND dpol1.deleted = false | |||||
| ) | |||||
| AND dpol2.deleted = false | |||||
| ) | |||||
| AND pol.deleted = false | |||||
| """) | |||||
| fun countPickOrderLinesByRelatedPickOrderId(@Param("pickOrderId") pickOrderId: Long): Long | |||||
| } | } | ||||
| @@ -0,0 +1,10 @@ | |||||
| { | |||||
| "folders": [ | |||||
| { | |||||
| "path": "../../../../../../../../.." | |||||
| }, | |||||
| { | |||||
| "path": "../../../../../../../../../../FPSMS-frontend" | |||||
| } | |||||
| ] | |||||
| } | |||||
| @@ -670,133 +670,269 @@ open class DeliveryOrderService( | |||||
| } | } | ||||
| //Delivery Note | |||||
| @Throws(IOException::class) | |||||
| @Transactional | |||||
| open fun exportDeliveryNote(request: ExportDeliveryNoteRequest): Map<String, Any> { | |||||
| val DELIVERYNOTE_PDF = "DeliveryNote/DeliveryNotePDF.jrxml" | |||||
| val resource = ClassPathResource(DELIVERYNOTE_PDF) | |||||
| if (!resource.exists()) { | |||||
| throw FileNotFoundException("Report file not fount: $DELIVERYNOTE_PDF") | |||||
| } | |||||
| val doPickOrder = doPickOrderRepository.findById(request.doPickOrderId).orElseThrow { | |||||
| NoSuchElementException("DoPickOrder not found with ID: ${request.doPickOrderId}") | |||||
| } | |||||
| val pickOrderIds = if (doPickOrder.pickOrderId != null) { | |||||
| // Single pick order case | |||||
| listOf(doPickOrder.pickOrderId!!) | |||||
| } else { | |||||
| // Merged pick orders case - get from DoPickOrderLine | |||||
| val doPickOrderLines = doPickOrderLineRepository.findByDoPickOrderIdAndDeletedFalse(doPickOrder.id!!) | |||||
| val orderIds = doPickOrderLines.mapNotNull { it.pickOrderId }.distinct() | |||||
| // Delivery Note | |||||
| @Throws(IOException::class) | |||||
| @Transactional | |||||
| open fun exportDeliveryNote(request: ExportDeliveryNoteRequest): Map<String, Any> { | |||||
| if (orderIds.isEmpty()) { | |||||
| throw IllegalStateException("DoPickOrder ${request.doPickOrderId} has no associated pick orders") | |||||
| } | |||||
| orderIds | |||||
| } | |||||
| // INPUT STREAM SETUP | |||||
| val DELIVERYNOTE_PDF = "DeliveryNote/DeliveryNotePDF.jrxml" | |||||
| val resource = ClassPathResource(DELIVERYNOTE_PDF) | |||||
| if (!resource.exists()) { | |||||
| throw FileNotFoundException("Report file not found: $DELIVERYNOTE_PDF") | |||||
| } | |||||
| val deliveryOrderIds = if (doPickOrder.doOrderId != null) { | |||||
| // Single delivery order case | |||||
| listOf(doPickOrder.doOrderId!!) | |||||
| } else { | |||||
| // Merged delivery orders case - get from DoPickOrderLine | |||||
| val doPickOrderLines = doPickOrderLineRepository.findByDoPickOrderIdAndDeletedFalse(doPickOrder.id!!) | |||||
| val orderIds = doPickOrderLines.mapNotNull { it.doOrderId }.distinct() | |||||
| val inputStream = resource.inputStream | |||||
| val deliveryNote = JasperCompileManager.compileReport(inputStream) | |||||
| if (orderIds.isEmpty()) { | |||||
| throw IllegalStateException("DoPickOrder ${request.doPickOrderId} has no associated delivery orders") | |||||
| } | |||||
| orderIds | |||||
| val fields = mutableListOf<MutableMap<String, Any>>() | |||||
| val params = mutableMapOf<String, Any>() | |||||
| // DRAFT & RECORD SEPARATION | |||||
| if (request.isDraft) { | |||||
| return exportDeliveryNoteFromDraft(request, deliveryNote, fields, params) | |||||
| } else { | |||||
| return exportDeliveryNoteFromRecord(request, deliveryNote, fields, params) | |||||
| } | |||||
| } | |||||
| // DRAFT | |||||
| private fun exportDeliveryNoteFromDraft( | |||||
| request: ExportDeliveryNoteRequest, | |||||
| deliveryNote: net.sf.jasperreports.engine.JasperReport, | |||||
| fields: MutableList<MutableMap<String, Any>>, | |||||
| params: MutableMap<String, Any> | |||||
| ): Map<String, Any> { | |||||
| val doPickOrder = doPickOrderRepository.findById(request.doPickOrderId).orElseThrow { | |||||
| NoSuchElementException("DoPickOrder not found with ID: ${request.doPickOrderId}") | |||||
| } | |||||
| val pickOrderIds = if (doPickOrder.pickOrderId != null) { | |||||
| // SINGLE DELIVERY ORDER | |||||
| listOf(doPickOrder.pickOrderId!!) | |||||
| } else { | |||||
| // MERGED DELIVERY ORDERS (DOPICKORDERLINE) | |||||
| val doPickOrderLines = doPickOrderLineRepository.findByDoPickOrderIdAndDeletedFalse(doPickOrder.id!!) | |||||
| val orderIds = doPickOrderLines.mapNotNull { it.pickOrderId }.distinct() | |||||
| if (orderIds.isEmpty()) { | |||||
| throw IllegalStateException("DoPickOrder ${request.doPickOrderId} has no associated pick orders") | |||||
| } | } | ||||
| orderIds | |||||
| } | |||||
| val deliveryNoteInfo = deliveryOrderIds.flatMap { deliveryOrderId -> | |||||
| deliveryOrderRepository.findDeliveryOrderInfoById(deliveryOrderId) | |||||
| }.toMutableList() | |||||
| val deliveryOrderIds = if (doPickOrder.doOrderId != null) { | |||||
| // SINGLE DELIVERY ORDER | |||||
| listOf(doPickOrder.doOrderId!!) | |||||
| } else { | |||||
| // MERGED DELIVERY ORDERS (DOPICKORDERLINE) | |||||
| val doPickOrderLines = doPickOrderLineRepository.findByDoPickOrderIdAndDeletedFalse(doPickOrder.id!!) | |||||
| val orderIds = doPickOrderLines.mapNotNull { it.doOrderId }.distinct() | |||||
| if (deliveryNoteInfo.isEmpty()) { | |||||
| throw NoSuchElementException("Delivery orders not found for IDs: $deliveryOrderIds") | |||||
| if (orderIds.isEmpty()) { | |||||
| throw IllegalStateException("DoPickOrder ${request.doPickOrderId} has no associated delivery orders") | |||||
| } | } | ||||
| orderIds | |||||
| } | |||||
| val pickOrderId = pickOrderIds.first() | |||||
| val deliveryNoteInfo = deliveryOrderIds.flatMap { deliveryOrderId -> | |||||
| deliveryOrderRepository.findDeliveryOrderInfoById(deliveryOrderId) | |||||
| }.toMutableList() | |||||
| val inputStream = resource.inputStream | |||||
| val deliveryNote = JasperCompileManager.compileReport(inputStream) | |||||
| if (deliveryNoteInfo.isEmpty()) { | |||||
| throw NoSuchElementException("Delivery orders not found for IDs: $deliveryOrderIds") | |||||
| } | |||||
| val fields = mutableListOf<MutableMap<String, Any>>() | |||||
| val params = mutableMapOf<String, Any>() | |||||
| val pickOrderId = pickOrderIds.first() | |||||
| val truckNo = doPickOrder.truckLanceCode ?: "" | |||||
| val selectedPickOrder = pickOrderRepository.findById(pickOrderId).orElse(null) | |||||
| val truckNo = doPickOrder.truckLanceCode ?: "" | |||||
| val selectedPickOrder = pickOrderRepository.findById(pickOrderId).orElse(null) | |||||
| val allLines = deliveryNoteInfo.flatMap { info -> | |||||
| info.deliveryOrderLines.map { line -> line } | |||||
| } | |||||
| val allLines = deliveryNoteInfo.flatMap { info -> | |||||
| info.deliveryOrderLines.map { line -> line } | |||||
| } | |||||
| val sortedLines = allLines.sortedBy { line -> | |||||
| line.itemId?.let { itemId -> | |||||
| getWarehouseOrderByItemId(itemId) | |||||
| } ?: Int.MAX_VALUE | |||||
| } | |||||
| val sortedLines = allLines.sortedBy { line -> | |||||
| line.itemId?.let { itemId -> | |||||
| getWarehouseOrderByItemId(itemId) | |||||
| } ?: Int.MAX_VALUE | |||||
| } | |||||
| sortedLines.forEach { line -> | |||||
| val field = mutableMapOf<String, Any>() | |||||
| field["sequenceNumber"] = (fields.size + 1).toString() | |||||
| field["itemNo"] = line.itemNo | |||||
| field["itemName"] = line.itemName ?: "" | |||||
| field["uom"] = line.uom ?: "" | |||||
| field["qty"] = line.qty.toString() | |||||
| field["shortName"] = line.uomShortDesc ?: "" | |||||
| val route = line.itemId?.let { itemId -> | |||||
| getWarehouseCodeByItemId(itemId) | |||||
| } ?: "-" | |||||
| field["route"] = route | |||||
| //USE SUGGESTED PICK LOTS | |||||
| val lotNo = line.itemId?.let { itemId -> | |||||
| pickOrderIds.mapNotNull { pickOrderId -> | |||||
| val lots = getLotNumbersForPickOrderByItemId(itemId, pickOrderId) | |||||
| lots.ifBlank { null } | |||||
| }.distinct().joinToString(", ") | |||||
| }?.ifBlank { "沒有庫存" } ?: "沒有庫存" | |||||
| field["lotNo"] = lotNo | |||||
| fields.add(field) | |||||
| } | |||||
| sortedLines.forEach { line -> | |||||
| val field = mutableMapOf<String, Any>() | |||||
| params["dnTitle"] = "送貨單(初稿)" | |||||
| params["colQty"] = "所需數量" | |||||
| params["totalCartonTitle"] = "" | |||||
| params["deliveryNoteCodeTitle"] = "" | |||||
| params["deliveryNoteCode"] = "" | |||||
| field["sequenceNumber"] = (fields.size + 1).toString() | |||||
| field["itemNo"] = line.itemNo | |||||
| field["itemName"] = line.itemName ?: "" | |||||
| field["uom"] = line.uom ?: "" | |||||
| field["qty"] = line.qty.toString() | |||||
| field["shortName"] = line.uomShortDesc ?: "" | |||||
| val route = line.itemId?.let { itemId -> | |||||
| getWarehouseCodeByItemId(itemId) | |||||
| } ?: "-" | |||||
| field["route"] = route | |||||
| val lotNo = line.itemId?.let { itemId -> | |||||
| pickOrderIds.mapNotNull { pickOrderId -> | |||||
| val lots = getLotNumbersForPickOrderByItemId(itemId, pickOrderId) | |||||
| lots.ifBlank { null } | |||||
| }.distinct().joinToString(", ") | |||||
| }?.ifBlank { "沒有庫存" } ?: "沒有庫存" | |||||
| field["lotNo"] = lotNo | |||||
| fields.add(field) | |||||
| params["numOfCarton"] = request.numOfCarton.toString() | |||||
| if (params["numOfCarton"] == "0") { | |||||
| params["numOfCarton"] = "" | |||||
| } | |||||
| params["shopName"] = doPickOrder.shopName ?: deliveryNoteInfo[0].shopName ?: "" | |||||
| params["shopAddress"] = deliveryNoteInfo[0].shopAddress ?: "" | |||||
| params["deliveryDate"] = deliveryNoteInfo[0].estimatedArrivalDate?.format(DateTimeFormatter.ISO_LOCAL_DATE) ?: "" | |||||
| params["truckNo"] = truckNo | |||||
| params["ShopPurchaseOrderNo"] = doPickOrder.deliveryOrderCode ?: deliveryNoteInfo.joinToString(", ") { it.code } | |||||
| params["FGPickOrderNo"] = doPickOrder.pickOrderCode ?: selectedPickOrder?.code ?: "" | |||||
| return mapOf( | |||||
| "report" to PdfUtils.fillReport(deliveryNote, fields, params), | |||||
| "filename" to deliveryNoteInfo.joinToString("_") { it.code } | |||||
| ) | |||||
| } | |||||
| private fun exportDeliveryNoteFromRecord( | |||||
| request: ExportDeliveryNoteRequest, | |||||
| deliveryNote: net.sf.jasperreports.engine.JasperReport, | |||||
| fields: MutableList<MutableMap<String, Any>>, | |||||
| params: MutableMap<String, Any> | |||||
| ) : Map<String, Any> { | |||||
| val doPickOrderRecord = doPickOrderRecordRepository.findById(request.doPickOrderId).orElseThrow { | |||||
| NoSuchElementException("DoPickOrderRecord not found with ID: ${request.doPickOrderId}") | |||||
| } | |||||
| val doPickOrderLineRecords = doPickOrderLineRecordRepository.findByDoPickOrderIdAndDeletedFalse(request.doPickOrderId) | |||||
| val pickOrderIds = doPickOrderLineRecords.mapNotNull { it.pickOrderId }.distinct() | |||||
| if(pickOrderIds.isEmpty()){ | |||||
| throw IllegalStateException("DoPickOrderRecord ${request.doPickOrderId} has no associated pick orders") | |||||
| } | |||||
| val deliveryOrderIds = doPickOrderLineRecords.mapNotNull { it.doOrderId }.distinct() | |||||
| if(deliveryOrderIds.isEmpty()){ | |||||
| throw IllegalStateException("DoPickOrderRecord ${request.doPickOrderId} has no associated delivery orders") | |||||
| } | |||||
| val deliveryNoteInfo = deliveryOrderIds.flatMap { deliveryOrderId -> | |||||
| deliveryOrderRepository.findDeliveryOrderInfoById(deliveryOrderId) | |||||
| }.toMutableList() | |||||
| val pickOrderId = pickOrderIds.first() | |||||
| val truckNo = doPickOrderRecord.truckLanceCode ?: "" | |||||
| val selectedPickOrder = pickOrderRepository.findById(pickOrderId).orElse(null) | |||||
| val allLines = deliveryNoteInfo.flatMap { info -> | |||||
| info.deliveryOrderLines.map { line -> line } | |||||
| } | |||||
| val pickOrderLines = pickOrderIds.flatMap { pickOrderId -> | |||||
| pickOrderLineRepository.findAllByPickOrderId(pickOrderId) | |||||
| } | |||||
| val pickOrderLineIdsByItemId = pickOrderLines | |||||
| .groupBy { it.item?.id } | |||||
| .mapValues { (_, lines) -> lines.mapNotNull { it.id } } | |||||
| val allPickOrderLineIds = pickOrderLines.mapNotNull { it.id } | |||||
| val stockOutLinesByPickOrderLineId = if (allPickOrderLineIds.isNotEmpty()) { | |||||
| allPickOrderLineIds.associateWith { pickOrderLineId -> | |||||
| stockOutLineRepository.findAllByPickOrderLineIdAndDeletedFalse(pickOrderLineId) | |||||
| } | } | ||||
| } else { | |||||
| emptyMap() | |||||
| } | |||||
| val sortedLines = allLines.sortedBy { line -> | |||||
| line.itemId?.let { itemId -> | |||||
| getWarehouseOrderByItemId(itemId) | |||||
| } ?: Int.MAX_VALUE | |||||
| } | |||||
| sortedLines.forEach { line -> | |||||
| val field = mutableMapOf<String, Any>() | |||||
| if (request.isDraft) { | |||||
| params["dnTitle"] = "送貨單(初稿)" | |||||
| params["colQty"] = "所需數量" | |||||
| params["totalCartonTitle"] = "" | |||||
| params["deliveryOrderCodeTitle"] = "" | |||||
| params["deliveryOrderCode"] = "" | |||||
| field["sequenceNumber"] = (fields.size + 1).toString() | |||||
| field["itemNo"] = line.itemNo | |||||
| field["itemName"] = line.itemName ?: "" | |||||
| field["uom"] = line.uom ?: "" | |||||
| val actualPickQty = if (line.itemId != null) { | |||||
| val pickOrderLineIdsForItem = pickOrderLineIdsByItemId[line.itemId] ?: emptyList() | |||||
| val totalQty = pickOrderLineIdsForItem.sumOf { pickOrderLineId -> | |||||
| val stockOutLines = stockOutLinesByPickOrderLineId[pickOrderLineId] ?: emptyList() | |||||
| stockOutLines.sumOf { it.qty } | |||||
| } | |||||
| totalQty.toString() | |||||
| } else { | } else { | ||||
| params["dnTitle"] = "送貨單" | |||||
| params["colQty"] = "已提數量" | |||||
| params["totalCartonTitle"] = "總箱數:" | |||||
| params["deliveryOrderCodeTitle"] = "送貨單編號:" | |||||
| params["deliveryOrderCode"] = "GEN FROM CODE GENERATOR (NEED FIND TIMING)" | |||||
| line.qty.toString() | |||||
| } | } | ||||
| field["qty"] = actualPickQty | |||||
| params["numOfCarton"] = request.numOfCarton.toString() | |||||
| if (params["numOfCarton"] == "0") { | |||||
| params["numOfCarton"] = "" | |||||
| } | |||||
| field["shortName"] = line.uomShortDesc ?: "" | |||||
| params["shopName"] = doPickOrder.shopName ?: deliveryNoteInfo[0].shopName ?:"" | |||||
| params["shopAddress"] = deliveryNoteInfo[0].shopAddress ?: "" | |||||
| params["deliveryDate"] = deliveryNoteInfo[0].estimatedArrivalDate?.format(DateTimeFormatter.ISO_LOCAL_DATE) ?: "" | |||||
| params["truckNo"] = truckNo | |||||
| params["ShopPurchaseOrderNo"] = doPickOrder.deliveryOrderCode ?: deliveryNoteInfo.joinToString(", ") { it.code } | |||||
| params["FGPickOrderNo"] = doPickOrder.pickOrderCode ?: selectedPickOrder?.code ?: "" | |||||
| val route = line.itemId?.let { itemId -> | |||||
| getWarehouseCodeByItemId(itemId) | |||||
| } ?: "-" | |||||
| field["route"] = route | |||||
| //USE STOCK OUT LINE | |||||
| val lotNo = line.itemId?.let { itemId -> | |||||
| val pickOrderLineIdsForItem = pickOrderLineIdsByItemId[itemId] ?: emptyList() | |||||
| val lotNumbers = pickOrderLineIdsForItem.flatMap { pickOrderLineId -> | |||||
| val stockOutLines = stockOutLinesByPickOrderLineId[pickOrderLineId] ?: emptyList() | |||||
| stockOutLines.mapNotNull { it.lotNo } | |||||
| }.distinct().joinToString(", ") | |||||
| return mapOf( | |||||
| "report" to PdfUtils.fillReport(deliveryNote, fields, params), | |||||
| "filename" to deliveryNoteInfo.joinToString("_") { it.code } | |||||
| ) | |||||
| lotNumbers.ifBlank { | |||||
| "沒有庫存" | |||||
| } | |||||
| } ?: "沒有庫存" | |||||
| field["lotNo"] = lotNo | |||||
| fields.add(field) | |||||
| } | |||||
| params["dnTitle"] = "送貨單" | |||||
| params["colQty"] = "已提數量" | |||||
| params["totalCartonTitle"] = "總箱數:" | |||||
| params["deliveryNoteCodeTitle"] = "送貨單編號:" | |||||
| params["deliveryNoteCode"] = doPickOrderRecord.deliveryNoteCode ?: "" | |||||
| params["numOfCarton"] = request.numOfCarton.toString() | |||||
| if (params["numOfCarton"] == "0") { | |||||
| params["numOfCarton"] = "" | |||||
| } | } | ||||
| params["shopName"] = doPickOrderRecord.shopName ?: deliveryNoteInfo[0].shopName ?: "" | |||||
| params["shopAddress"] = deliveryNoteInfo[0].shopAddress ?: "" | |||||
| params["deliveryDate"] = deliveryNoteInfo[0].estimatedArrivalDate?.format(DateTimeFormatter.ISO_LOCAL_DATE) ?: "" | |||||
| params["truckNo"] = truckNo | |||||
| params["ShopPurchaseOrderNo"] = doPickOrderRecord.deliveryOrderCode ?: deliveryNoteInfo.joinToString(", ") { it.code } | |||||
| params["FGPickOrderNo"] = doPickOrderRecord.pickOrderCode ?: selectedPickOrder?.code ?: "" | |||||
| return mapOf( | |||||
| "report" to PdfUtils.fillReport(deliveryNote, fields, params), | |||||
| "filename" to deliveryNoteInfo.joinToString("_") { it.code } | |||||
| ) | |||||
| } | |||||
| //Print Delivery Note | //Print Delivery Note | ||||
| @Transactional | @Transactional | ||||
| open fun printDeliveryNote(request: PrintDeliveryNoteRequest) { | open fun printDeliveryNote(request: PrintDeliveryNoteRequest) { | ||||
| @@ -857,7 +993,7 @@ open class DeliveryOrderService( | |||||
| } | } | ||||
| params["shopPurchaseOrderNo"] = doPickOrder.deliveryOrderCode ?: cartonLabelInfo[0].code | params["shopPurchaseOrderNo"] = doPickOrder.deliveryOrderCode ?: cartonLabelInfo[0].code | ||||
| params["deliveryOrderCode"] = "GEN FROM CODE GENERATOR (NEED FIND TIMING)" | |||||
| params["deliveryNoteCode"] = "GEN FROM CODE GENERATOR (NEED FIND TIMING)" | |||||
| params["shopAddress"] = cartonLabelInfo[0].shopAddress ?: "" | params["shopAddress"] = cartonLabelInfo[0].shopAddress ?: "" | ||||
| params["shopName"] = doPickOrder.shopName ?: cartonLabelInfo[0].shopName ?: "" | params["shopName"] = doPickOrder.shopName ?: cartonLabelInfo[0].shopName ?: "" | ||||
| @@ -4546,6 +4546,7 @@ println("DEBUG sol polIds in linesResults: " + linesResults.mapNotNull { it["sto | |||||
| val sql = """ | val sql = """ | ||||
| SELECT DISTINCT | SELECT DISTINCT | ||||
| dpor.id as doPickOrderRecordId, | dpor.id as doPickOrderRecordId, | ||||
| dpor.record_id as recordId, | |||||
| dpor.ticket_no as ticketNo, | dpor.ticket_no as ticketNo, | ||||
| dpor.store_id as storeId, | dpor.store_id as storeId, | ||||
| dpor.ticketCompleteDateTime as completedDate, | dpor.ticketCompleteDateTime as completedDate, | ||||
| @@ -4648,6 +4649,7 @@ println("DEBUG sol polIds in linesResults: " + linesResults.mapNotNull { it["sto | |||||
| mapOf( | mapOf( | ||||
| "id" to (row["doPickOrderRecordId"] ?: 0L), | "id" to (row["doPickOrderRecordId"] ?: 0L), | ||||
| "doPickOrderRecordId" to (row["doPickOrderRecordId"] ?: 0L), | "doPickOrderRecordId" to (row["doPickOrderRecordId"] ?: 0L), | ||||
| "recordId" to (row["recordId"] ?: ""), | |||||
| "ticketNo" to (row["ticketNo"] ?: ""), | "ticketNo" to (row["ticketNo"] ?: ""), | ||||
| "storeId" to (row["storeId"] ?: ""), | "storeId" to (row["storeId"] ?: ""), | ||||
| "completedDate" to (row["completedDate"]?.toString() ?: ""), | "completedDate" to (row["completedDate"]?.toString() ?: ""), | ||||
| @@ -31,6 +31,8 @@ import com.ffii.fpsms.modules.deliveryOrder.entity.DoPickOrderRecord | |||||
| import com.ffii.fpsms.modules.deliveryOrder.entity.DoPickOrderLineRecord | import com.ffii.fpsms.modules.deliveryOrder.entity.DoPickOrderLineRecord | ||||
| import com.ffii.fpsms.modules.deliveryOrder.enums.DeliveryOrderStatus | import com.ffii.fpsms.modules.deliveryOrder.enums.DeliveryOrderStatus | ||||
| import com.ffii.fpsms.modules.deliveryOrder.entity.DoPickOrderLineRecordRepository | import com.ffii.fpsms.modules.deliveryOrder.entity.DoPickOrderLineRecordRepository | ||||
| import com.ffii.fpsms.modules.common.CodeGenerator | |||||
| @Service | @Service | ||||
| open class StockOutLineService( | open class StockOutLineService( | ||||
| private val jdbcDao: JdbcDao, | private val jdbcDao: JdbcDao, | ||||
| @@ -372,7 +374,12 @@ private fun getStockOutIdFromPickOrderLine(pickOrderLineId: Long): Long { | |||||
| dpo.ticketStatus = DoPickOrderStatus.completed | dpo.ticketStatus = DoPickOrderStatus.completed | ||||
| dpo.ticketCompleteDateTime = LocalDateTime.now() | dpo.ticketCompleteDateTime = LocalDateTime.now() | ||||
| doPickOrderRepository.save(dpo) | doPickOrderRepository.save(dpo) | ||||
| val prefix = "DN" | |||||
| val midfix = CodeGenerator.DEFAULT_MIDFIX | |||||
| val latestCode = doPickOrderRecordRepository.findLatestDeliveryNoteCodeByPrefix("${prefix}-${midfix}") | |||||
| val deliveryNoteCode = CodeGenerator.generateNo(prefix = prefix, midfix = midfix, latestCode = latestCode) | |||||
| // 4) 可选:复制 header 到 record 表,复制 lines 到 line_record,再删除原有行/头(与你在 PickOrderService.completeStockOut 的做法保持一致) | // 4) 可选:复制 header 到 record 表,复制 lines 到 line_record,再删除原有行/头(与你在 PickOrderService.completeStockOut 的做法保持一致) | ||||
| val dpoRecord = DoPickOrderRecord( | val dpoRecord = DoPickOrderRecord( | ||||
| recordId =dpoId, | recordId =dpoId, | ||||
| @@ -388,6 +395,7 @@ private fun getStockOutIdFromPickOrderLine(pickOrderLineId: Long): Long { | |||||
| doOrderId = dpo.doOrderId, | doOrderId = dpo.doOrderId, | ||||
| pickOrderCode = dpo.pickOrderCode, | pickOrderCode = dpo.pickOrderCode, | ||||
| deliveryOrderCode = dpo.deliveryOrderCode, | deliveryOrderCode = dpo.deliveryOrderCode, | ||||
| deliveryNoteCode = deliveryNoteCode, | |||||
| loadingSequence = dpo.loadingSequence, | loadingSequence = dpo.loadingSequence, | ||||
| ticketReleaseTime = dpo.ticketReleaseTime, | ticketReleaseTime = dpo.ticketReleaseTime, | ||||
| ticketCompleteDateTime = LocalDateTime.now(), | ticketCompleteDateTime = LocalDateTime.now(), | ||||
| @@ -1,7 +1,7 @@ | |||||
| <?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!-- Created with Jaspersoft Studio version 6.17.0.final using JasperReports Library version 6.17.0-6d93193241dd8cc42629e188b94f9e0bc5722efd --> | <!-- Created with Jaspersoft Studio version 6.17.0.final using JasperReports Library version 6.17.0-6d93193241dd8cc42629e188b94f9e0bc5722efd --> | ||||
| <jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="DeliveryNotePDF" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="36f9d415-527f-4152-b7b0-eea81fe06f73"> | <jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="DeliveryNotePDF" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="36f9d415-527f-4152-b7b0-eea81fe06f73"> | ||||
| <parameter name="deliveryOrderCode" class="java.lang.String"> | |||||
| <parameter name="deliveryNoteCode" class="java.lang.String"> | |||||
| <parameterDescription><![CDATA[DeliveryOrderCode]]></parameterDescription> | <parameterDescription><![CDATA[DeliveryOrderCode]]></parameterDescription> | ||||
| </parameter> | </parameter> | ||||
| <parameter name="shopName" class="java.lang.String"/> | <parameter name="shopName" class="java.lang.String"/> | ||||
| @@ -14,7 +14,7 @@ | |||||
| <parameter name="dnTitle" class="java.lang.String"/> | <parameter name="dnTitle" class="java.lang.String"/> | ||||
| <parameter name="colQty" class="java.lang.String"/> | <parameter name="colQty" class="java.lang.String"/> | ||||
| <parameter name="totalCartonTitle" class="java.lang.String"/> | <parameter name="totalCartonTitle" class="java.lang.String"/> | ||||
| <parameter name="deliveryOrderCodeTitle" class="java.lang.String"/> | |||||
| <parameter name="deliveryNoteCodeTitle" class="java.lang.String"/> | |||||
| <queryString> | <queryString> | ||||
| <![CDATA[]]> | <![CDATA[]]> | ||||
| </queryString> | </queryString> | ||||
| @@ -33,7 +33,7 @@ | |||||
| <band/> | <band/> | ||||
| </title> | </title> | ||||
| <pageHeader> | <pageHeader> | ||||
| <band height="186"> | |||||
| <band height="155"> | |||||
| <staticText> | <staticText> | ||||
| <reportElement x="430" y="0" width="40" height="18" uuid="3381622a-7eda-4649-88b8-650da96c2a77"> | <reportElement x="430" y="0" width="40" height="18" uuid="3381622a-7eda-4649-88b8-650da96c2a77"> | ||||
| <property name="com.jaspersoft.studio.unit.y" value="px"/> | <property name="com.jaspersoft.studio.unit.y" value="px"/> | ||||
| @@ -119,10 +119,10 @@ | |||||
| </textElement> | </textElement> | ||||
| <text><![CDATA[地址:]]></text> | <text><![CDATA[地址:]]></text> | ||||
| </staticText> | </staticText> | ||||
| <textField> | |||||
| <textField textAdjust="StretchHeight"> | |||||
| <reportElement x="70" y="50" width="465" height="23" uuid="89e79bce-bd39-48e6-b114-c11b4bcc5c9f"/> | <reportElement x="70" y="50" width="465" height="23" uuid="89e79bce-bd39-48e6-b114-c11b4bcc5c9f"/> | ||||
| <textElement verticalAlignment="Middle"> | <textElement verticalAlignment="Middle"> | ||||
| <font fontName="微軟正黑體" size="13" isBold="true"/> | |||||
| <font fontName="微軟正黑體" size="16" isBold="true"/> | |||||
| </textElement> | </textElement> | ||||
| <textFieldExpression><![CDATA[$P{shopAddress}]]></textFieldExpression> | <textFieldExpression><![CDATA[$P{shopAddress}]]></textFieldExpression> | ||||
| </textField> | </textField> | ||||
| @@ -167,7 +167,7 @@ | |||||
| <textElement textAlignment="Left" verticalAlignment="Middle"> | <textElement textAlignment="Left" verticalAlignment="Middle"> | ||||
| <font fontName="微軟正黑體" size="12"/> | <font fontName="微軟正黑體" size="12"/> | ||||
| </textElement> | </textElement> | ||||
| <text><![CDATA[成品提料編號:]]></text> | |||||
| <text><![CDATA[成品提貨單號:]]></text> | |||||
| </staticText> | </staticText> | ||||
| <staticText> | <staticText> | ||||
| <reportElement x="5" y="130" width="110" height="18" uuid="111c5f73-f543-4006-931b-27479ccca816"> | <reportElement x="5" y="130" width="110" height="18" uuid="111c5f73-f543-4006-931b-27479ccca816"> | ||||
| @@ -177,14 +177,14 @@ | |||||
| <textElement textAlignment="Left" verticalAlignment="Top"> | <textElement textAlignment="Left" verticalAlignment="Top"> | ||||
| <font fontName="微軟正黑體" size="12"/> | <font fontName="微軟正黑體" size="12"/> | ||||
| </textElement> | </textElement> | ||||
| <text><![CDATA[店鋪採購單編號:]]></text> | |||||
| <text><![CDATA[店鋪採購單號:]]></text> | |||||
| </staticText> | </staticText> | ||||
| <textField> | |||||
| <reportElement x="115" y="130" width="425" height="54" uuid="7171ba0b-1a78-4ff6-a765-7b2b543ab0bc"> | |||||
| <textField textAdjust="StretchHeight"> | |||||
| <reportElement x="115" y="130" width="425" height="18" uuid="7171ba0b-1a78-4ff6-a765-7b2b543ab0bc"> | |||||
| <property name="com.jaspersoft.studio.unit.height" value="px"/> | <property name="com.jaspersoft.studio.unit.height" value="px"/> | ||||
| </reportElement> | </reportElement> | ||||
| <textElement verticalAlignment="Top"> | |||||
| <font fontName="微軟正黑體"/> | |||||
| <textElement textAlignment="Left" verticalAlignment="Middle"> | |||||
| <font fontName="微軟正黑體" size="12"/> | |||||
| </textElement> | </textElement> | ||||
| <textFieldExpression><![CDATA[$P{ShopPurchaseOrderNo}]]></textFieldExpression> | <textFieldExpression><![CDATA[$P{ShopPurchaseOrderNo}]]></textFieldExpression> | ||||
| </textField> | </textField> | ||||
| @@ -193,7 +193,7 @@ | |||||
| <property name="com.jaspersoft.studio.unit.height" value="px"/> | <property name="com.jaspersoft.studio.unit.height" value="px"/> | ||||
| </reportElement> | </reportElement> | ||||
| <textElement verticalAlignment="Middle"> | <textElement verticalAlignment="Middle"> | ||||
| <font fontName="微軟正黑體"/> | |||||
| <font fontName="微軟正黑體" size="12"/> | |||||
| </textElement> | </textElement> | ||||
| <textFieldExpression><![CDATA[$P{FGPickOrderNo}]]></textFieldExpression> | <textFieldExpression><![CDATA[$P{FGPickOrderNo}]]></textFieldExpression> | ||||
| </textField> | </textField> | ||||
| @@ -202,7 +202,7 @@ | |||||
| <property name="com.jaspersoft.studio.unit.height" value="px"/> | <property name="com.jaspersoft.studio.unit.height" value="px"/> | ||||
| </reportElement> | </reportElement> | ||||
| <textElement verticalAlignment="Middle"> | <textElement verticalAlignment="Middle"> | ||||
| <font fontName="微軟正黑體"/> | |||||
| <font fontName="微軟正黑體" size="12"/> | |||||
| </textElement> | </textElement> | ||||
| <textFieldExpression><![CDATA[$P{deliveryDate}]]></textFieldExpression> | <textFieldExpression><![CDATA[$P{deliveryDate}]]></textFieldExpression> | ||||
| </textField> | </textField> | ||||
| @@ -211,7 +211,7 @@ | |||||
| <property name="com.jaspersoft.studio.unit.height" value="px"/> | <property name="com.jaspersoft.studio.unit.height" value="px"/> | ||||
| </reportElement> | </reportElement> | ||||
| <textElement verticalAlignment="Middle"> | <textElement verticalAlignment="Middle"> | ||||
| <font fontName="微軟正黑體"/> | |||||
| <font fontName="微軟正黑體" size="12"/> | |||||
| </textElement> | </textElement> | ||||
| <textFieldExpression><![CDATA[$P{numOfCarton}]]></textFieldExpression> | <textFieldExpression><![CDATA[$P{numOfCarton}]]></textFieldExpression> | ||||
| </textField> | </textField> | ||||
| @@ -220,7 +220,7 @@ | |||||
| <property name="com.jaspersoft.studio.unit.height" value="px"/> | <property name="com.jaspersoft.studio.unit.height" value="px"/> | ||||
| </reportElement> | </reportElement> | ||||
| <textElement verticalAlignment="Middle"> | <textElement verticalAlignment="Middle"> | ||||
| <font fontName="微軟正黑體"/> | |||||
| <font fontName="微軟正黑體" size="12"/> | |||||
| </textElement> | </textElement> | ||||
| <textFieldExpression><![CDATA[$P{totalCartonTitle}]]></textFieldExpression> | <textFieldExpression><![CDATA[$P{totalCartonTitle}]]></textFieldExpression> | ||||
| </textField> | </textField> | ||||
| @@ -229,18 +229,18 @@ | |||||
| <property name="com.jaspersoft.studio.unit.height" value="px"/> | <property name="com.jaspersoft.studio.unit.height" value="px"/> | ||||
| </reportElement> | </reportElement> | ||||
| <textElement verticalAlignment="Middle"> | <textElement verticalAlignment="Middle"> | ||||
| <font fontName="微軟正黑體"/> | |||||
| <font fontName="微軟正黑體" size="12"/> | |||||
| </textElement> | </textElement> | ||||
| <textFieldExpression><![CDATA[$P{deliveryOrderCode}]]></textFieldExpression> | |||||
| <textFieldExpression><![CDATA[$P{deliveryNoteCode}]]></textFieldExpression> | |||||
| </textField> | </textField> | ||||
| <textField> | <textField> | ||||
| <reportElement x="280" y="110" width="110" height="18" uuid="f0f2f87f-26cb-4fad-9c78-9d934191fad9"> | <reportElement x="280" y="110" width="110" height="18" uuid="f0f2f87f-26cb-4fad-9c78-9d934191fad9"> | ||||
| <property name="com.jaspersoft.studio.unit.height" value="px"/> | <property name="com.jaspersoft.studio.unit.height" value="px"/> | ||||
| </reportElement> | </reportElement> | ||||
| <textElement verticalAlignment="Middle"> | <textElement verticalAlignment="Middle"> | ||||
| <font fontName="微軟正黑體"/> | |||||
| <font fontName="微軟正黑體" size="12"/> | |||||
| </textElement> | </textElement> | ||||
| <textFieldExpression><![CDATA[$P{deliveryOrderCodeTitle}]]></textFieldExpression> | |||||
| <textFieldExpression><![CDATA[$P{deliveryNoteCodeTitle}]]></textFieldExpression> | |||||
| </textField> | </textField> | ||||
| </band> | </band> | ||||
| </pageHeader> | </pageHeader> | ||||
| @@ -269,11 +269,11 @@ | |||||
| <text><![CDATA[路綫]]></text> | <text><![CDATA[路綫]]></text> | ||||
| </staticText> | </staticText> | ||||
| <staticText> | <staticText> | ||||
| <reportElement x="150" y="4" width="80" height="18" uuid="65c27cc0-f806-4930-930c-6b3fd632a52f"> | |||||
| <reportElement x="150" y="5" width="80" height="18" uuid="65c27cc0-f806-4930-930c-6b3fd632a52f"> | |||||
| <property name="com.jaspersoft.studio.unit.y" value="px"/> | <property name="com.jaspersoft.studio.unit.y" value="px"/> | ||||
| <property name="com.jaspersoft.studio.unit.height" value="px"/> | <property name="com.jaspersoft.studio.unit.height" value="px"/> | ||||
| </reportElement> | </reportElement> | ||||
| <textElement textAlignment="Left"> | |||||
| <textElement textAlignment="Left" verticalAlignment="Middle"> | |||||
| <font fontName="微軟正黑體" size="12"/> | <font fontName="微軟正黑體" size="12"/> | ||||
| </textElement> | </textElement> | ||||
| <text><![CDATA[貨品編號]]></text> | <text><![CDATA[貨品編號]]></text> | ||||
| @@ -283,7 +283,7 @@ | |||||
| <property name="com.jaspersoft.studio.unit.y" value="px"/> | <property name="com.jaspersoft.studio.unit.y" value="px"/> | ||||
| <property name="com.jaspersoft.studio.unit.height" value="px"/> | <property name="com.jaspersoft.studio.unit.height" value="px"/> | ||||
| </reportElement> | </reportElement> | ||||
| <textElement textAlignment="Left"> | |||||
| <textElement textAlignment="Left" verticalAlignment="Middle"> | |||||
| <font fontName="微軟正黑體" size="12"/> | <font fontName="微軟正黑體" size="12"/> | ||||
| </textElement> | </textElement> | ||||
| <text><![CDATA[貨品名稱]]></text> | <text><![CDATA[貨品名稱]]></text> | ||||
| @@ -315,7 +315,7 @@ | |||||
| <detail> | <detail> | ||||
| <band height="42"> | <band height="42"> | ||||
| <textField> | <textField> | ||||
| <reportElement x="0" y="1" width="40" height="18" uuid="ae87b739-dadf-452a-bc35-8c2da1a6a9a8"> | |||||
| <reportElement x="0" y="0" width="40" height="18" uuid="ae87b739-dadf-452a-bc35-8c2da1a6a9a8"> | |||||
| <property name="com.jaspersoft.studio.unit.height" value="px"/> | <property name="com.jaspersoft.studio.unit.height" value="px"/> | ||||
| </reportElement> | </reportElement> | ||||
| <textElement verticalAlignment="Middle"> | <textElement verticalAlignment="Middle"> | ||||
| @@ -324,7 +324,7 @@ | |||||
| <textFieldExpression><![CDATA[$F{sequenceNumber}]]></textFieldExpression> | <textFieldExpression><![CDATA[$F{sequenceNumber}]]></textFieldExpression> | ||||
| </textField> | </textField> | ||||
| <textField> | <textField> | ||||
| <reportElement x="40" y="1" width="110" height="18" uuid="b4bcfa6c-5d2e-4fba-815a-cc2fccd39213"> | |||||
| <reportElement x="40" y="0" width="110" height="18" uuid="b4bcfa6c-5d2e-4fba-815a-cc2fccd39213"> | |||||
| <property name="com.jaspersoft.studio.unit.height" value="px"/> | <property name="com.jaspersoft.studio.unit.height" value="px"/> | ||||
| </reportElement> | </reportElement> | ||||
| <textElement verticalAlignment="Middle"> | <textElement verticalAlignment="Middle"> | ||||
| @@ -351,10 +351,10 @@ | |||||
| <textFieldExpression><![CDATA[$F{qty} + $F{shortName}]]></textFieldExpression> | <textFieldExpression><![CDATA[$F{qty} + $F{shortName}]]></textFieldExpression> | ||||
| </textField> | </textField> | ||||
| <textField> | <textField> | ||||
| <reportElement x="230" y="1" width="240" height="18" uuid="c2b4da75-fdca-4e99-8103-5769dea75841"> | |||||
| <reportElement x="230" y="0" width="230" height="18" uuid="c2b4da75-fdca-4e99-8103-5769dea75841"> | |||||
| <property name="com.jaspersoft.studio.unit.height" value="px"/> | <property name="com.jaspersoft.studio.unit.height" value="px"/> | ||||
| </reportElement> | </reportElement> | ||||
| <textElement verticalAlignment="Top"> | |||||
| <textElement verticalAlignment="Middle"> | |||||
| <font fontName="微軟正黑體"/> | <font fontName="微軟正黑體"/> | ||||
| </textElement> | </textElement> | ||||
| <textFieldExpression><![CDATA[$F{itemName} + "(" + $F{uom} + ")"]]></textFieldExpression> | <textFieldExpression><![CDATA[$F{itemName} + "(" + $F{uom} + ")"]]></textFieldExpression> | ||||
| @@ -365,7 +365,7 @@ | |||||
| </reportElement> | </reportElement> | ||||
| </line> | </line> | ||||
| <textField> | <textField> | ||||
| <reportElement x="230" y="18" width="240" height="18" uuid="af701932-2e78-47d4-a131-b668200dc376"> | |||||
| <reportElement x="230" y="18" width="230" height="18" uuid="af701932-2e78-47d4-a131-b668200dc376"> | |||||
| <property name="com.jaspersoft.studio.unit.height" value="px"/> | <property name="com.jaspersoft.studio.unit.height" value="px"/> | ||||
| </reportElement> | </reportElement> | ||||
| <textElement verticalAlignment="Middle"> | <textElement verticalAlignment="Middle"> | ||||
| @@ -0,0 +1,5 @@ | |||||
| -- liquibase formatted sql | |||||
| -- changeset KelvinY:add_delivery_note_code | |||||
| ALTER TABLE `fpsmsdb`.`do_pick_order_record` | |||||
| ADD COLUMN `deliveryNoteCode` VARCHAR(50) NULL AFTER `delivery_order_code`; | |||||