From c57bec2f741501af4da3fd853468d8707c82ab1f Mon Sep 17 00:00:00 2001 From: "CANCERYS\\kw093" Date: Wed, 20 May 2026 14:38:51 +0800 Subject: [PATCH] update TRF fix --- .../service/DoWorkbenchMainService.kt | 2 +- .../stock/service/StockInLineService.kt | 4 +-- .../stock/service/StockOutLineService.kt | 28 +++++++++++++------ .../service/StockOutLineWorkbenchService.kt | 2 +- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoWorkbenchMainService.kt b/src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoWorkbenchMainService.kt index e859e3c..72d084b 100644 --- a/src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoWorkbenchMainService.kt +++ b/src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoWorkbenchMainService.kt @@ -2344,7 +2344,7 @@ return MessageResponse( onHandQtyBeforeUpdate: Double?, ): Double { if (onHandQtyBeforeUpdate != null) return onHandQtyBeforeUpdate - val latestLedger = stockLedgerRepository.findLatestByItemId(itemId).firstOrNull() + val latestLedger = stockLedgerRepository.findFirstByItemIdAndDeletedFalseOrderByDateDescIdDesc(itemId) return latestLedger?.balance ?: (inventory.onHandQty ?: BigDecimal.ZERO).toDouble() } 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 a0d2906..75bb2f6 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 @@ -221,7 +221,7 @@ open class StockInLineService( ) } */ - fun assignLotNo(): String { + open fun assignLotNo(): String { val prefix = "LT" val midfix = LocalDate.now().format(CodeGenerator.DEFAULT_FORMATTER) val fullPrefix = "$prefix-$midfix" @@ -248,7 +248,7 @@ open class StockInLineService( * - 年份使用兩位數(例如 2026-03-18 -> 260318) * - 序號仍然與現有規則一致,且跨 inventory_lot / stock_in_line 同步遞增 */ - fun assignLotNoForJo(planStart: LocalDate?): String { + open fun assignLotNoForJo(planStart: LocalDate?): String { val prefix = "LT" val date = planStart ?: LocalDate.now() // 兩位數年份 + MMdd,例如 2026-03-18 -> "260318" 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 f1c43b9..0a9671d 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 @@ -1512,7 +1512,7 @@ open fun newBatchSubmit(request: QrPickBatchSubmitRequest): MessageResponse { val outQty = stockOutLine.qty?.toDouble() ?: 0.0 // Use latest ledger balance (same pattern as createStockLedgerForStockIn) so balance is correct when multiple actions run in one transaction - val latestLedger = stockLedgerRepository.findLatestByItemId(item.id!!).firstOrNull() + val latestLedger = stockLedgerRepository.findFirstByItemIdAndDeletedFalseOrderByDateDescIdDesc(item.id!!) val previousBalance = latestLedger?.balance ?: (inventory.onHandQty ?: BigDecimal.ZERO).toDouble() val newBalance = previousBalance - outQty @@ -1818,7 +1818,7 @@ open fun newBatchSubmit(request: QrPickBatchSubmitRequest): MessageResponse { if (onHandQtyBeforeUpdate != null) { return onHandQtyBeforeUpdate } - val latestLedger = stockLedgerRepository.findLatestByItemId(itemId).firstOrNull() + val latestLedger = stockLedgerRepository.findFirstByItemIdAndDeletedFalseOrderByDateDescIdDesc(itemId) return latestLedger?.balance ?: (inventory.onHandQty ?: BigDecimal.ZERO).toDouble() } @@ -2309,12 +2309,23 @@ open fun createStockOutBatch(request: BatchStockOutRequest): BatchStockOutResult val savedLines = stockOutLineRepository.saveAll(stockOutLinesToInsert) // 5) 批量组装 ledger(避免每笔 createStockLedgerForStockOut) - savedLines.forEach { sol -> + // Keep per-item running balance so multiple lines in the same batch + // chain from the previous ledger balance instead of reusing inventory.onHandQty. + val runningLedgerBalanceByItemId = mutableMapOf() + val inventoryByItemId = mutableMapOf() + savedLines.sortedBy { it.id ?: Long.MAX_VALUE }.forEach { sol -> val item = sol.item ?: return@forEach - val inv = itemUomService.findInventoryForItemBaseUom(item.id!!) ?: return@forEach + val itemId = item.id ?: return@forEach + val inv = inventoryByItemId[itemId] + ?: itemUomService.findInventoryForItemBaseUom(itemId)?.also { inventoryByItemId[itemId] = it } + ?: return@forEach val delta = BigDecimal.valueOf(sol.qty ?: 0.0) - val prevBalance = inv.onHandQty?.toDouble() ?: 0.0 -val newBalance = prevBalance - delta.toDouble() + val prevBalance = runningLedgerBalanceByItemId[itemId] + ?: run { + val latestLedger = stockLedgerRepository.findFirstByItemIdAndDeletedFalseOrderByDateDescIdDesc(itemId) + latestLedger?.balance ?: (inv.onHandQty ?: BigDecimal.ZERO).toDouble() + } + val newBalance = prevBalance - delta.toDouble() ledgersToInsert += StockLedger().apply { this.stockOutLine = sol @@ -2323,12 +2334,13 @@ val newBalance = prevBalance - delta.toDouble() this.outQty = delta.toDouble() this.balance = newBalance this.type = request.type - this.itemId = item.id + this.itemId = itemId this.itemCode = item.code - this.uomId = itemUomRespository.findByItemIdAndStockUnitIsTrueAndDeletedIsFalse(item.id!!)?.uom?.id + this.uomId = itemUomRespository.findByItemIdAndStockUnitIsTrueAndDeletedIsFalse(itemId)?.uom?.id ?: inv.uom?.id this.date = today } + runningLedgerBalanceByItemId[itemId] = newBalance } stockLedgerRepository.saveAll(ledgersToInsert) diff --git a/src/main/java/com/ffii/fpsms/modules/stock/service/StockOutLineWorkbenchService.kt b/src/main/java/com/ffii/fpsms/modules/stock/service/StockOutLineWorkbenchService.kt index 5c3b449..013fd73 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/service/StockOutLineWorkbenchService.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/service/StockOutLineWorkbenchService.kt @@ -527,7 +527,7 @@ if (updated == 0) { onHandQtyBeforeUpdate: Double?, ): Double { if (onHandQtyBeforeUpdate != null) return onHandQtyBeforeUpdate - val latestLedger = stockLedgerRepository.findLatestByItemId(itemId).firstOrNull() + val latestLedger = stockLedgerRepository.findFirstByItemIdAndDeletedFalseOrderByDateDescIdDesc(itemId) return latestLedger?.balance ?: (inventory.onHandQty ?: BigDecimal.ZERO).toDouble() }