|
|
|
@@ -780,15 +780,16 @@ open class PickOrderService( |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
open fun getAllPickOrdersInfo(): GetPickOrderInfoResponse { |
|
|
|
open fun getAllPickOrdersInfo(userId: Long? = null): GetPickOrderInfoResponse { |
|
|
|
// 使用现有的查询方法获取所有 Pick Orders,然后在内存中过滤 |
|
|
|
val allPickOrders = pickOrderRepository.findAll() |
|
|
|
val releasedPickOrderIds = allPickOrders |
|
|
|
.filter { it.status == PickOrderStatus.RELEASED } |
|
|
|
.filter { userId == null || it.assignTo?.id == userId } // ✅ Fixed: now userId is a parameter |
|
|
|
.map { it.id!! } |
|
|
|
|
|
|
|
println("All released pick order IDs: $releasedPickOrderIds") |
|
|
|
|
|
|
|
|
|
|
|
println("All released pick order IDs for user $userId: $releasedPickOrderIds") |
|
|
|
|
|
|
|
// 如果没有任何已发布的 Pick Orders,返回空结果 |
|
|
|
if (releasedPickOrderIds.isEmpty()) { |
|
|
|
return GetPickOrderInfoResponse( |
|
|
|
@@ -797,11 +798,10 @@ open class PickOrderService( |
|
|
|
items = emptyList() |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 重用现有的 getPickOrdersInfo 方法 |
|
|
|
return getPickOrdersInfo(releasedPickOrderIds) |
|
|
|
} |
|
|
|
|
|
|
|
open fun getPickOrderLineLotDetails(pickOrderLineId: Long): List<Map<String, Any>> { |
|
|
|
val today = LocalDate.now() |
|
|
|
|
|
|
|
@@ -1327,4 +1327,190 @@ open class PickOrderService( |
|
|
|
|
|
|
|
return false |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
open fun getAllPickOrderLotsWithDetails(userId: Long? = null): List<Map<String, Any>> { |
|
|
|
val today = LocalDate.now() |
|
|
|
val zero = BigDecimal.ZERO |
|
|
|
|
|
|
|
println("=== Debug: getAllPickOrderLotsWithDetails ===") |
|
|
|
println("today: $today") |
|
|
|
println("userId filter: $userId") |
|
|
|
|
|
|
|
val sql = """ |
|
|
|
SELECT |
|
|
|
-- Pick Order Information |
|
|
|
po.id as pickOrderId, |
|
|
|
po.code as pickOrderCode, |
|
|
|
po.targetDate as pickOrderTargetDate, |
|
|
|
po.type as pickOrderType, |
|
|
|
po.status as pickOrderStatus, |
|
|
|
po.assignTo as pickOrderAssignTo, |
|
|
|
pog.name as groupName, |
|
|
|
|
|
|
|
-- Pick Order Line Information |
|
|
|
pol.id as pickOrderLineId, |
|
|
|
pol.qty as pickOrderLineRequiredQty, |
|
|
|
pol.status as pickOrderLineStatus, |
|
|
|
|
|
|
|
-- Item Information |
|
|
|
i.id as itemId, |
|
|
|
i.code as itemCode, |
|
|
|
i.name as itemName, |
|
|
|
uc.code as uomCode, |
|
|
|
uc.udfudesc as uomDesc, |
|
|
|
|
|
|
|
-- Lot Information |
|
|
|
ill.id as lotId, |
|
|
|
il.lotNo, |
|
|
|
il.expiryDate, |
|
|
|
w.name as location, |
|
|
|
COALESCE(uc.udfudesc, 'N/A') as stockUnit, |
|
|
|
|
|
|
|
-- ✅ FIXED: Set quantities to NULL for rejected lots |
|
|
|
CASE |
|
|
|
WHEN sol.status = 'rejected' THEN NULL |
|
|
|
ELSE (COALESCE(ill.inQty, 0) - COALESCE(ill.outQty, 0) - COALESCE(ill.holdQty, 0)) |
|
|
|
END as availableQty, |
|
|
|
|
|
|
|
CASE |
|
|
|
WHEN sol.status = 'rejected' THEN NULL |
|
|
|
ELSE spl.qty |
|
|
|
END as requiredQty, |
|
|
|
|
|
|
|
CASE |
|
|
|
WHEN sol.status = 'rejected' THEN NULL |
|
|
|
ELSE COALESCE(sol.qty, 0) |
|
|
|
END as actualPickQty, |
|
|
|
|
|
|
|
spl.id as suggestedPickLotId, |
|
|
|
ill.status as lotStatus, |
|
|
|
sol.id as stockOutLineId, |
|
|
|
sol.status as stockOutLineStatus, |
|
|
|
sol.qty as stockOutLineQty, |
|
|
|
|
|
|
|
-- Calculated fields |
|
|
|
CASE |
|
|
|
WHEN sol.status = 'rejected' THEN 'rejected' |
|
|
|
WHEN ill.status != 'available' THEN 'unavailable' |
|
|
|
WHEN (il.expiryDate IS NOT NULL AND il.expiryDate < CURDATE()) THEN 'expired' |
|
|
|
WHEN (COALESCE(ill.inQty, 0) - COALESCE(ill.outQty, 0) - COALESCE(ill.holdQty, 0)) < (spl.qty) THEN 'insufficient_stock' |
|
|
|
ELSE 'available' |
|
|
|
END as lotAvailability, |
|
|
|
|
|
|
|
-- Stock out line status for filtering |
|
|
|
CASE |
|
|
|
WHEN sol.status = 'completed' AND sol.qty = spl.qty THEN 'completed' |
|
|
|
WHEN sol.status = 'completed' AND sol.qty < spl.qty THEN 'partially_completed' |
|
|
|
WHEN sol.status = 'rejected' THEN 'rejected' |
|
|
|
WHEN sol.status = 'pending' THEN 'pending' |
|
|
|
WHEN sol.status = 'checked' THEN 'checked' |
|
|
|
ELSE 'not_started' |
|
|
|
END as processingStatus |
|
|
|
|
|
|
|
FROM fpsmsdb.pick_order po |
|
|
|
JOIN fpsmsdb.pick_order_line pol ON pol.poId = po.id |
|
|
|
JOIN fpsmsdb.items i ON i.id = pol.itemId |
|
|
|
LEFT JOIN fpsmsdb.uom_conversion uc ON uc.id = pol.uomId |
|
|
|
LEFT JOIN fpsmsdb.pick_order_group pog ON pog.pick_order_id = po.id AND pog.deleted = false |
|
|
|
JOIN fpsmsdb.suggested_pick_lot spl ON spl.pickOrderLineId = pol.id |
|
|
|
JOIN fpsmsdb.inventory_lot_line ill ON ill.id = spl.suggestedLotLineId |
|
|
|
JOIN fpsmsdb.inventory_lot il ON il.id = ill.inventoryLotId |
|
|
|
LEFT JOIN fpsmsdb.warehouse w ON w.id = ill.warehouseId |
|
|
|
LEFT JOIN fpsmsdb.stock_out_line sol ON sol.pickOrderLineId = pol.id AND sol.inventoryLotLineId = ill.id |
|
|
|
WHERE po.deleted = false |
|
|
|
AND po.status = 'RELEASED' |
|
|
|
AND pol.deleted = false |
|
|
|
AND ill.deleted = false |
|
|
|
AND il.deleted = false |
|
|
|
${if (userId != null) "AND po.assignTo = :userId" else ""} |
|
|
|
|
|
|
|
UNION ALL |
|
|
|
|
|
|
|
-- ✅ ADD: Query for rejected lots that might not have suggested_pick_lot entries |
|
|
|
SELECT |
|
|
|
-- Pick Order Information |
|
|
|
po.id as pickOrderId, |
|
|
|
po.code as pickOrderCode, |
|
|
|
po.targetDate as pickOrderTargetDate, |
|
|
|
po.type as pickOrderType, |
|
|
|
po.status as pickOrderStatus, |
|
|
|
po.assignTo as pickOrderAssignTo, |
|
|
|
pog.name as groupName, |
|
|
|
|
|
|
|
-- Pick Order Line Information |
|
|
|
pol.id as pickOrderLineId, |
|
|
|
pol.qty as pickOrderLineRequiredQty, |
|
|
|
pol.status as pickOrderLineStatus, |
|
|
|
|
|
|
|
-- Item Information |
|
|
|
i.id as itemId, |
|
|
|
i.code as itemCode, |
|
|
|
i.name as itemName, |
|
|
|
uc.code as uomCode, |
|
|
|
uc.udfudesc as uomDesc, |
|
|
|
|
|
|
|
-- Lot Information |
|
|
|
ill.id as lotId, |
|
|
|
il.lotNo, |
|
|
|
il.expiryDate, |
|
|
|
w.name as location, |
|
|
|
COALESCE(uc.udfudesc, 'N/A') as stockUnit, |
|
|
|
|
|
|
|
-- ✅ NULL for rejected lots |
|
|
|
NULL as availableQty, |
|
|
|
NULL as requiredQty, |
|
|
|
NULL as actualPickQty, |
|
|
|
|
|
|
|
NULL as suggestedPickLotId, |
|
|
|
ill.status as lotStatus, |
|
|
|
sol.id as stockOutLineId, |
|
|
|
sol.status as stockOutLineStatus, |
|
|
|
sol.qty as stockOutLineQty, |
|
|
|
|
|
|
|
-- Calculated fields |
|
|
|
'rejected' as lotAvailability, |
|
|
|
'rejected' as processingStatus |
|
|
|
|
|
|
|
FROM fpsmsdb.pick_order po |
|
|
|
JOIN fpsmsdb.pick_order_line pol ON pol.poId = po.id |
|
|
|
JOIN fpsmsdb.items i ON i.id = pol.itemId |
|
|
|
LEFT JOIN fpsmsdb.uom_conversion uc ON uc.id = pol.uomId |
|
|
|
LEFT JOIN fpsmsdb.pick_order_group pog ON pog.pick_order_id = po.id AND pog.deleted = false |
|
|
|
JOIN fpsmsdb.stock_out_line sol ON sol.pickOrderLineId = pol.id |
|
|
|
JOIN fpsmsdb.inventory_lot_line ill ON ill.id = sol.inventoryLotLineId |
|
|
|
JOIN fpsmsdb.inventory_lot il ON il.id = ill.inventoryLotId |
|
|
|
LEFT JOIN fpsmsdb.warehouse w ON w.id = ill.warehouseId |
|
|
|
WHERE po.deleted = false |
|
|
|
AND po.status = 'RELEASED' |
|
|
|
AND pol.deleted = false |
|
|
|
AND ill.deleted = false |
|
|
|
AND il.deleted = false |
|
|
|
AND sol.status = 'rejected' |
|
|
|
${if (userId != null) "AND po.assignTo = :userId" else ""} |
|
|
|
|
|
|
|
ORDER BY |
|
|
|
pickOrderCode ASC, |
|
|
|
itemCode ASC, |
|
|
|
expiryDate ASC, |
|
|
|
lotNo ASC |
|
|
|
""".trimIndent() |
|
|
|
|
|
|
|
println("🔍 Executing SQL for all pick order lots: $sql") |
|
|
|
|
|
|
|
val params = if (userId != null) { |
|
|
|
mapOf("userId" to userId) |
|
|
|
} else { |
|
|
|
emptyMap<String, Any>() |
|
|
|
} |
|
|
|
|
|
|
|
val result = jdbcDao.queryForList(sql, params) |
|
|
|
|
|
|
|
println("Total result count (including completed and rejected): ${result.size}") |
|
|
|
result.forEach { row -> |
|
|
|
println("Row: $row") |
|
|
|
} |
|
|
|
|
|
|
|
return result |
|
|
|
} |
|
|
|
} |