|
|
@@ -42,6 +42,8 @@ import com.ffii.fpsms.modules.stock.entity.InventoryRepository |
|
|
import com.ffii.fpsms.modules.stock.entity.StockLedger |
|
|
import com.ffii.fpsms.modules.stock.entity.StockLedger |
|
|
import java.time.LocalDate |
|
|
import java.time.LocalDate |
|
|
import com.ffii.fpsms.modules.stock.entity.InventoryLotLine |
|
|
import com.ffii.fpsms.modules.stock.entity.InventoryLotLine |
|
|
|
|
|
import java.math.RoundingMode |
|
|
|
|
|
import com.ffii.fpsms.modules.stock.entity.StockTake |
|
|
@Service |
|
|
@Service |
|
|
class StockTakeRecordService( |
|
|
class StockTakeRecordService( |
|
|
val stockTakeRepository: StockTakeRepository, |
|
|
val stockTakeRepository: StockTakeRepository, |
|
|
@@ -392,7 +394,8 @@ class StockTakeRecordService( |
|
|
remarks = null, |
|
|
remarks = null, |
|
|
warehouseSlot = warehouse?.slot, |
|
|
warehouseSlot = warehouse?.slot, |
|
|
warehouseArea = warehouse?.area, |
|
|
warehouseArea = warehouse?.area, |
|
|
warehouse = warehouse?.warehouse |
|
|
|
|
|
|
|
|
warehouse = warehouse?.warehouse, |
|
|
|
|
|
bookQty = null, |
|
|
|
|
|
|
|
|
) |
|
|
) |
|
|
} |
|
|
} |
|
|
@@ -483,20 +486,26 @@ class StockTakeRecordService( |
|
|
approverQty = stockTakeRecord?.approverStockTakeQty, |
|
|
approverQty = stockTakeRecord?.approverStockTakeQty, |
|
|
approverBadQty = stockTakeRecord?.approverBadQty, |
|
|
approverBadQty = stockTakeRecord?.approverBadQty, |
|
|
finalQty = stockTakeLine?.finalQty, |
|
|
finalQty = stockTakeLine?.finalQty, |
|
|
|
|
|
bookQty = stockTakeRecord?.bookQty, |
|
|
) |
|
|
) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Apply pagination |
|
|
// Apply pagination |
|
|
val pageable = PageRequest.of(pageNum, pageSize) |
|
|
val pageable = PageRequest.of(pageNum, pageSize) |
|
|
val startIndex = pageable.offset.toInt() |
|
|
|
|
|
val endIndex = minOf(startIndex + pageSize, allResults.size) |
|
|
|
|
|
val paginatedResult = if (startIndex < allResults.size) { |
|
|
|
|
|
allResults.subList(startIndex, endIndex) |
|
|
|
|
|
} else { |
|
|
|
|
|
emptyList() |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return RecordsRes(paginatedResult, allResults.size) |
|
|
|
|
|
|
|
|
val startIndex = pageable.offset.toInt() |
|
|
|
|
|
val filteredResults = allResults.filter { response -> |
|
|
|
|
|
val av = response.availableQty ?: BigDecimal.ZERO |
|
|
|
|
|
// 显示: availableQty > 0,或已有盘点记录(即使盘点结果为 0) |
|
|
|
|
|
av.compareTo(BigDecimal.ZERO) > 0 || response.stockTakeRecordId != null |
|
|
|
|
|
} |
|
|
|
|
|
// endIndex 必須基於 filteredResults.size,不能用 allResults.size |
|
|
|
|
|
val endIndex = minOf(startIndex + pageSize, filteredResults.size) |
|
|
|
|
|
val paginatedResult = if (startIndex < filteredResults.size) { |
|
|
|
|
|
filteredResults.subList(startIndex, endIndex) |
|
|
|
|
|
} else { |
|
|
|
|
|
emptyList() |
|
|
|
|
|
} |
|
|
|
|
|
return RecordsRes(paginatedResult, filteredResults.size) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
open fun saveStockTakeRecord( |
|
|
open fun saveStockTakeRecord( |
|
|
@@ -888,142 +897,10 @@ class StockTakeRecordService( |
|
|
inventoryLot.item?.id ?: throw IllegalArgumentException("Item ID not found") |
|
|
inventoryLot.item?.id ?: throw IllegalArgumentException("Item ID not found") |
|
|
).orElse(null) ?: throw IllegalArgumentException("Inventory not found for item") |
|
|
).orElse(null) ?: throw IllegalArgumentException("Inventory not found for item") |
|
|
|
|
|
|
|
|
// 只有 variance != 0 时才做调整 |
|
|
|
|
|
if (varianceQty != BigDecimal.ZERO) { |
|
|
|
|
|
// 新增一条 StockTakeLine 记录 |
|
|
|
|
|
val stockTakeLine = StockTakeLine().apply { |
|
|
|
|
|
this.stockTake = stockTake |
|
|
|
|
|
this.inventoryLotLine = inventoryLotLine |
|
|
|
|
|
this.initialQty = stockTakeRecord.bookQty |
|
|
|
|
|
this.finalQty = finalQty |
|
|
|
|
|
this.status = StockTakeLineStatus.COMPLETED |
|
|
|
|
|
this.completeDate = java.time.LocalDateTime.now() |
|
|
|
|
|
} |
|
|
|
|
|
stockTakeLineRepository.save(stockTakeLine) |
|
|
|
|
|
|
|
|
|
|
|
// variance < 0:做出库,影响 outQty(减少库存) |
|
|
|
|
|
if (varianceQty < BigDecimal.ZERO) { |
|
|
|
|
|
val absVariance = varianceQty.negate() // 正数,表示实际出库数量 |
|
|
|
|
|
|
|
|
|
|
|
var stockOut = stockOutRepository.findByStockTakeIdAndDeletedFalse(stockTakeId) |
|
|
|
|
|
?: StockOut().apply { |
|
|
|
|
|
this.type = "stockTake" |
|
|
|
|
|
this.status = "completed" |
|
|
|
|
|
this.handler = request.approverId |
|
|
|
|
|
}.also { stockOutRepository.save(it) } |
|
|
|
|
|
|
|
|
|
|
|
val stockOutLine = StockOutLine().apply { |
|
|
|
|
|
this.item = inventoryLot.item |
|
|
|
|
|
this.qty = absVariance.toDouble() |
|
|
|
|
|
this.stockOut = stockOut |
|
|
|
|
|
this.inventoryLotLine = inventoryLotLine |
|
|
|
|
|
this.status = "completed" |
|
|
|
|
|
this.type = "ADJ" |
|
|
|
|
|
} |
|
|
|
|
|
stockOutLineRepository.save(stockOutLine) |
|
|
|
|
|
|
|
|
|
|
|
val newBalance = (inventory.onHandQty ?: BigDecimal.ZERO).toDouble() - absVariance.toDouble() |
|
|
|
|
|
val stockLedger = StockLedger().apply { |
|
|
|
|
|
this.inventory = inventory |
|
|
|
|
|
this.itemId = inventoryLot.item?.id |
|
|
|
|
|
this.itemCode = stockTakeRecord.itemCode |
|
|
|
|
|
this.inQty = null |
|
|
|
|
|
this.outQty = absVariance.toDouble() |
|
|
|
|
|
this.stockOutLine = stockOutLine |
|
|
|
|
|
this.balance = newBalance |
|
|
|
|
|
this.type = "TKE" |
|
|
|
|
|
this.date = LocalDate.now() |
|
|
|
|
|
} |
|
|
|
|
|
stockLedgerRepository.save(stockLedger) |
|
|
|
|
|
|
|
|
|
|
|
// 更新原来这条 InventoryLotLine 的 outQty,而不是 inQty |
|
|
|
|
|
val newOutQty = (inventoryLotLine.outQty ?: BigDecimal.ZERO).add(absVariance) |
|
|
|
|
|
val updateRequest = SaveInventoryLotLineRequest( |
|
|
|
|
|
id = inventoryLotLine.id, |
|
|
|
|
|
inventoryLotId = inventoryLotLine.inventoryLot?.id, |
|
|
|
|
|
warehouseId = inventoryLotLine.warehouse?.id, |
|
|
|
|
|
stockUomId = inventoryLotLine.stockUom?.id, |
|
|
|
|
|
inQty = inventoryLotLine.inQty, // 不改 inQty |
|
|
|
|
|
outQty = newOutQty, // 增加出库数量 |
|
|
|
|
|
holdQty = inventoryLotLine.holdQty, |
|
|
|
|
|
status = inventoryLotLine.status?.value, |
|
|
|
|
|
remarks = inventoryLotLine.remarks |
|
|
|
|
|
) |
|
|
|
|
|
inventoryLotLineService.saveInventoryLotLine(updateRequest) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// variance > 0:做入库,创建新 lot / lotLine,StockInLine 指向新 lot / lotLine |
|
|
|
|
|
if (varianceQty > BigDecimal.ZERO) { |
|
|
|
|
|
val plusQty = varianceQty |
|
|
|
|
|
|
|
|
|
|
|
var stockIn = stockInRepository.findByStockTakeIdAndDeletedFalse(stockTakeId) |
|
|
|
|
|
?: StockIn().apply { |
|
|
|
|
|
this.code = stockTake.code |
|
|
|
|
|
this.status = "completed" |
|
|
|
|
|
this.stockTake = stockTake |
|
|
|
|
|
}.also { stockInRepository.save(it) } |
|
|
|
|
|
|
|
|
|
|
|
// 1. 先创建 StockInLine(不设置 inventoryLot,因为还没有创建) |
|
|
|
|
|
val stockInLine = StockInLine().apply { |
|
|
|
|
|
this.stockTakeLine = stockTakeLine |
|
|
|
|
|
this.item = inventoryLot.item |
|
|
|
|
|
this.itemNo = stockTakeRecord.itemCode |
|
|
|
|
|
this.stockIn = stockIn |
|
|
|
|
|
this.demandQty = plusQty |
|
|
|
|
|
this.acceptedQty = plusQty |
|
|
|
|
|
this.expiryDate = inventoryLot.expiryDate |
|
|
|
|
|
this.lotNo = inventoryLot.lotNo |
|
|
|
|
|
this.status = "completed" |
|
|
|
|
|
this.type = "TKE" |
|
|
|
|
|
// 注意:此时不设置 inventoryLot 和 inventoryLotLine,因为还没有创建 |
|
|
|
|
|
} |
|
|
|
|
|
stockInLineRepository.save(stockInLine) |
|
|
|
|
|
|
|
|
|
|
|
// 2. 创建 InventoryLot(设置 stockInLine) |
|
|
|
|
|
val newInventoryLot = InventoryLot().apply { |
|
|
|
|
|
this.item = inventoryLot.item |
|
|
|
|
|
this.lotNo = inventoryLot.lotNo |
|
|
|
|
|
this.expiryDate = inventoryLot.expiryDate |
|
|
|
|
|
this.productionDate = inventoryLot.productionDate |
|
|
|
|
|
this.stockInDate = LocalDateTime.now() |
|
|
|
|
|
this.stockInLine = stockInLine // 设置 stockInLine |
|
|
|
|
|
} |
|
|
|
|
|
inventoryLotRepository.save(newInventoryLot) |
|
|
|
|
|
|
|
|
|
|
|
// 3. 创建 InventoryLotLine |
|
|
|
|
|
val newInventoryLotLine = InventoryLotLine().apply { |
|
|
|
|
|
this.inventoryLot = newInventoryLot |
|
|
|
|
|
this.warehouse = inventoryLotLine.warehouse |
|
|
|
|
|
this.stockUom = inventoryLotLine.stockUom |
|
|
|
|
|
this.inQty = plusQty |
|
|
|
|
|
this.outQty = BigDecimal.ZERO |
|
|
|
|
|
this.holdQty = BigDecimal.ZERO |
|
|
|
|
|
this.status = inventoryLotLine.status |
|
|
|
|
|
this.remarks = "Stock take adjustment (+$plusQty)" |
|
|
|
|
|
} |
|
|
|
|
|
inventoryLotLineRepository.save(newInventoryLotLine) |
|
|
|
|
|
|
|
|
|
|
|
// 4. 更新 StockInLine,设置 inventoryLot 和 inventoryLotLine |
|
|
|
|
|
stockInLine.inventoryLot = newInventoryLot |
|
|
|
|
|
stockInLine.inventoryLotLine = newInventoryLotLine |
|
|
|
|
|
stockInLineRepository.save(stockInLine) |
|
|
|
|
|
|
|
|
|
|
|
val newBalance = (inventory.onHandQty ?: BigDecimal.ZERO).toDouble() + plusQty.toDouble() |
|
|
|
|
|
val stockLedger = StockLedger().apply { |
|
|
|
|
|
this.inventory = inventory |
|
|
|
|
|
this.itemId = newInventoryLot.item?.id |
|
|
|
|
|
this.itemCode = newInventoryLot.item?.code |
|
|
|
|
|
this.inQty = plusQty.toDouble() |
|
|
|
|
|
this.outQty = null |
|
|
|
|
|
this.stockInLine = stockInLine |
|
|
|
|
|
this.balance = newBalance |
|
|
|
|
|
this.type = "Adj" |
|
|
|
|
|
this.date = LocalDate.now() |
|
|
|
|
|
} |
|
|
|
|
|
stockLedgerRepository.save(stockLedger) |
|
|
|
|
|
// 注意:正差额不再修改原来的 inventoryLotLine |
|
|
|
|
|
|
|
|
// 只有 variance != 0 时才做调整 |
|
|
|
|
|
if (varianceQty != BigDecimal.ZERO) { |
|
|
|
|
|
applyVarianceAdjustment(stockTake, stockTakeRecord, finalQty!!, varianceQty, request.approverId) |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
val stockTakeSection = savedRecord.stockTakeSection |
|
|
val stockTakeSection = savedRecord.stockTakeSection |
|
|
if (stockTakeSection != null) { |
|
|
if (stockTakeSection != null) { |
|
|
checkAndUpdateStockTakeStatus(stockTakeId, stockTakeSection) |
|
|
checkAndUpdateStockTakeStatus(stockTakeId, stockTakeSection) |
|
|
@@ -1083,11 +960,23 @@ open fun batchSaveApproverStockTakeRecords( |
|
|
|
|
|
|
|
|
val bookQty = record.bookQty ?: BigDecimal.ZERO |
|
|
val bookQty = record.bookQty ?: BigDecimal.ZERO |
|
|
val varianceQty = qty.subtract(bookQty) |
|
|
val varianceQty = qty.subtract(bookQty) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (varianceQty.compareTo(BigDecimal.ZERO) != 0) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val tolerancePercent = request.variancePercentTolerance ?: BigDecimal.ZERO |
|
|
|
|
|
val shouldSkip = if (tolerancePercent.compareTo(BigDecimal.ZERO) <= 0) { |
|
|
|
|
|
varianceQty.compareTo(BigDecimal.ZERO) != 0 // 原有逻辑:仅 variance=0 可保存 |
|
|
|
|
|
} else { |
|
|
|
|
|
if (bookQty.compareTo(BigDecimal.ZERO) == 0) { |
|
|
|
|
|
varianceQty.compareTo(BigDecimal.ZERO) != 0 |
|
|
|
|
|
} else { |
|
|
|
|
|
val threshold = bookQty.abs() |
|
|
|
|
|
.multiply(tolerancePercent) |
|
|
|
|
|
.divide(BigDecimal("100"), 10, RoundingMode.HALF_UP) |
|
|
|
|
|
varianceQty.abs().compareTo(threshold) > 0 // |variance| > threshold 则跳过 |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
if (shouldSkip) { |
|
|
skippedCount++ |
|
|
skippedCount++ |
|
|
println("Skipping record ${record.id}: variance = $varianceQty (qty=$qty, bookQty=$bookQty)") |
|
|
|
|
|
|
|
|
println("Skipping record ${record.id}: |variance| > ${tolerancePercent}% of bookQty (variance=$varianceQty, bookQty=$bookQty)") |
|
|
return@forEach |
|
|
return@forEach |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@@ -1102,6 +991,16 @@ open fun batchSaveApproverStockTakeRecords( |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
stockTakeRecordRepository.save(record) |
|
|
stockTakeRecordRepository.save(record) |
|
|
|
|
|
if (varianceQty != BigDecimal.ZERO) { |
|
|
|
|
|
try { |
|
|
|
|
|
applyVarianceAdjustment(stockTake, record, qty, varianceQty, request.approverId) |
|
|
|
|
|
} catch (e: Exception) { |
|
|
|
|
|
logger.error("Failed to apply variance adjustment for record ${record.id}", e) |
|
|
|
|
|
errorCount++ |
|
|
|
|
|
errors.add("Record ${record.id}: ${e.message}") |
|
|
|
|
|
return@forEach |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
successCount++ |
|
|
successCount++ |
|
|
} catch (e: Exception) { |
|
|
} catch (e: Exception) { |
|
|
errorCount++ |
|
|
errorCount++ |
|
|
@@ -1124,7 +1023,158 @@ open fun batchSaveApproverStockTakeRecords( |
|
|
) |
|
|
) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 根据 variance 调整库存并创建 Stock Ledger。 |
|
|
|
|
|
* 当 variance != 0 时:创建 StockTakeLine,并根据 variance 正负创建 StockIn/StockOut 及 Ledger。 |
|
|
|
|
|
*/ |
|
|
|
|
|
private fun applyVarianceAdjustment( |
|
|
|
|
|
stockTake: StockTake, |
|
|
|
|
|
stockTakeRecord: StockTakeRecord, |
|
|
|
|
|
finalQty: BigDecimal, |
|
|
|
|
|
varianceQty: BigDecimal, |
|
|
|
|
|
approverId: Long? |
|
|
|
|
|
) { |
|
|
|
|
|
if (varianceQty == BigDecimal.ZERO) return |
|
|
|
|
|
|
|
|
|
|
|
val inventoryLotLine = inventoryLotLineRepository.findByIdAndDeletedIsFalse( |
|
|
|
|
|
stockTakeRecord.inventoryLotId ?: throw IllegalArgumentException("Inventory lot ID not found") |
|
|
|
|
|
) ?: throw IllegalArgumentException("Inventory lot line not found") |
|
|
|
|
|
|
|
|
|
|
|
val inventoryLot = inventoryLotRepository.findByIdAndDeletedFalse( |
|
|
|
|
|
inventoryLotLine.inventoryLot?.id ?: throw IllegalArgumentException("Inventory lot ID not found") |
|
|
|
|
|
) ?: throw IllegalArgumentException("Inventory lot not found") |
|
|
|
|
|
|
|
|
|
|
|
val inventory = inventoryRepository.findByItemId( |
|
|
|
|
|
inventoryLot.item?.id ?: throw IllegalArgumentException("Item ID not found") |
|
|
|
|
|
).orElse(null) ?: throw IllegalArgumentException("Inventory not found for item") |
|
|
|
|
|
|
|
|
|
|
|
// 1. 创建 StockTakeLine |
|
|
|
|
|
val stockTakeLine = StockTakeLine().apply { |
|
|
|
|
|
this.stockTake = stockTake |
|
|
|
|
|
this.inventoryLotLine = inventoryLotLine |
|
|
|
|
|
this.initialQty = stockTakeRecord.bookQty |
|
|
|
|
|
this.finalQty = finalQty |
|
|
|
|
|
this.status = StockTakeLineStatus.COMPLETED |
|
|
|
|
|
this.completeDate = java.time.LocalDateTime.now() |
|
|
|
|
|
} |
|
|
|
|
|
stockTakeLineRepository.save(stockTakeLine) |
|
|
|
|
|
|
|
|
|
|
|
// 2. variance < 0:出库 + StockLedger |
|
|
|
|
|
if (varianceQty < BigDecimal.ZERO) { |
|
|
|
|
|
val absVariance = varianceQty.negate() |
|
|
|
|
|
|
|
|
|
|
|
var stockOut = stockOutRepository.findByStockTakeIdAndDeletedFalse(stockTake.id!!) |
|
|
|
|
|
?: StockOut().apply { |
|
|
|
|
|
this.type = "stockTake" |
|
|
|
|
|
this.status = "completed" |
|
|
|
|
|
this.handler = approverId |
|
|
|
|
|
}.also { stockOutRepository.save(it) } |
|
|
|
|
|
|
|
|
|
|
|
val stockOutLine = StockOutLine().apply { |
|
|
|
|
|
this.item = inventoryLot.item |
|
|
|
|
|
this.qty = absVariance.toDouble() |
|
|
|
|
|
this.stockOut = stockOut |
|
|
|
|
|
this.inventoryLotLine = inventoryLotLine |
|
|
|
|
|
this.status = "completed" |
|
|
|
|
|
this.type = "TKE" |
|
|
|
|
|
} |
|
|
|
|
|
stockOutLineRepository.save(stockOutLine) |
|
|
|
|
|
|
|
|
|
|
|
val newBalance = (inventory.onHandQty ?: BigDecimal.ZERO).toDouble() - absVariance.toDouble() |
|
|
|
|
|
val stockLedger = StockLedger().apply { |
|
|
|
|
|
this.inventory = inventory |
|
|
|
|
|
this.itemId = inventoryLot.item?.id |
|
|
|
|
|
this.itemCode = stockTakeRecord.itemCode |
|
|
|
|
|
this.inQty = null |
|
|
|
|
|
this.outQty = absVariance.toDouble() |
|
|
|
|
|
this.stockOutLine = stockOutLine |
|
|
|
|
|
this.balance = newBalance |
|
|
|
|
|
this.type = "TKE" |
|
|
|
|
|
this.date = LocalDate.now() |
|
|
|
|
|
} |
|
|
|
|
|
stockLedgerRepository.save(stockLedger) |
|
|
|
|
|
|
|
|
|
|
|
val newOutQty = (inventoryLotLine.outQty ?: BigDecimal.ZERO).add(absVariance) |
|
|
|
|
|
val updateRequest = SaveInventoryLotLineRequest( |
|
|
|
|
|
id = inventoryLotLine.id, |
|
|
|
|
|
inventoryLotId = inventoryLotLine.inventoryLot?.id, |
|
|
|
|
|
warehouseId = inventoryLotLine.warehouse?.id, |
|
|
|
|
|
stockUomId = inventoryLotLine.stockUom?.id, |
|
|
|
|
|
inQty = inventoryLotLine.inQty, |
|
|
|
|
|
outQty = newOutQty, |
|
|
|
|
|
holdQty = inventoryLotLine.holdQty, |
|
|
|
|
|
status = inventoryLotLine.status?.value, |
|
|
|
|
|
remarks = inventoryLotLine.remarks |
|
|
|
|
|
) |
|
|
|
|
|
inventoryLotLineService.saveInventoryLotLine(updateRequest) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 3. variance > 0:入库 + StockLedger |
|
|
|
|
|
if (varianceQty > BigDecimal.ZERO) { |
|
|
|
|
|
val plusQty = varianceQty |
|
|
|
|
|
|
|
|
|
|
|
var stockIn = stockInRepository.findByStockTakeIdAndDeletedFalse(stockTake.id!!) |
|
|
|
|
|
?: StockIn().apply { |
|
|
|
|
|
this.code = stockTake.code |
|
|
|
|
|
this.status = "completed" |
|
|
|
|
|
this.stockTake = stockTake |
|
|
|
|
|
}.also { stockInRepository.save(it) } |
|
|
|
|
|
|
|
|
|
|
|
val stockInLine = StockInLine().apply { |
|
|
|
|
|
this.stockTakeLine = stockTakeLine |
|
|
|
|
|
this.item = inventoryLot.item |
|
|
|
|
|
this.itemNo = stockTakeRecord.itemCode |
|
|
|
|
|
this.stockIn = stockIn |
|
|
|
|
|
this.demandQty = plusQty |
|
|
|
|
|
this.acceptedQty = plusQty |
|
|
|
|
|
this.expiryDate = inventoryLot.expiryDate |
|
|
|
|
|
this.lotNo = inventoryLot.lotNo |
|
|
|
|
|
this.status = "completed" |
|
|
|
|
|
this.type = "TKE" |
|
|
|
|
|
} |
|
|
|
|
|
stockInLineRepository.save(stockInLine) |
|
|
|
|
|
|
|
|
|
|
|
val newInventoryLot = InventoryLot().apply { |
|
|
|
|
|
this.item = inventoryLot.item |
|
|
|
|
|
this.lotNo = inventoryLot.lotNo |
|
|
|
|
|
this.expiryDate = inventoryLot.expiryDate |
|
|
|
|
|
this.productionDate = inventoryLot.productionDate |
|
|
|
|
|
this.stockInDate = LocalDateTime.now() |
|
|
|
|
|
this.stockInLine = stockInLine |
|
|
|
|
|
} |
|
|
|
|
|
inventoryLotRepository.save(newInventoryLot) |
|
|
|
|
|
|
|
|
|
|
|
val newInventoryLotLine = InventoryLotLine().apply { |
|
|
|
|
|
this.inventoryLot = newInventoryLot |
|
|
|
|
|
this.warehouse = inventoryLotLine.warehouse |
|
|
|
|
|
this.stockUom = inventoryLotLine.stockUom |
|
|
|
|
|
this.inQty = plusQty |
|
|
|
|
|
this.outQty = BigDecimal.ZERO |
|
|
|
|
|
this.holdQty = BigDecimal.ZERO |
|
|
|
|
|
this.status = inventoryLotLine.status |
|
|
|
|
|
this.remarks = "Stock take adjustment (+$plusQty)" |
|
|
|
|
|
} |
|
|
|
|
|
inventoryLotLineRepository.save(newInventoryLotLine) |
|
|
|
|
|
|
|
|
|
|
|
stockInLine.inventoryLot = newInventoryLot |
|
|
|
|
|
stockInLine.inventoryLotLine = newInventoryLotLine |
|
|
|
|
|
stockInLineRepository.save(stockInLine) |
|
|
|
|
|
|
|
|
|
|
|
val newBalance = (inventory.onHandQty ?: BigDecimal.ZERO).toDouble() + plusQty.toDouble() |
|
|
|
|
|
val stockLedger = StockLedger().apply { |
|
|
|
|
|
this.inventory = inventory |
|
|
|
|
|
this.itemId = newInventoryLot.item?.id |
|
|
|
|
|
this.itemCode = newInventoryLot.item?.code |
|
|
|
|
|
this.inQty = plusQty.toDouble() |
|
|
|
|
|
this.outQty = null |
|
|
|
|
|
this.stockInLine = stockInLine |
|
|
|
|
|
this.balance = newBalance |
|
|
|
|
|
this.type = "TKE" |
|
|
|
|
|
this.date = LocalDate.now() |
|
|
|
|
|
} |
|
|
|
|
|
stockLedgerRepository.save(stockLedger) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
open fun updateStockTakeRecordStatusToNotMatch(stockTakeRecordId: Long): StockTakeRecord { |
|
|
open fun updateStockTakeRecordStatusToNotMatch(stockTakeRecordId: Long): StockTakeRecord { |
|
|
println("updateStockTakeRecordStatusToNotMatch called with stockTakeRecordId: $stockTakeRecordId") |
|
|
println("updateStockTakeRecordStatusToNotMatch called with stockTakeRecordId: $stockTakeRecordId") |
|
|
|
|
|
|
|
|
@@ -1233,6 +1283,7 @@ open fun getInventoryLotDetailsByStockTakeSectionNotMatch( |
|
|
approverQty = stockTakeRecord.approverStockTakeQty, |
|
|
approverQty = stockTakeRecord.approverStockTakeQty, |
|
|
approverBadQty = stockTakeRecord.approverBadQty, |
|
|
approverBadQty = stockTakeRecord.approverBadQty, |
|
|
finalQty = stockTakeLine?.finalQty, |
|
|
finalQty = stockTakeLine?.finalQty, |
|
|
|
|
|
bookQty = stockTakeRecord.bookQty, |
|
|
) |
|
|
) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|