|
|
|
@@ -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<Long, Double>() |
|
|
|
val inventoryByItemId = mutableMapOf<Long, Inventory>() |
|
|
|
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) |
|
|
|
|
|
|
|
|