| @@ -34,49 +34,129 @@ class DoReleaseCoordinatorService( | |||
| val updateSql = """ | |||
| UPDATE fpsmsdb.do_pick_order dpo | |||
| INNER JOIN ( | |||
| WITH DoWarehouseFloor AS ( | |||
| WITH DoFloorCounts AS ( | |||
| SELECT | |||
| dol.deliveryOrderId, | |||
| w.store_id, | |||
| COUNT(DISTINCT dol.itemId) AS item_count | |||
| FROM fpsmsdb.delivery_order_line dol | |||
| LEFT JOIN fpsmsdb.inventory_lot il ON il.itemId = dol.itemId AND il.deleted = 0 | |||
| LEFT JOIN fpsmsdb.inventory_lot_line ill ON ill.inventoryLotId = il.id AND ill.deleted = 0 | |||
| LEFT JOIN fpsmsdb.warehouse w ON w.id = ill.warehouseId AND w.deleted = 0 | |||
| INNER JOIN fpsmsdb.inventory i ON i.itemId = dol.itemId | |||
| AND i.deleted = 0 | |||
| AND i.onHandQty > 0 | |||
| INNER JOIN fpsmsdb.inventory_lot il ON il.itemId = i.itemId | |||
| AND il.deleted = 0 | |||
| INNER JOIN fpsmsdb.inventory_lot_line ill ON ill.inventoryLotId = il.id | |||
| AND ill.deleted = 0 | |||
| INNER JOIN fpsmsdb.warehouse w ON w.id = ill.warehouseId | |||
| AND w.deleted = 0 | |||
| AND w.store_id IN ('2F', '4F') | |||
| WHERE dol.deleted = 0 | |||
| GROUP BY dol.deliveryOrderId, w.store_id | |||
| ), | |||
| DoFloorSummary AS ( | |||
| SELECT | |||
| do.id AS deliveryOrderId, | |||
| COALESCE(SUM(CASE WHEN dfc.store_id = '2F' THEN dfc.item_count ELSE 0 END), 0) AS count_2f, | |||
| COALESCE(SUM(CASE WHEN dfc.store_id = '4F' THEN dfc.item_count ELSE 0 END), 0) AS count_4f | |||
| FROM fpsmsdb.delivery_order do | |||
| LEFT JOIN DoFloorCounts dfc ON dfc.deliveryOrderId = do.id | |||
| WHERE do.deleted = 0 | |||
| GROUP BY do.id | |||
| ), | |||
| PreferredFloor AS ( | |||
| SELECT | |||
| deliveryOrderId, | |||
| store_id, | |||
| ROW_NUMBER() OVER ( | |||
| PARTITION BY deliveryOrderId | |||
| ORDER BY item_count DESC, store_id ASC | |||
| ) AS rn | |||
| FROM DoWarehouseFloor | |||
| WHERE store_id IS NOT NULL | |||
| CASE | |||
| WHEN count_2f > count_4f THEN '2F' | |||
| WHEN count_4f > count_2f THEN '4F' | |||
| ELSE '2F' | |||
| END AS preferred_floor, | |||
| CASE | |||
| WHEN count_2f > count_4f THEN 2 | |||
| WHEN count_4f > count_2f THEN 4 | |||
| ELSE 2 | |||
| END AS preferred_store_id | |||
| FROM DoFloorSummary | |||
| ), | |||
| TruckSelection AS ( | |||
| SELECT | |||
| do.id AS delivery_order_id, | |||
| do.estimatedArrivalDate, | |||
| pf.preferred_floor, | |||
| CASE | |||
| WHEN (SELECT COUNT(*) FROM fpsmsdb.truck t WHERE t.shopId = do.shopId AND t.deleted = 0) > 1 THEN | |||
| COALESCE( | |||
| (SELECT t.DepartureTime FROM fpsmsdb.truck t | |||
| WHERE t.shopId = do.shopId AND t.deleted = 0 | |||
| AND t.Store_id = pf.preferred_store_id | |||
| ORDER BY t.DepartureTime ASC LIMIT 1), | |||
| (SELECT t.DepartureTime FROM fpsmsdb.truck t | |||
| WHERE t.shopId = do.shopId AND t.deleted = 0 | |||
| ORDER BY t.DepartureTime ASC LIMIT 1), | |||
| '23:59:59' | |||
| ) | |||
| ELSE | |||
| COALESCE( | |||
| (SELECT t.DepartureTime FROM fpsmsdb.truck t | |||
| WHERE t.shopId = do.shopId AND t.deleted = 0 | |||
| ORDER BY t.DepartureTime ASC LIMIT 1), | |||
| '23:59:59' | |||
| ) | |||
| END AS selected_departure_time, | |||
| CASE | |||
| WHEN (SELECT COUNT(*) FROM fpsmsdb.truck t WHERE t.shopId = do.shopId AND t.deleted = 0) > 1 THEN | |||
| COALESCE( | |||
| (SELECT t.TruckLanceCode FROM fpsmsdb.truck t | |||
| WHERE t.shopId = do.shopId AND t.deleted = 0 | |||
| AND t.Store_id = pf.preferred_store_id | |||
| ORDER BY t.DepartureTime ASC LIMIT 1), | |||
| (SELECT t.TruckLanceCode FROM fpsmsdb.truck t | |||
| WHERE t.shopId = do.shopId AND t.deleted = 0 | |||
| ORDER BY t.DepartureTime ASC LIMIT 1), | |||
| 'ZZ' | |||
| ) | |||
| ELSE | |||
| COALESCE( | |||
| (SELECT t.TruckLanceCode FROM fpsmsdb.truck t | |||
| WHERE t.shopId = do.shopId AND t.deleted = 0 | |||
| ORDER BY t.DepartureTime ASC LIMIT 1), | |||
| 'ZZ' | |||
| ) | |||
| END AS selected_truck_lance, | |||
| COALESCE( | |||
| (SELECT t.LoadingSequence FROM fpsmsdb.truck t | |||
| WHERE t.shopId = do.shopId AND t.deleted = 0 | |||
| AND t.Store_id = pf.preferred_store_id | |||
| ORDER BY t.DepartureTime ASC LIMIT 1), | |||
| (SELECT t.LoadingSequence FROM fpsmsdb.truck t | |||
| WHERE t.shopId = do.shopId AND t.deleted = 0 | |||
| ORDER BY t.DepartureTime ASC LIMIT 1), | |||
| 999 | |||
| ) AS loading_sequence | |||
| FROM fpsmsdb.delivery_order do | |||
| LEFT JOIN PreferredFloor pf ON pf.deliveryOrderId = do.id | |||
| WHERE do.deleted = 0 | |||
| ) | |||
| SELECT | |||
| dpo2.id, | |||
| CONCAT('TI-', | |||
| DATE_FORMAT(dpo2.RequiredDeliveryDate, '%Y%m%d'), | |||
| '-', | |||
| COALESCE(pf.store_id, '2F'), | |||
| COALESCE(ts.preferred_floor, '2F'), | |||
| '-', | |||
| LPAD( | |||
| ROW_NUMBER() OVER ( | |||
| PARTITION BY DATE(dpo2.RequiredDeliveryDate), COALESCE(pf.store_id, '2F') | |||
| ORDER BY COALESCE(dpo2.truck_departure_time, '23:59:59'), | |||
| COALESCE(dpo2.TruckLanceCode, 'ZZ'), | |||
| COALESCE(dpo2.loading_sequence, 999), | |||
| dpo2.id | |||
| PARTITION BY DATE(dpo2.RequiredDeliveryDate), COALESCE(ts.preferred_floor, '2F') | |||
| ORDER BY COALESCE(ts.selected_departure_time, '23:59:59'), | |||
| COALESCE(ts.selected_truck_lance, 'ZZ'), | |||
| COALESCE(ts.loading_sequence, 999), | |||
| dpo2.do_order_id | |||
| ), | |||
| 3, '0' | |||
| ) | |||
| ) AS new_ticket_no | |||
| FROM fpsmsdb.do_pick_order dpo2 | |||
| LEFT JOIN PreferredFloor pf ON pf.deliveryOrderId = dpo2.do_order_id AND pf.rn = 1 | |||
| LEFT JOIN TruckSelection ts ON ts.delivery_order_id = dpo2.do_order_id | |||
| WHERE dpo2.ticket_no LIKE 'TEMP-%' | |||
| AND dpo2.deleted = 0 | |||
| ) AS ticket_mapping ON dpo.id = ticket_mapping.id | |||
| @@ -93,7 +173,7 @@ class DoReleaseCoordinatorService( | |||
| private fun getOrderedDeliveryOrderIds(ids: List<Long>): List<Long> { | |||
| try { | |||
| println("🔍 DEBUG: Getting ordered IDs for ${ids.size} orders") | |||
| println("🔍 DEBUG: First 5 IDs: ${ids.take(5)}") | |||
| val sql = """ | |||
| WITH DoFloorCounts AS ( | |||
| SELECT | |||
| @@ -202,8 +282,18 @@ class DoReleaseCoordinatorService( | |||
| 'ZZ' | |||
| ) | |||
| END AS selected_truck_lance, | |||
| (SELECT COUNT(*) FROM fpsmsdb.delivery_order_line dol | |||
| WHERE dol.deliveryOrderId = do.id AND dol.deleted = 0) AS loading_sequence | |||
| COALESCE( | |||
| (SELECT t.LoadingSequence | |||
| FROM fpsmsdb.truck t | |||
| WHERE t.shopId = do.shopId AND t.deleted = 0 | |||
| AND t.Store_id = pf.preferred_store_id | |||
| ORDER BY t.DepartureTime ASC LIMIT 1), | |||
| (SELECT t.LoadingSequence | |||
| FROM fpsmsdb.truck t | |||
| WHERE t.shopId = do.shopId AND t.deleted = 0 | |||
| ORDER BY t.DepartureTime ASC LIMIT 1), | |||
| 999 | |||
| ) AS loading_sequence | |||
| FROM fpsmsdb.delivery_order do | |||
| LEFT JOIN PreferredFloor pf ON pf.deliveryOrderId = do.id | |||
| WHERE do.id IN (${ids.joinToString(",")}) | |||
| @@ -218,26 +308,42 @@ class DoReleaseCoordinatorService( | |||
| selected_truck_lance, | |||
| loading_sequence ASC, | |||
| delivery_order_id ASC | |||
| """.trimIndent() | |||
| val results = jdbcDao.queryForList(sql) | |||
| val sortedIds = results.mapNotNull { it["id"] as? Long } | |||
| println("🔍 DEBUG: Query returned ${sortedIds.size} sorted IDs") | |||
| println("🔍 DEBUG: First 10 sorted IDs: ${sortedIds.take(10)}") | |||
| return if (sortedIds.isEmpty()) { | |||
| println("⚠️ WARNING: No sorted IDs, using original order") | |||
| ids | |||
| } else { | |||
| sortedIds | |||
| } | |||
| } catch (e: Exception) { | |||
| println("❌ ERROR: ${e.message}") | |||
| e.printStackTrace() | |||
| return ids | |||
| println("🔍 DEBUG: SQL length: ${sql.length} characters") // ✅ 添加这行 | |||
| println("🔍 DEBUG: SQL first 500 chars: ${sql.take(500)}") // ✅ 添加这行 | |||
| val results = jdbcDao.queryForList(sql) | |||
| println("🔍 DEBUG: Results type: ${results.javaClass.name}") // ✅ 添加这行 | |||
| println("🔍 DEBUG: Results size: ${results.size}") // ✅ 添加这行 | |||
| if (results.isNotEmpty()) { | |||
| println("🔍 DEBUG: First result keys: ${results[0].keys}") // ✅ 添加这行 | |||
| println("🔍 DEBUG: First result: ${results[0]}") // ✅ 添加这行 | |||
| } | |||
| val sortedIds = results.mapNotNull { row -> | |||
| (row["id"] as? Number)?.toLong() | |||
| } | |||
| println("🔍 DEBUG: Query returned ${sortedIds.size} sorted IDs") | |||
| println("🔍 DEBUG: First 10 sorted IDs: ${sortedIds.take(10)}") | |||
| return if (sortedIds.isEmpty()) { | |||
| println("⚠️ WARNING: No sorted IDs, using original order") | |||
| ids | |||
| } else { | |||
| sortedIds | |||
| } | |||
| } catch (e: Exception) { | |||
| println("❌ ERROR: ${e.message}") | |||
| println("❌ ERROR Stack Trace:") // ✅ 添加这行 | |||
| e.printStackTrace() | |||
| return ids | |||
| } | |||
| } | |||
| fun startBatchReleaseAsync(ids: List<Long>, userId: Long): MessageResponse { | |||
| if (ids.isEmpty()) { | |||
| return MessageResponse(id = null, code = "NO_IDS", name = null, type = null, | |||