From e40d5bf2ac0d20d046f96d5be49c4dfe4c5ab488 Mon Sep 17 00:00:00 2001 From: "CANCERYS\\kw093" Date: Thu, 9 Oct 2025 18:24:18 +0800 Subject: [PATCH] update --- .../jobOrder/service/JoPickOrderService.kt | 275 +++++++++--------- .../pickOrder/service/PickOrderService.kt | 21 +- .../20251009_02_enson/01_altertable_enson.sql | 5 + 3 files changed, 149 insertions(+), 152 deletions(-) create mode 100644 src/main/resources/db/changelog/changes/20251009_02_enson/01_altertable_enson.sql diff --git a/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JoPickOrderService.kt b/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JoPickOrderService.kt index eea33ef..d374174 100644 --- a/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JoPickOrderService.kt +++ b/src/main/java/com/ffii/fpsms/modules/jobOrder/service/JoPickOrderService.kt @@ -250,140 +250,136 @@ open class JoPickOrderService( val pickOrderIdsStr = pickOrderIds.joinToString(",") val sql = """ - SELECT - -- Pick Order Information - po.id as pickOrderId, - po.code as pickOrderCode, - po.consoCode as pickOrderConsoCode, - DATE_FORMAT(po.targetDate, '%Y-%m-%d') as pickOrderTargetDate, - po.type as pickOrderType, - po.status as pickOrderStatus, - po.assignTo as pickOrderAssignTo, - - -- Job Order Information - jo.id as jobOrderId, - jo.code as jobOrderCode, - - -- 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, - uc.udfShortDesc as uomShortDesc, - - -- Lot Information - ill.id as lotId, - il.lotNo, - DATE_FORMAT(il.expiryDate, '%Y-%m-%d') as expiryDate, - w.name as location, - COALESCE(uc.udfudesc, 'N/A') as stockUnit, - - -- Router Information - r.id as routerId, - ro.`order` as routerIndex, - CONCAT(COALESCE(ro.route_area, ''), COALESCE(r.route, '')) as routerRoute, - ro.route_area as routerArea, - - -- 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, - - -- Required quantity for this lot - COALESCE(spl.qty, 0) as requiredQty, - - -- Actual picked quantity - COALESCE(sol.qty, 0) as actualPickQty, - - -- Suggested pick lot information - spl.id as suggestedPickLotId, - ill.status as lotStatus, - - -- Stock out line information - sol.id as stockOutLineId, - sol.status as stockOutLineStatus, - COALESCE(sol.qty, 0) as stockOutLineQty, - - -- Additional detailed fields - COALESCE(ill.inQty, 0) as inQty, - COALESCE(ill.outQty, 0) as outQty, - COALESCE(ill.holdQty, 0) as holdQty, - COALESCE(spl.suggestedLotLineId, ill.id) as debugSuggestedLotLineId, - ill.inventoryLotId as debugInventoryLotId, - - -- Calculate total picked quantity by ALL pick orders for this lot - COALESCE(( - SELECT SUM(sol_all.qty) - FROM fpsmsdb.stock_out_line sol_all - WHERE sol_all.inventoryLotLineId = ill.id - AND sol_all.deleted = false - AND sol_all.status IN ('pending', 'checked', 'partially_completed', 'completed') - ), 0) as totalPickedByAllPickOrders, - - -- Calculate remaining available quantity correctly - (COALESCE(ill.inQty, 0) - COALESCE(ill.outQty, 0) - COALESCE(ill.holdQty, 0)) as remainingAfterAllPickOrders, - - -- Lot availability status - CASE - WHEN (il.expiryDate IS NOT NULL AND il.expiryDate < CURDATE()) THEN 'expired' - WHEN sol.status = 'rejected' THEN 'rejected' - WHEN (COALESCE(ill.inQty, 0) - COALESCE(ill.outQty, 0) - COALESCE(ill.holdQty, 0)) <= 0 THEN 'insufficient_stock' - WHEN ill.status = 'unavailable' THEN 'status_unavailable' - ELSE 'available' - END as lotAvailability, - - -- Processing status - CASE - WHEN sol.status = 'completed' THEN 'completed' - WHEN sol.status = 'rejected' THEN 'rejected' - WHEN sol.status = 'created' THEN 'pending' - ELSE 'pending' - END as processingStatus, - - -- JoPickOrder second scan status - jpo.match_status as match_status, - jpo.match_by as match_by, - jpo.match_qty as match_qty, - jpo.ticketReleaseTime as ticketReleaseTime, - jpo.ticketCompleteTime as ticketCompleteTime - - FROM fpsmsdb.pick_order po - JOIN fpsmsdb.job_order jo ON jo.id = po.joId - 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.suggested_pick_lot spl ON pol.id = spl.pickOrderLineId - LEFT JOIN fpsmsdb.inventory_lot_line ill ON spl.suggestedLotLineId = ill.id - LEFT JOIN fpsmsdb.router r ON r.inventoryLotId = ill.id AND r.deleted = false - LEFT JOIN fpsmsdb.inventory_lot il ON il.id = ill.inventoryLotId - LEFT JOIN fpsmsdb.warehouse w ON w.id = ill.warehouseId - LEFT JOIN fpsmsdb.router_order ro ON r.router_id = ro.id - LEFT JOIN fpsmsdb.stock_out_line sol ON sol.pickOrderLineId = pol.id AND sol.inventoryLotLineId = ill.id AND sol.deleted = false - LEFT JOIN fpsmsdb.jo_pick_order jpo ON jpo.pick_order_id = po.id AND jpo.item_id = pol.itemId - WHERE po.deleted = false - AND po.id IN ($pickOrderIdsStr) - AND pol.deleted = false - AND po.status IN ('PENDING', 'RELEASED', 'COMPLETED') - AND po.assignTo = :userId - AND ill.deleted = false - AND il.deleted = false - AND (spl.pickOrderLineId IS NOT NULL OR sol.pickOrderLineId IS NOT NULL) - ORDER BY - CASE WHEN sol.status = 'rejected' THEN 0 ELSE 1 END, - COALESCE(ro.`order`, 999999) ASC, - COALESCE(r.route, 999999) ASC, - po.code ASC, - i.code ASC, - il.expiryDate ASC, - il.lotNo ASC - """.trimIndent() + SELECT + -- Pick Order Information + po.id as pickOrderId, + po.code as pickOrderCode, + po.consoCode as pickOrderConsoCode, + DATE_FORMAT(po.targetDate, '%Y-%m-%d') as pickOrderTargetDate, + po.type as pickOrderType, + po.status as pickOrderStatus, + po.assignTo as pickOrderAssignTo, + + -- Job Order Information + jo.id as jobOrderId, + jo.code as jobOrderCode, + + -- 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, + uc.udfShortDesc as uomShortDesc, + + -- Lot Information + ill.id as lotId, + il.lotNo, + DATE_FORMAT(il.expiryDate, '%Y-%m-%d') as expiryDate, + w.name as location, + COALESCE(uc.udfudesc, 'N/A') as stockUnit, + + -- ✅ Simplified Router Information using warehouse + w.`order` as routerIndex, + w.code as routerRoute, + w.code as routerArea, + + -- 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, + + -- Required quantity for this lot + COALESCE(spl.qty, 0) as requiredQty, + + -- Actual picked quantity + COALESCE(sol.qty, 0) as actualPickQty, + + -- Suggested pick lot information + spl.id as suggestedPickLotId, + ill.status as lotStatus, + + -- Stock out line information + sol.id as stockOutLineId, + sol.status as stockOutLineStatus, + COALESCE(sol.qty, 0) as stockOutLineQty, + + -- Additional detailed fields + COALESCE(ill.inQty, 0) as inQty, + COALESCE(ill.outQty, 0) as outQty, + COALESCE(ill.holdQty, 0) as holdQty, + COALESCE(spl.suggestedLotLineId, ill.id) as debugSuggestedLotLineId, + ill.inventoryLotId as debugInventoryLotId, + + -- Calculate total picked quantity by ALL pick orders for this lot + COALESCE(( + SELECT SUM(sol_all.qty) + FROM fpsmsdb.stock_out_line sol_all + WHERE sol_all.inventoryLotLineId = ill.id + AND sol_all.deleted = false + AND sol_all.status IN ('pending', 'checked', 'partially_completed', 'completed') + ), 0) as totalPickedByAllPickOrders, + + -- Calculate remaining available quantity correctly + (COALESCE(ill.inQty, 0) - COALESCE(ill.outQty, 0) - COALESCE(ill.holdQty, 0)) as remainingAfterAllPickOrders, + + -- Lot availability status + CASE + WHEN (il.expiryDate IS NOT NULL AND il.expiryDate < CURDATE()) THEN 'expired' + WHEN sol.status = 'rejected' THEN 'rejected' + WHEN (COALESCE(ill.inQty, 0) - COALESCE(ill.outQty, 0) - COALESCE(ill.holdQty, 0)) <= 0 THEN 'insufficient_stock' + WHEN ill.status = 'unavailable' THEN 'status_unavailable' + ELSE 'available' + END as lotAvailability, + + -- Processing status + CASE + WHEN sol.status = 'completed' THEN 'completed' + WHEN sol.status = 'rejected' THEN 'rejected' + WHEN sol.status = 'created' THEN 'pending' + ELSE 'pending' + END as processingStatus, + + -- JoPickOrder second scan status + jpo.match_status as match_status, + jpo.match_by as match_by, + jpo.match_qty as match_qty, + jpo.ticketReleaseTime as ticketReleaseTime, + jpo.ticketCompleteTime as ticketCompleteTime + + FROM fpsmsdb.pick_order po + JOIN fpsmsdb.job_order jo ON jo.id = po.joId + 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.suggested_pick_lot spl ON pol.id = spl.pickOrderLineId + LEFT JOIN fpsmsdb.inventory_lot_line ill ON spl.suggestedLotLineId = ill.id + LEFT JOIN fpsmsdb.inventory_lot il ON il.id = ill.inventoryLotId + LEFT JOIN fpsmsdb.warehouse w ON w.id = ill.warehouseId -- ✅ 直接关联 warehouse + LEFT JOIN fpsmsdb.stock_out_line sol ON sol.pickOrderLineId = pol.id AND sol.inventoryLotLineId = ill.id AND sol.deleted = false + LEFT JOIN fpsmsdb.jo_pick_order jpo ON jpo.pick_order_id = po.id AND jpo.item_id = pol.itemId + WHERE po.deleted = false + AND po.id IN ($pickOrderIdsStr) + AND pol.deleted = false + AND po.status IN ('PENDING', 'RELEASED', 'COMPLETED') + AND po.assignTo = :userId + AND ill.deleted = false + AND il.deleted = false + AND (spl.pickOrderLineId IS NOT NULL OR sol.pickOrderLineId IS NOT NULL) + ORDER BY + CASE WHEN sol.status = 'rejected' THEN 0 ELSE 1 END, + COALESCE(w.`order`, 999999) ASC, -- ✅ 使用 warehouse.order 排序 + po.code ASC, + i.code ASC, + il.expiryDate ASC, + il.lotNo ASC + """.trimIndent() println("🔍 Executing SQL for job order hierarchical structure: $sql") println("🔍 With parameters: userId = $userId, pickOrderIds = $pickOrderIdsStr") @@ -562,11 +558,9 @@ open fun getCompletedJobOrderLotsHierarchical(userId: Long): Map { COALESCE(uc.udfudesc, 'N/A') as stockUnit, -- Router Information - r.id as routerId, - ro.`order` as routerIndex, - CONCAT(COALESCE(ro.route_area, ''), COALESCE(r.route, '')) as routerRoute, - ro.route_area as routerArea, - -- Set quantities to NULL for rejected lots + w.`order` as routerIndex, + w.code as routerRoute, + w.code as routerArea, CASE WHEN sol.status = 'rejected' THEN NULL ELSE (COALESCE(ill.inQty, 0) - COALESCE(ill.outQty, 0) - COALESCE(ill.holdQty, 0)) @@ -652,8 +646,7 @@ open fun getCompletedJobOrderLotsHierarchical(userId: Long): Map { AND (jpo.match_status = 'pending' OR jpo.match_status = 'scanned') ORDER BY CASE WHEN sol.status = 'rejected' THEN 0 ELSE 1 END, - COALESCE(ro.`order`, 999999) ASC, - COALESCE(r.route, 999999) ASC, + COALESCE(w.`order`, 999999) ASC po.code ASC, i.code ASC, il.expiryDate ASC, diff --git a/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderService.kt b/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderService.kt index 5463689..2b91dd8 100644 --- a/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderService.kt +++ b/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderService.kt @@ -3396,11 +3396,10 @@ open fun getAllPickOrderLotsWithDetailsHierarchical(userId: Long): Map