logger.warn("Row ${i + 1}: Warehouse not found in database for LocationCode: '$locationCode', inventorySheet: '$inventorySheet', company: '$company', storeLocation: '$storeLocation'")
}
foundWarehouse
} catch (e: Exception) {
logger.warn("Row ${i + 1}: Failed to find warehouse with LocationCode '$locationCode' - ${e.message}")
logger.warn("Row ${i + 1}: Failed to find warehouse with LocationCode '$locationCode', inventorySheet '$inventorySheet', company '$company', storeLocation '$storeLocation' - ${e.message}")
null
}
} else {
logger.warn("Row ${i + 1}: Item '$itemCode' has no LocationCode, warehouse will be null")
if (locationCode.isNullOrBlank()) {
logger.warn("Row ${i + 1}: Item '$itemCode' has no LocationCode (null or blank), warehouse will be null")
}
if (inventorySheet.isNullOrBlank()) {
logger.warn("Row ${i + 1}: Item '$itemCode' has no inventorySheet (null or blank), warehouse will be null")
}
if (company.isNullOrBlank()) {
logger.warn("Row ${i + 1}: Item '$itemCode' has no company (null or blank), warehouse will be null")
}
if (storeLocation.isNullOrBlank()) {
logger.warn("Row ${i + 1}: Item '$itemCode' has no storeLocation (null or blank), warehouse will be null")
}
null
}
@@ -841,62 +964,139 @@ open class ItemsService(
null
}
// Update StockInLine to RECEIVED status (this will trigger InventoryLot & InventoryLotLine creation)
// Step 7a: First update to PENDING with qcAccept=true to create InventoryLot
// This will create InventoryLot and automatically set status to RECEIVED
saveStockInLineReq.apply {
id = savedStockInLine.id
status = StockInLineStatus.RECEIVED.status
status = StockInLineStatus.PENDING.status
this.dnNo = dnNo
this.inventoryLotLines = inventoryLotLines
this.qcAccept = true
this.acceptedQty = qty
this.acceptQty = qty
// Don't set inventoryLotLines yet
}
val finalStockInLine = try {
val updatedForLot = try {
stockInLineService.update(saveStockInLineReq)
} catch (e: Exception) {
logger.error("Row ${i + 1}: Failed to update StockInLine to RECEIVED for item '$itemCode' - ${e.message}")
logWriter.writeRowError(i, "Failed to update StockInLine to RECEIVED - ${e.message}")
logger.error("Row ${i + 1}: Failed to update StockInLine to PENDING (for InventoryLot) for item '$itemCode' - ${e.message}")
logWriter.writeRowError(i, "Failed to update StockInLine to PENDING - ${e.message}")
errorCount++
errors.add("Row ${i + 1}: Failed to update StockInLine to RECEIVED - ${e.message}")
errors.add("Row ${i + 1}: Failed to update StockInLine to PENDING - ${e.message}")
continue
}
logger.info("Row ${i + 1}: Updated StockInLine to RECEIVED (ID: ${finalStockInLine.id}) for item '$itemCode' with lotNo: $lotNo, dnNo: $dnNo")
val inventoryLotLine = if (finalStockInLine.id != null && warehouse?.id != null) {
try {
// Check if update was successful
if (updatedForLot?.id == null) {
logger.error("Row ${i + 1}: StockInLine update returned null ID for item '$itemCode'")
logWriter.writeRowError(i, "StockInLine update returned null")
errorCount++
errors.add("Row ${i + 1}: StockInLine update returned null")
continue
}
logger.info("Row ${i + 1}: Updated StockInLine to PENDING (ID: ${updatedForLot.id}) - InventoryLot should be created")
// Refresh StockInLine entity to get the InventoryLot that was just created
val refreshedStockInLine = stockInLineRepository.findById(updatedForLot.id!!).orElse(null)
if (refreshedStockInLine?.inventoryLot == null) {
logger.warn("Row ${i + 1}: InventoryLot was not created for StockInLine ${updatedForLot.id}")
logWriter.writeRowError(i, "InventoryLot was not created")
} else {
logger.info("Row ${i + 1}: InventoryLot created (ID: ${refreshedStockInLine.inventoryLot?.id}, lotNo: ${refreshedStockInLine.inventoryLot?.lotNo})")
}
// Step 7b: Second update to RECEIVED with inventoryLotLines to create InventoryLotLine
// Only proceed if warehouse is available (InventoryLotLine requires warehouse)
if (warehouse?.id == null) {
logger.warn("Row ${i + 1}: Warehouse is null (no LocationCode), skipping InventoryLotLine creation for item '$itemCode'")
logWriter.writeRowError(i, "Warehouse is null - InventoryLotLine will not be created")
// Continue without InventoryLotLine - StockTakeLine will not be updated with inventoryLotLineId
} else {
// Warehouse is available, proceed with InventoryLotLine creation
saveStockInLineReq.apply {
id = savedStockInLine.id
status = StockInLineStatus.RECEIVED.status // Explicitly set to RECEIVED
this.dnNo = dnNo
this.acceptedQty = qty
this.acceptQty = qty
this.inventoryLotLines = inventoryLotLines // REQUIRED for InventoryLotLine creation
}
val finalStockInLine = try {
stockInLineService.update(saveStockInLineReq)
} catch (e: Exception) {
logger.error("Row ${i + 1}: Failed to update StockInLine to RECEIVED (for InventoryLotLine) for item '$itemCode' - ${e.message}")
logWriter.writeRowError(i, "Failed to update StockInLine to RECEIVED - ${e.message}")
errorCount++
errors.add("Row ${i + 1}: Failed to update StockInLine to RECEIVED - ${e.message}")
continue
}
if (finalStockInLine?.id == null) {
logger.error("Row ${i + 1}: StockInLine update to RECEIVED returned null ID for item '$itemCode'")
logWriter.writeRowError(i, "StockInLine update to RECEIVED returned null")
errorCount++
errors.add("Row ${i + 1}: StockInLine update to RECEIVED returned null")
continue
}
logger.info("Row ${i + 1}: Updated StockInLine to RECEIVED (ID: ${finalStockInLine.id}) for item '$itemCode' with lotNo: $lotNo, dnNo: $dnNo")
// Step 8: Find InventoryLotLine and update StockTakeLine
// Flush first to ensure InventoryLotLine is persisted
stockInLineRepository.flush()
// Verify InventoryLotLine was created by querying directly