From 0cc69229ea6963e7c836c2db3bdc1b8041197fe4 Mon Sep 17 00:00:00 2001 From: "CANCERYS\\kw093" Date: Thu, 30 Oct 2025 22:42:44 +0800 Subject: [PATCH] update --- .../service/DoPickOrderService.kt | 2 +- .../pickOrder/entity/PickExecutionIssue.kt | 12 +- .../service/PickExecutionIssueService.kt | 8 +- .../pickOrder/service/PickOrderService.kt | 12 +- .../stock/service/StockOutLineService.kt | 234 ++++++++++++++---- 5 files changed, 207 insertions(+), 61 deletions(-) diff --git a/src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoPickOrderService.kt b/src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoPickOrderService.kt index 5210974..6634ae5 100644 --- a/src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoPickOrderService.kt +++ b/src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoPickOrderService.kt @@ -58,7 +58,7 @@ open class DoPickOrderService( @Lazy private val deliveryOrderRepository: DeliveryOrderRepository, private val doPickOrderLineRecordRepository: DoPickOrderLineRecordRepository ) { - fun findReleasedDoPickOrders(): List { + open fun findReleasedDoPickOrders(): List { return doPickOrderRepository.findByTicketStatusIn( listOf(DoPickOrderStatus.released, DoPickOrderStatus.pending) ) diff --git a/src/main/java/com/ffii/fpsms/modules/pickOrder/entity/PickExecutionIssue.kt b/src/main/java/com/ffii/fpsms/modules/pickOrder/entity/PickExecutionIssue.kt index 6c034fc..cefb95c 100644 --- a/src/main/java/com/ffii/fpsms/modules/pickOrder/entity/PickExecutionIssue.kt +++ b/src/main/java/com/ffii/fpsms/modules/pickOrder/entity/PickExecutionIssue.kt @@ -13,8 +13,8 @@ class PickExecutionIssue( @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Long? = null, - @Column(name = "pick_order_id", nullable = false) - val pickOrderId: Long, + @Column(name = "pick_order_id", nullable = true) + val pickOrderId: Long? = null, @Column(name = "pick_order_code", length = 50, nullable = false) val pickOrderCode: String, @@ -30,8 +30,8 @@ val joPickOrderId: Long? = null, @Column(name = "Do_pick_order_id") val doPickOrderId: Long? = null, - @Column(name = "pick_order_line_id", nullable = false) - val pickOrderLineId: Long, + @Column(name = "pick_order_line_id", nullable = true) + val pickOrderLineId: Long? = null, @Column(name = "issue_no", length = 50) val issueNo: String? = null, @@ -105,11 +105,11 @@ val doPickOrderId: Long? = null, ) { // ✅ 添加默认构造函数 constructor() : this( - pickOrderId = 0L, + pickOrderId = null, pickOrderCode = "", pickOrderCreateDate = null, pickExecutionDate = null, - pickOrderLineId = 0L, + pickOrderLineId = null, itemId = 0L, itemCode = null, itemDescription = null, diff --git a/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickExecutionIssueService.kt b/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickExecutionIssueService.kt index b8d5c44..42fd4ae 100644 --- a/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickExecutionIssueService.kt +++ b/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickExecutionIssueService.kt @@ -711,8 +711,8 @@ open fun createBatchReleaseIssue( val linesSql = """ SELECT dol.id, dol.itemId, i.code as itemCode, i.name as itemName, dol.qty FROM fpsmsdb.delivery_order_line dol - INNER JOIN fpsmsdb.item i ON i.id = dol.itemId - WHERE dol.doId = :deliveryOrderId + INNER JOIN fpsmsdb.items i ON i.id = dol.itemId + WHERE dol.deliveryOrderId = :deliveryOrderId AND dol.deleted = 0 """.trimIndent() @@ -736,11 +736,11 @@ open fun createBatchReleaseIssue( val issue = PickExecutionIssue( id = null, - pickOrderId = 0L, // batch release 失败时可能还没有 pick order + pickOrderId = null, // batch release 失败时可能还没有 pick order pickOrderCode = deliveryOrder["code"] as? String ?: "", pickOrderCreateDate = LocalDate.now(), pickExecutionDate = LocalDate.now(), - pickOrderLineId = 0L, // batch release 失败时可能还没有 pick order line + pickOrderLineId = null, // batch release 失败时可能还没有 pick order line issueNo = issueNo, joPickOrderId = null, doPickOrderId = null, diff --git a/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderService.kt b/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderService.kt index b71b17b..70e2b07 100644 --- a/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderService.kt +++ b/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderService.kt @@ -3566,7 +3566,8 @@ open fun getAllPickOrderLotsWithDetailsHierarchical(userId: Long): Map(jdbcDao, stockOutLineRepository) { @Throws(IOException::class) @Transactional @@ -325,6 +342,86 @@ private fun getStockOutIdFromPickOrderLine(pickOrderLineId: Long): Long { }) } } + private fun completeDoIfAllPickOrdersCompleted(pickOrderId: Long) { + // 1) 先用 line 关联找 do_pick_order_id + val lines = doPickOrderLineRepository.findByPickOrderIdAndDeletedFalse(pickOrderId) + val doPickOrderIds = + if (lines.isNotEmpty()) lines.mapNotNull { it.doPickOrderId }.distinct() + else doPickOrderRepository.findByPickOrderId(pickOrderId).mapNotNull { it.id } // 兼容旧设计 + + doPickOrderIds.forEach { dpoId -> + val allLines = doPickOrderLineRepository.findByDoPickOrderIdAndDeletedFalse(dpoId) + val allPickOrderIdsInDpo = if (allLines.isNotEmpty()) + allLines.mapNotNull { it.pickOrderId }.distinct() + else + doPickOrderRepository.findById(dpoId).orElse(null)?.pickOrderId?.let { listOf(it) } ?: emptyList() + + if (allPickOrderIdsInDpo.isEmpty()) return@forEach + + // 2) 检查这个 do_pick_order 下所有 pick orders 是否都 COMPLETED + val statuses = allPickOrderIdsInDpo.map { id -> + pickOrderRepository.findById(id).orElse(null)?.status + } + val allCompleted = statuses.all { it == PickOrderStatus.COMPLETED } + + if (!allCompleted) return@forEach + + // 3) 全部完成 → 更新 do_pick_order 为 completed,并可复制到 record 表(可选) + val dpo = doPickOrderRepository.findById(dpoId).orElse(null) ?: return@forEach + dpo.ticketStatus = DoPickOrderStatus.completed + dpo.ticketCompleteDateTime = LocalDateTime.now() + doPickOrderRepository.save(dpo) + + // 4) 可选:复制 header 到 record 表,复制 lines 到 line_record,再删除原有行/头(与你在 PickOrderService.completeStockOut 的做法保持一致) + val dpoRecord = DoPickOrderRecord( + storeId = dpo.storeId ?: "", + ticketNo = dpo.ticketNo ?: "", + ticketStatus = DoPickOrderStatus.completed, + truckId = dpo.truckId, + pickOrderId = dpo.pickOrderId, + truckDepartureTime = dpo.truckDepartureTime, + shopId = dpo.shopId, + handledBy = dpo.handledBy, + handlerName = dpo.handlerName, + doOrderId = dpo.doOrderId, + pickOrderCode = dpo.pickOrderCode, + deliveryOrderCode = dpo.deliveryOrderCode, + loadingSequence = dpo.loadingSequence, + ticketReleaseTime = dpo.ticketReleaseTime, + ticketCompleteDateTime = LocalDateTime.now(), + truckLanceCode = dpo.truckLanceCode, + shopCode = dpo.shopCode, + shopName = dpo.shopName, + requiredDeliveryDate = dpo.requiredDeliveryDate + ) + val savedHeader = doPickOrderRecordRepository.save(dpoRecord) + + val lineRecords = allLines.map { l -> + DoPickOrderLineRecord().apply { + this.doPickOrderId = savedHeader.id + this.pickOrderId = l.pickOrderId + this.doOrderId = l.doOrderId + this.pickOrderCode = l.pickOrderCode + this.deliveryOrderCode = l.deliveryOrderCode + this.status = l.status + } + } + if (lineRecords.isNotEmpty()) doPickOrderLineRecordRepository.saveAll(lineRecords) + + // 若你流程要求,把原行/头删掉(或保留 completed 状态) + if (allLines.isNotEmpty()) doPickOrderLineRepository.deleteAll(allLines) + doPickOrderRepository.delete(dpo) + + // 5) 可选:同步 delivery_order → COMPLETED + dpo.doOrderId?.let { doId -> + val deliveryOrder = deliveryOrderRepository.findByIdAndDeletedIsFalse(doId) + if (deliveryOrder != null && deliveryOrder.status != DeliveryOrderStatus.COMPLETED) { + deliveryOrder.status = DeliveryOrderStatus.COMPLETED + deliveryOrderRepository.save(deliveryOrder) + } + } + } + } @Transactional open fun update(request: UpdateStockOutLineRequest): MessageResponse { val stockOutLine = stockOutLineRepository.findById(request.id).orElseThrow() @@ -373,54 +470,101 @@ private fun getStockOutIdFromPickOrderLine(pickOrderLineId: Long): Long { entity = lineInfoList, ) } + private fun completeDoForPickOrder(pickOrderId: Long) { + // 1) 原表 do_pick_order → completed + val dpos = doPickOrderRepository.findByPickOrderId(pickOrderId) + if (dpos.isNotEmpty()) { + dpos.forEach { + it.ticketStatus = com.ffii.fpsms.modules.deliveryOrder.enums.DoPickOrderStatus.completed + it.ticketCompleteDateTime = java.time.LocalDateTime.now() + } + doPickOrderRepository.saveAll(dpos) - @Transactional -open fun updateStatus(request: UpdateStockOutLineStatusRequest): MessageResponse { - try { - val stockOutLine = stockOutLineRepository.findById(request.id).orElseThrow { - IllegalArgumentException("StockOutLine not found with ID: ${request.id}") - } - - println("Updating StockOutLine ID: ${request.id}") - println("Current status: ${stockOutLine.status}") - println("New status: ${request.status}") - - // Update status - stockOutLine.status = request.status - - // Update quantity if provided - if (request.qty != null) { - val currentQty = stockOutLine.qty?.toDouble() ?: 0.0 - val newQty = currentQty + request.qty - stockOutLine.qty = (newQty) + // 2) 同步相关 delivery_order 状态 + dpos.forEach { dpo -> + dpo.doOrderId?.let { doId -> + val deliveryOrder = deliveryOrderRepository.findByIdAndDeletedIsFalse(doId) + if (deliveryOrder != null && + deliveryOrder.status != com.ffii.fpsms.modules.deliveryOrder.enums.DeliveryOrderStatus.COMPLETED + ) { + deliveryOrder.status = com.ffii.fpsms.modules.deliveryOrder.enums.DeliveryOrderStatus.COMPLETED + deliveryOrderRepository.save(deliveryOrder) + } + } + } } - val savedStockOutLine = stockOutLineRepository.saveAndFlush(stockOutLine) - println("Updated StockOutLine: ${savedStockOutLine.id} with status: ${savedStockOutLine.status}") - - // ✅ FIX: Only call once and add debugging - if (request.status == "rejected" || request.status == "REJECTED") { - println("=== TRIGGERING LOT REJECTION LOGIC ===") - handleLotRejectionFromStockOutLine(savedStockOutLine) + // 3) 记录表 do_pick_order_record → completed(可选) + val dporList = doPickOrderRecordRepository.findByPickOrderId(pickOrderId) + if (dporList.isNotEmpty()) { + dporList.forEach { + it.ticketStatus = com.ffii.fpsms.modules.deliveryOrder.enums.DoPickOrderStatus.completed + it.ticketCompleteDateTime = java.time.LocalDateTime.now() + } + doPickOrderRecordRepository.saveAll(dporList) + } + } + open fun updateStatus(request: UpdateStockOutLineStatusRequest): MessageResponse { + try { + // 1. 查当前 stockOutLine + val stockOutLine = stockOutLineRepository.findById(request.id).orElseThrow { + IllegalArgumentException("StockOutLine not found with ID: ${request.id}") + } + + println("Updating StockOutLine ID: ${request.id}") + println("Current status: ${stockOutLine.status}") + println("New status: ${request.status}") + + // 2. 更新自身 status/qty + stockOutLine.status = request.status + if (request.qty != null) { + val currentQty = stockOutLine.qty?.toDouble() ?: 0.0 + val newQty = currentQty + request.qty + stockOutLine.qty = (newQty) + } + val savedStockOutLine = stockOutLineRepository.saveAndFlush(stockOutLine) + println("Updated StockOutLine: ${savedStockOutLine.id} with status: ${savedStockOutLine.status}") + + // 3. 如果被拒绝,触发特殊处理 + if (request.status == "rejected" || request.status == "REJECTED") { + println("=== TRIGGERING LOT REJECTION LOGIC ===") + handleLotRejectionFromStockOutLine(savedStockOutLine) + } + + // 4. 自动刷 pickOrderLine 状态 + val pickOrderLine = stockOutLine.pickOrderLine + if (pickOrderLine != null) { + checkIsStockOutLineCompleted(pickOrderLine.id) + // 5. 自动刷 pickOrder 状态 + val pickOrder = pickOrderLine.pickOrder + if (pickOrder != null) { + val allLines = pickOrder.pickOrderLines + val allCompleted = allLines.all { it.status == PickOrderLineStatus.COMPLETED } + if (allCompleted && allLines.isNotEmpty()) { + pickOrder.status = PickOrderStatus.COMPLETED + pickOrderRepository.save(pickOrder) + completeDoForPickOrder(pickOrder.id!!) + completeDoIfAllPickOrdersCompleted(pickOrder.id!!) + } + } + } + + val mappedSavedStockOutLine = stockOutLineRepository.findStockOutLineInfoById(savedStockOutLine.id!!) + return MessageResponse( + id = savedStockOutLine.id, + name = savedStockOutLine.inventoryLotLine!!.inventoryLot!!.lotNo, + code = savedStockOutLine.stockOut!!.consoPickOrderCode, + type = savedStockOutLine.status, + message = "Stock out line status updated successfully", + errorPosition = null, + entity = mappedSavedStockOutLine, + ) + } catch (e: Exception) { + println("Error updating stock out line status: ${e.message}") + e.printStackTrace() + throw e } - - val mappedSavedStockOutLine = stockOutLineRepository.findStockOutLineInfoById(savedStockOutLine.id!!) - - return MessageResponse( - id = savedStockOutLine.id, - name = savedStockOutLine.inventoryLotLine!!.inventoryLot!!.lotNo, - code = savedStockOutLine.stockOut!!.consoPickOrderCode, - type = savedStockOutLine.status, - message = "Stock out line status updated successfully", - errorPosition = null, - entity = mappedSavedStockOutLine, - ) - } catch (e: Exception) { - println("Error updating stock out line status: ${e.message}") - e.printStackTrace() - throw e } -} // ✅ ADD THIS: Handle lot rejection when stock out line is rejected private fun handleLotRejectionFromStockOutLine(stockOutLine: StockOutLine) { try {