|
|
@@ -127,12 +127,11 @@ open class PickOrderService( |
|
|
|
val total = response.totalElements |
|
|
|
return RecordsRes<PickOrderInfo>(records, total.toInt()) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
open fun getPickOrdersWithStockBalanceByPage(request: SearchPickOrderRequest): RecordsRes<GetPickOrderInfo> { |
|
|
|
val pageable = PageRequest.of(request.pageNum ?: 0, request.pageSize ?: 10); |
|
|
|
|
|
|
|
|
|
|
|
// First get the basic pick order info for pagination |
|
|
|
val response = pickOrderRepository.findPickOrderInfoByConditionsAndPageable( |
|
|
|
code = request.code ?: "all", |
|
|
@@ -143,27 +142,27 @@ open class PickOrderService( |
|
|
|
itemName = request.itemName ?: "all", |
|
|
|
pageable = pageable |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
val records = response.content |
|
|
|
val pickOrderIds = records.mapNotNull { it.id } |
|
|
|
|
|
|
|
|
|
|
|
if (pickOrderIds.isEmpty()) { |
|
|
|
return RecordsRes(emptyList(), 0) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Get full pick orders with relationships |
|
|
|
val fullPickOrders = pickOrderRepository.findAllByIdIn(pickOrderIds) |
|
|
|
|
|
|
|
|
|
|
|
// Get all item IDs |
|
|
|
val itemIds = fullPickOrders |
|
|
|
.flatMap { it.pickOrderLines } |
|
|
|
.mapNotNull { it.item?.id } |
|
|
|
.distinct() |
|
|
|
|
|
|
|
|
|
|
|
// Get inventory data |
|
|
|
val today = LocalDate.now() |
|
|
|
val zero = BigDecimal.ZERO |
|
|
|
|
|
|
|
|
|
|
|
val inventories = if (itemIds.isNotEmpty()) { |
|
|
|
inventoryLotLineService |
|
|
|
.allInventoryLotLinesByItemIdIn(itemIds) |
|
|
@@ -174,12 +173,12 @@ open class PickOrderService( |
|
|
|
} else { |
|
|
|
emptyMap() |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Build response (removed suggestions) |
|
|
|
val pickOrderInfos = fullPickOrders.map { po -> |
|
|
|
val pickOrderLineInfos = po.pickOrderLines.map { pol -> |
|
|
|
val inventory = pol.item?.id?.let { inventories[it] } |
|
|
|
|
|
|
|
|
|
|
|
GetPickOrderLineInfo( |
|
|
|
id = pol.id, |
|
|
|
itemId = pol.item?.id, |
|
|
@@ -192,20 +191,87 @@ open class PickOrderService( |
|
|
|
suggestedList = emptyList() // Empty list since you don't need suggestions |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GetPickOrderInfo( |
|
|
|
id = po.id, |
|
|
|
code = po.code, |
|
|
|
targetDate = po.targetDate, |
|
|
|
type = po.type?.value, |
|
|
|
status = po.status?.value, |
|
|
|
assignTo = po.assignTo?.id, |
|
|
|
pickOrderLines = pickOrderLineInfos |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
val total = response.totalElements |
|
|
|
return RecordsRes(pickOrderInfos, total.toInt()) |
|
|
|
} |
|
|
|
|
|
|
|
open fun assignPickOrders(pickOrderIds: List<Long>, assignTo: Long): MessageResponse { |
|
|
|
try { |
|
|
|
val pickOrders = pickOrderRepository.findAllById(pickOrderIds) |
|
|
|
val user = userService.find(assignTo).orElse(null) // 获取用户对象 |
|
|
|
|
|
|
|
pickOrders.forEach { pickOrder -> |
|
|
|
pickOrder.assignTo = user // 使用 User 对象而不是 Long |
|
|
|
pickOrder.status = PickOrderStatus.ASSIGNED // 使用枚举值 |
|
|
|
} |
|
|
|
|
|
|
|
pickOrderRepository.saveAll(pickOrders) |
|
|
|
|
|
|
|
return MessageResponse( |
|
|
|
id = null, |
|
|
|
name = "Pick orders assigned successfully", |
|
|
|
code = "SUCCESS", |
|
|
|
type = "pickorder", |
|
|
|
message = "Pick orders assigned successfully", |
|
|
|
errorPosition = null |
|
|
|
) |
|
|
|
} catch (e: Exception) { |
|
|
|
return MessageResponse( |
|
|
|
id = null, |
|
|
|
name = "Failed to assign pick orders", |
|
|
|
code = "ERROR", |
|
|
|
type = "pickorder", |
|
|
|
message = "Failed to assign pick orders: ${e.message}", |
|
|
|
errorPosition = null |
|
|
|
) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
open fun releasePickOrders(pickOrderIds: List<Long>, assignTo: Long): MessageResponse { |
|
|
|
try { |
|
|
|
val pickOrders = pickOrderRepository.findAllById(pickOrderIds) |
|
|
|
val user = userService.find(assignTo).orElse(null) // 获取用户对象 |
|
|
|
|
|
|
|
pickOrders.forEach { pickOrder -> |
|
|
|
pickOrder.assignTo = user // 使用 User 对象而不是 Long |
|
|
|
pickOrder.status = PickOrderStatus.RELEASED // 使用枚举值 |
|
|
|
} |
|
|
|
|
|
|
|
pickOrderRepository.saveAll(pickOrders) |
|
|
|
|
|
|
|
return MessageResponse( |
|
|
|
id = null, |
|
|
|
name = "Pick orders released successfully", |
|
|
|
code = "SUCCESS", |
|
|
|
type = "pickorder", |
|
|
|
message = "Pick orders released successfully", |
|
|
|
errorPosition = null |
|
|
|
) |
|
|
|
} catch (e: Exception) { |
|
|
|
return MessageResponse( |
|
|
|
id = null, |
|
|
|
name = "Failed to release pick orders", |
|
|
|
code = "ERROR", |
|
|
|
type = "pickorder", |
|
|
|
message = "Failed to release pick orders: ${e.message}", |
|
|
|
errorPosition = null |
|
|
|
) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
open fun getConsoPickOrderList(args: MutableMap<String, Any>): List<Map<String, Any>> { |
|
|
|
val sql = StringBuilder( |
|
|
|
"select" |
|
|
@@ -525,7 +591,7 @@ open class PickOrderService( |
|
|
|
itemCode = pol.item?.code, |
|
|
|
itemName = pol.item?.name, |
|
|
|
// availableQty = inventory?.availableQty, |
|
|
|
availableQty = inventory?.sumOf { i -> (i.availableQty ?: zero) }, |
|
|
|
availableQty = inventory?.sumOf { i -> (i.availableQty ?: zero) }, |
|
|
|
// availableQty = inventory?.sumOf { i -> (i.availableQty ?: zero) * (itemUom?.ratioN ?: one) * (itemUom?.ratioD ?: one) }, |
|
|
|
requiredQty = pol.qty, |
|
|
|
uomCode = pol.uom?.code, |
|
|
@@ -623,7 +689,7 @@ open class PickOrderService( |
|
|
|
itemCode = pol.item?.code, |
|
|
|
itemName = pol.item?.name, |
|
|
|
// availableQty = inventory?.availableQty, |
|
|
|
availableQty = inventory?.sumOf { i -> (i.availableQty ?: zero) }, |
|
|
|
availableQty = inventory?.sumOf { i -> (i.availableQty ?: zero) }, |
|
|
|
// availableQty = inventory?.sumOf { i -> (i.availableQty ?: zero) * (itemUom?.ratioN ?: one) * (itemUom?.ratioD ?: one) }, |
|
|
|
requiredQty = pol.qty, |
|
|
|
uomCode = pol.uom?.code, |
|
|
@@ -636,10 +702,11 @@ open class PickOrderService( |
|
|
|
// Return |
|
|
|
GetPickOrderInfo( |
|
|
|
id = po.id, |
|
|
|
code = po.code, |
|
|
|
code = po.code, |
|
|
|
targetDate = po.targetDate, |
|
|
|
type = po.type?.value, |
|
|
|
status = po.status?.value, |
|
|
|
assignTo = po.assignTo?.id, |
|
|
|
pickOrderLines = releasePickOrderLineInfos |
|
|
|
) |
|
|
|
} |
|
|
@@ -677,9 +744,9 @@ open class PickOrderService( |
|
|
|
val releasedPickOrderIds = allPickOrders |
|
|
|
.filter { it.status == PickOrderStatus.RELEASED } |
|
|
|
.map { it.id!! } |
|
|
|
|
|
|
|
|
|
|
|
println("All released pick order IDs: $releasedPickOrderIds") |
|
|
|
|
|
|
|
|
|
|
|
// 如果没有任何已发布的 Pick Orders,返回空结果 |
|
|
|
if (releasedPickOrderIds.isEmpty()) { |
|
|
|
return GetPickOrderInfoResponse( |
|
|
@@ -687,18 +754,18 @@ open class PickOrderService( |
|
|
|
items = emptyList() |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 重用现有的 getPickOrdersInfo 方法 |
|
|
|
return getPickOrdersInfo(releasedPickOrderIds) |
|
|
|
} |
|
|
|
|
|
|
|
open fun getPickOrderLineLotDetails(pickOrderLineId: Long): List<Map<String, Any>> { |
|
|
|
val today = LocalDate.now() |
|
|
|
|
|
|
|
|
|
|
|
println("=== Debug: getPickOrderLineLotDetails ===") |
|
|
|
println("pickOrderLineId: $pickOrderLineId") |
|
|
|
println("today: $today") |
|
|
|
|
|
|
|
|
|
|
|
// 检查具体的数量字段值 |
|
|
|
val quantityCheckSql = """ |
|
|
|
SELECT |
|
|
@@ -716,13 +783,13 @@ open class PickOrderService( |
|
|
|
WHERE spl.pickOrderLineId = :pickOrderLineId |
|
|
|
AND ill.status = 'available' |
|
|
|
""".trimIndent() |
|
|
|
|
|
|
|
|
|
|
|
val quantityCheckResult = jdbcDao.queryForList(quantityCheckSql, mapOf("pickOrderLineId" to pickOrderLineId)) |
|
|
|
println("Quantity check result:") |
|
|
|
quantityCheckResult.forEach { row -> |
|
|
|
println("Row: $row") |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 检查日期条件 |
|
|
|
val dateCheckSql = """ |
|
|
|
SELECT |
|
|
@@ -740,13 +807,14 @@ open class PickOrderService( |
|
|
|
AND ill.status = 'available' |
|
|
|
AND (COALESCE(ill.inQty, 0) - COALESCE(ill.outQty, 0) - COALESCE(ill.holdQty, 0)) > 0 |
|
|
|
""".trimIndent() |
|
|
|
|
|
|
|
val dateCheckResult = jdbcDao.queryForList(dateCheckSql, mapOf("pickOrderLineId" to pickOrderLineId, "today" to today)) |
|
|
|
|
|
|
|
val dateCheckResult = |
|
|
|
jdbcDao.queryForList(dateCheckSql, mapOf("pickOrderLineId" to pickOrderLineId, "today" to today)) |
|
|
|
println("Date check result:") |
|
|
|
dateCheckResult.forEach { row -> |
|
|
|
println("Row: $row") |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 检查 warehouse JOIN |
|
|
|
val warehouseCheckSql = """ |
|
|
|
SELECT |
|
|
@@ -764,13 +832,14 @@ open class PickOrderService( |
|
|
|
AND (COALESCE(ill.inQty, 0) - COALESCE(ill.outQty, 0) - COALESCE(ill.holdQty, 0)) > 0 |
|
|
|
AND (il.expiryDate IS NULL OR il.expiryDate >= :today) |
|
|
|
""".trimIndent() |
|
|
|
|
|
|
|
val warehouseCheckResult = jdbcDao.queryForList(warehouseCheckSql, mapOf("pickOrderLineId" to pickOrderLineId, "today" to today)) |
|
|
|
|
|
|
|
val warehouseCheckResult = |
|
|
|
jdbcDao.queryForList(warehouseCheckSql, mapOf("pickOrderLineId" to pickOrderLineId, "today" to today)) |
|
|
|
println("Warehouse check result count: ${warehouseCheckResult.size}") |
|
|
|
warehouseCheckResult.forEach { row -> |
|
|
|
println("Warehouse Row: $row") |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 检查 uom_conversion JOIN - 使用 LEFT JOIN 并检查 stockItemUomId |
|
|
|
val uomCheckSql = """ |
|
|
|
SELECT |
|
|
@@ -789,13 +858,14 @@ open class PickOrderService( |
|
|
|
AND (COALESCE(ill.inQty, 0) - COALESCE(ill.outQty, 0) - COALESCE(ill.holdQty, 0)) > 0 |
|
|
|
AND (il.expiryDate IS NULL OR il.expiryDate >= :today) |
|
|
|
""".trimIndent() |
|
|
|
|
|
|
|
val uomCheckResult = jdbcDao.queryForList(uomCheckSql, mapOf("pickOrderLineId" to pickOrderLineId, "today" to today)) |
|
|
|
|
|
|
|
val uomCheckResult = |
|
|
|
jdbcDao.queryForList(uomCheckSql, mapOf("pickOrderLineId" to pickOrderLineId, "today" to today)) |
|
|
|
println("UOM check result count: ${uomCheckResult.size}") |
|
|
|
uomCheckResult.forEach { row -> |
|
|
|
println("UOM Row: $row") |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 修改查询,通过 item_uom 表获取 UOM 信息 |
|
|
|
val sql = """ |
|
|
|
SELECT |
|
|
@@ -833,27 +903,22 @@ open class PickOrderService( |
|
|
|
END, |
|
|
|
il.expiryDate ASC |
|
|
|
""".trimIndent() |
|
|
|
|
|
|
|
|
|
|
|
val params = mapOf( |
|
|
|
"pickOrderLineId" to pickOrderLineId, |
|
|
|
"today" to today |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
val result = jdbcDao.queryForList(sql, params) |
|
|
|
println("Final result count: ${result.size}") |
|
|
|
result.forEach { row -> |
|
|
|
println("Final Row: $row") |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return result |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Transactional(rollbackFor = [java.lang.Exception::class]) |
|
|
|
open fun releaseConsoPickOrderAction(request: ReleaseConsoPickOrderRequest): ReleasePickOrderInfoResponse { |
|
|
|
val zero = BigDecimal.ZERO |
|
|
@@ -908,6 +973,94 @@ open class PickOrderService( |
|
|
|
return releaseConsoPickOrderInfo(request.consoCode) |
|
|
|
} |
|
|
|
|
|
|
|
@Transactional(rollbackFor = [java.lang.Exception::class]) |
|
|
|
open fun releaseAssignedPickOrders(pickOrderIds: List<Long>, assignTo: Long): MessageResponse { |
|
|
|
try { |
|
|
|
val zero = BigDecimal.ZERO |
|
|
|
val releasedBy = SecurityUtils.getUser().getOrNull() |
|
|
|
val user = userService.find(assignTo).orElse(null) |
|
|
|
|
|
|
|
|
|
|
|
val pickOrders = pickOrderRepository.findAllByIdInAndStatus(pickOrderIds, PickOrderStatus.ASSIGNED) |
|
|
|
|
|
|
|
if (pickOrders.isEmpty()) { |
|
|
|
return MessageResponse( |
|
|
|
id = null, |
|
|
|
name = "No assigned pick orders found", |
|
|
|
code = "ERROR", |
|
|
|
type = "pickorder", |
|
|
|
message = "No assigned pick orders found with the provided IDs", |
|
|
|
errorPosition = null |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pickOrders.forEach { pickOrder -> |
|
|
|
pickOrder.apply { |
|
|
|
this.releasedBy = releasedBy |
|
|
|
status = PickOrderStatus.RELEASED |
|
|
|
this.assignTo = user |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
val suggestions = suggestedPickLotService.suggestionForPickOrders( |
|
|
|
SuggestedPickLotForPoRequest(pickOrders = pickOrders) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
val currUser = SecurityUtils.getUser().orElseThrow() |
|
|
|
val stockOut = StockOut().apply { |
|
|
|
this.type = "job" |
|
|
|
this.consoPickOrderCode = null // 单个 pick orders 没有 consoCode |
|
|
|
this.status = StockOutStatus.PENDING.status |
|
|
|
this.handler = currUser.id |
|
|
|
} |
|
|
|
stockOutRepository.save(stockOut) |
|
|
|
|
|
|
|
|
|
|
|
val saveSuggestedPickLots = suggestedPickLotService.saveAll(suggestions.suggestedList) |
|
|
|
|
|
|
|
pickOrderRepository.saveAll(pickOrders) |
|
|
|
|
|
|
|
|
|
|
|
val inventoryLotLines = inventoryLotLineRepository.findAllByIdIn( |
|
|
|
saveSuggestedPickLots.mapNotNull { it.suggestedLotLine?.id } |
|
|
|
) |
|
|
|
|
|
|
|
saveSuggestedPickLots.forEach { lot -> |
|
|
|
if (lot.suggestedLotLine != null && lot.suggestedLotLine?.id != null && lot.suggestedLotLine!!.id!! > 0) { |
|
|
|
val lineIndex = inventoryLotLines.indexOf(lot.suggestedLotLine) |
|
|
|
if (lineIndex >= 0) { |
|
|
|
inventoryLotLines[lineIndex].holdQty = |
|
|
|
(inventoryLotLines[lineIndex].holdQty ?: zero).plus(lot.qty ?: zero) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
inventoryLotLineRepository.saveAll(inventoryLotLines) |
|
|
|
|
|
|
|
return MessageResponse( |
|
|
|
id = null, |
|
|
|
name = "Pick orders released successfully with inventory management", |
|
|
|
code = "SUCCESS", |
|
|
|
type = "pickorder", |
|
|
|
message = "Pick orders released successfully with inventory management", |
|
|
|
errorPosition = null |
|
|
|
) |
|
|
|
|
|
|
|
} catch (e: Exception) { |
|
|
|
return MessageResponse( |
|
|
|
id = null, |
|
|
|
name = "Failed to release pick orders", |
|
|
|
code = "ERROR", |
|
|
|
type = "pickorder", |
|
|
|
message = "Failed to release pick orders: ${e.message}", |
|
|
|
errorPosition = null |
|
|
|
) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@Throws(IOException::class) |
|
|
|
@Transactional |
|
|
|
open fun completeStockOut(consoCode: String): MessageResponse { |
|
|
@@ -939,8 +1092,8 @@ open class PickOrderService( |
|
|
|
} else { |
|
|
|
return MessageResponse( |
|
|
|
id = stockOut.id, |
|
|
|
name = stockOut.consoPickOrderCode ?: stockOut.deliveryOrderCode, |
|
|
|
code = stockOut.consoPickOrderCode ?: stockOut.deliveryOrderCode, |
|
|
|
name = stockOut.consoPickOrderCode ?: stockOut.deliveryOrderCode, // 修复:使用 stockOut 而不是 savedStockOut |
|
|
|
code = stockOut.consoPickOrderCode ?: stockOut.deliveryOrderCode, // 修复:使用 stockOut 而不是 savedStockOut |
|
|
|
type = stockOut.type, |
|
|
|
message = "not completed", |
|
|
|
errorPosition = null, |
|
|
|