From ebf0f51d900d7f80c8e0f7e7f52d7ce66a8725a0 Mon Sep 17 00:00:00 2001 From: "CANCERYS\\kw093" Date: Wed, 8 Apr 2026 01:17:48 +0800 Subject: [PATCH] update --- .../pickOrder/service/PickOrderService.kt | 61 ++++++++++++------- .../stock/service/StockOutLineService.kt | 28 ++++++--- 2 files changed, 58 insertions(+), 31 deletions(-) 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 92c45b5..9ce1158 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 @@ -4062,17 +4062,9 @@ println("DEBUG sol polIds in linesResults: " + linesResults.mapNotNull { it["sto message = "Cannot resolve new inventory lot line", errorPosition = null ) - if (newIll.status == InventoryLotLineStatus.UNAVAILABLE) { - return MessageResponse( - id = null, - name = "Lot line unavailable", - code = "LOT_UNAVAILABLE", - type = "pickorder", - message = "Cannot switch to unavailable inventory lot line", - errorPosition = null - ) - } + val targetUnavailable = newIll.status == InventoryLotLineStatus.UNAVAILABLE + // Item consistency check val newItemId = newIll.inventoryLot?.item?.id if (newItemId == null || newItemId != polItemId) { @@ -4108,21 +4100,48 @@ println("DEBUG sol polIds in linesResults: " + linesResults.mapNotNull { it["sto ) } - // Availability check on newIll BEFORE updates - val inQty = newIll.inQty ?: zero - val outQty = newIll.outQty ?: zero - val holdQty = newIll.holdQty ?: zero - val issueQty = newIll.issueQty ?: zero - val available = inQty.subtract(outQty).subtract(holdQty).subtract(issueQty) + if (!targetUnavailable) { + // Availability check on newIll BEFORE updates + val inQty = newIll.inQty ?: zero + val outQty = newIll.outQty ?: zero + val holdQty = newIll.holdQty ?: zero + //val issueQty = newIll.issueQty ?: zero + val available = inQty.subtract(outQty).subtract(holdQty)//.subtract(issueQty) + + if (available.compareTo(qtyToHold) < 0) { + return MessageResponse( + id = null, name = "Insufficient lot qty", code = "REJECT", type = "pickorder", + message = "Reject switch lot: available=$available < required=$qtyToHold", errorPosition = null + ) + } + } - if (available.compareTo(qtyToHold) < 0) { + val oldIll = spl.suggestedLotLine + + // Allow switch to UNAVAILABLE lot, but do NOT move hold/onHold and do NOT alter SOL status. + if (targetUnavailable) { + spl.suggestedLotLine = newIll + suggestPickLotRepository.saveAndFlush(spl) + + if (req.stockOutLineId != null && req.stockOutLineId > 0) { + val sol = stockOutLIneRepository.findById(req.stockOutLineId).orElse(null) + if (sol != null) { + sol.inventoryLotLine = newIll + sol.item = pol.item + stockOutLIneRepository.saveAndFlush(sol) + } + } + + val newLotNo = newIll.inventoryLot?.lotNo ?: req.newInventoryLotNo return MessageResponse( - id = null, name = "Insufficient lot qty", code = "REJECT", type = "pickorder", - message = "Reject switch lot: available=$available < required=$qtyToHold", errorPosition = null + id = null, + name = "Lot substitution confirmed (unavailable lot bound)", + code = "SUCCESS_UNAVAILABLE", + type = "pickorder", + message = "Switched to unavailable lot '$newLotNo' without hold movement and without stock out status update", + errorPosition = null ) } - - val oldIll = spl.suggestedLotLine // Load stock out line (if provided) to decide "bind vs split" val existingSol = if (req.stockOutLineId != null && req.stockOutLineId > 0) { diff --git a/src/main/java/com/ffii/fpsms/modules/stock/service/StockOutLineService.kt b/src/main/java/com/ffii/fpsms/modules/stock/service/StockOutLineService.kt index 597e784..41f13af 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/service/StockOutLineService.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/service/StockOutLineService.kt @@ -1012,16 +1012,9 @@ open fun updateStockOutLineStatusByQRCodeAndLotNo(request: UpdateStockOutLineSta errorPosition = null ) } - if (resolved.status == InventoryLotLineStatus.UNAVAILABLE) { - println(" Reject noLot bind: resolved InventoryLotLine id=${resolved.id} is UNAVAILABLE") - return MessageResponse( - id = null, - name = "Lot line unavailable", - code = "LOT_UNAVAILABLE", - type = "error", - message = "Cannot confirm scan: target inventory lot line is unavailable", - errorPosition = null - ) + val targetUnavailable = resolved.status == InventoryLotLineStatus.UNAVAILABLE + if (targetUnavailable) { + println(" noLot bind target is UNAVAILABLE (id=${resolved.id}), will bind only without status update") } // Bind the lot line to this stockOutLine so subsequent operations can proceed stockOutLine.inventoryLotLine = resolved @@ -1077,6 +1070,21 @@ open fun updateStockOutLineStatusByQRCodeAndLotNo(request: UpdateStockOutLineSta println(" - Item ID match: $itemIdMatch (Expected: ${inventoryLot.item?.id}, Got: ${request.itemId})") if (lotNoMatch && itemIdMatch) { + val targetUnavailable = inventoryLotLine.status == InventoryLotLineStatus.UNAVAILABLE + if (targetUnavailable) { + println(" Target lot is UNAVAILABLE. Bind kept, skip stockOutLine status update.") + val savedStockOutLine = stockOutLineRepository.saveAndFlush(stockOutLine) + val mappedStockOutLine = stockOutLineRepository.findStockOutLineInfoById(savedStockOutLine.id!!) + return MessageResponse( + id = savedStockOutLine.id, + name = inventoryLot.lotNo, + code = "BOUND_UNAVAILABLE", + type = savedStockOutLine.status, + message = "Bound to unavailable lot without stock out line status update", + errorPosition = null, + entity = mappedStockOutLine + ) + } println(" MATCH SUCCESS: Lot and Item both match!")