From 70f620959a1d5a9e33b2823cb53c07e0383480fd Mon Sep 17 00:00:00 2001 From: "vluk@2fi-solutions.com.hk" Date: Tue, 7 Jul 2026 18:05:52 +0800 Subject: [PATCH] fixing the GRN duplicated item bug for same PO --- .../stock/service/StockInLineService.kt | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/ffii/fpsms/modules/stock/service/StockInLineService.kt b/src/main/java/com/ffii/fpsms/modules/stock/service/StockInLineService.kt index f31b7a3..67d3f98 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/service/StockInLineService.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/service/StockInLineService.kt @@ -835,7 +835,7 @@ open class StockInLineService( syncPurchaseOrderLineM18LotFromM18(savedPo) // Completed lines for GRN: either this receipt date only (multi-delivery POs) or all completed on PO (legacy). - val linesForGrn = if (grnReceiptDate != null) { + val candidateLines = if (grnReceiptDate != null) { stockInLineRepository.findCompletedByPurchaseOrderIdAndReceiptDateAndDeletedFalseWithItemNames( savedPo.id!!, grnReceiptDate, @@ -843,20 +843,29 @@ open class StockInLineService( } else { stockInLineRepository.findCompletedByPurchaseOrderIdAndDeletedFalseWithItemNames(savedPo.id!!) } - if (linesForGrn.isEmpty()) { + if (candidateLines.isEmpty()) { logger.info("[tryUpdatePurchaseOrderAndCreateGrnIfCompleted] DEBUG: Skipping M18 GRN - no stock-in lines for PO id=${savedPo.id} code=${savedPo.code}") return } - if (grnReceiptDate != null && linesForGrn.all { sil -> - val id = sil.id ?: return@all false - m18GoodsReceiptNoteLogRepository.existsByStockInLineIdAndStatusTrue(id) - }) { + val linesForGrn = candidateLines.filter { sil -> + val id = sil.id ?: return@filter true + !m18GoodsReceiptNoteLogRepository.existsByStockInLineIdAndStatusTrue(id) + } + if (linesForGrn.isEmpty()) { logger.info( - "[tryUpdatePurchaseOrderAndCreateGrnIfCompleted] Skipping M18 GRN — all ${linesForGrn.size} line(s) for PO id=${savedPo.id} " + - "code=${savedPo.code} on receipt date $grnReceiptDate already have successful GRN logs" + "[tryUpdatePurchaseOrderAndCreateGrnIfCompleted] Skipping M18 GRN — all ${candidateLines.size} line(s) for PO id=${savedPo.id} " + + "code=${savedPo.code}${grnReceiptDate?.let { " on receipt date $it" } ?: ""} already have successful GRN logs" ) return } + val alreadySyncedCount = candidateLines.size - linesForGrn.size + if (alreadySyncedCount > 0) { + logger.info( + "[tryUpdatePurchaseOrderAndCreateGrnIfCompleted] PO id=${savedPo.id} code=${savedPo.code}: " + + "excluding $alreadySyncedCount stock-in line(s) already in successful M18 GRN log; " + + "sending ${linesForGrn.size} new line(s)${grnReceiptDate?.let { " for receipt date $it" } ?: ""}" + ) + } if (savedPo.m18BeId == null || savedPo.supplier?.m18Id == null || savedPo.currency?.m18Id == null) { logger.info("[tryUpdatePurchaseOrderAndCreateGrnIfCompleted] DEBUG: Skipping M18 GRN - missing M18 ids for PO id=${savedPo.id} code=${savedPo.code}. m18BeId=${savedPo.m18BeId}, supplier.m18Id=${savedPo.supplier?.m18Id}, currency.m18Id=${savedPo.currency?.m18Id}") return