| @@ -659,51 +659,7 @@ return MessageResponse( | |||||
| // ... existing code ... | // ... existing code ... | ||||
| } | } | ||||
| /* | |||||
| open fun getRouteAndIndexByInventoryLotId(inventoryLotId: Int): List<Router> { | |||||
| return routerRepository.findByInventoryLotIdAndDeletedFalse(inventoryLotId) | |||||
| .sortedWith(compareBy( | |||||
| { it.routerOrder?.order ?: 999999 }, | |||||
| { it.route ?: 999999 } | |||||
| )) | |||||
| } | |||||
| open fun getRoutesByInventoryLotId(inventoryLotId: Int): List<String> { | |||||
| return getRouteAndIndexByInventoryLotId(inventoryLotId) | |||||
| .mapNotNull { router -> | |||||
| val routeArea = router.routerOrder?.routeArea ?: "" | |||||
| val route = router.route?.toString() ?: "" | |||||
| if (routeArea.isNotEmpty() || route.isNotEmpty()) { | |||||
| "$routeArea$route" | |||||
| } else { | |||||
| null | |||||
| } | |||||
| } | |||||
| } | |||||
| open fun getRouteByItemId(itemId: Long): String? { | |||||
| val inventoryLots = inventoryLotService.findByItemId(itemId) | |||||
| if (inventoryLots.isNotEmpty()){ | |||||
| val inventoryLotId = inventoryLots.first().id?.toInt() | |||||
| return inventoryLotId?.let { lotId -> | |||||
| getRoutesByInventoryLotId(lotId).firstOrNull() | |||||
| } | |||||
| } | |||||
| return null | |||||
| } | |||||
| open fun getRouterIndexByItemId(itemId: Long): Int? { | |||||
| val inventoryLots = inventoryLotService.findByItemId(itemId) | |||||
| if (inventoryLots.isNotEmpty()){ | |||||
| val inventoryLotId = inventoryLots.first().id?.toInt() | |||||
| return inventoryLotId?.let { lotId -> | |||||
| getRouteAndIndexByInventoryLotId(lotId).firstOrNull()?.routerOrder?.order | |||||
| } | |||||
| } | |||||
| return null | |||||
| } | |||||
| */ | |||||
| open fun getLotNumbersForPickOrderByItemId(itemId: Long, pickOrderId: Long): String { | open fun getLotNumbersForPickOrderByItemId(itemId: Long, pickOrderId: Long): String { | ||||
| try { | try { | ||||
| val pickOrderLines = pickOrderLineRepository.findAllByPickOrderId(pickOrderId) | val pickOrderLines = pickOrderLineRepository.findAllByPickOrderId(pickOrderId) | ||||
| @@ -57,8 +57,13 @@ class DoPickOrderService( | |||||
| println("🔍 DEBUG: Getting next ticket number for date prefix: $datePrefix, store: $storeId") | println("🔍 DEBUG: Getting next ticket number for date prefix: $datePrefix, store: $storeId") | ||||
| try { | try { | ||||
| val sanitizedStoreId = storeId.replace("/", "") | val sanitizedStoreId = storeId.replace("/", "") | ||||
| val shortDatePrefix = if (datePrefix.length == 8) { | |||||
| datePrefix.substring(2) // 从 20251016 变成 251016 | |||||
| } else { | |||||
| datePrefix | |||||
| } | |||||
| // ✅ 修改搜索模式为新格式 | // ✅ 修改搜索模式为新格式 | ||||
| val searchPattern = "T-${datePrefix}-${sanitizedStoreId}-" // T-20250915-4F- | |||||
| val searchPattern = "T-${shortDatePrefix}-${sanitizedStoreId}-" // T-20250915-4F- | |||||
| val todayTickets = doPickOrderRepository.findByTicketNoStartingWith(searchPattern) | val todayTickets = doPickOrderRepository.findByTicketNoStartingWith(searchPattern) | ||||
| println("🔍 DEBUG: Found ${todayTickets.size} existing tickets with prefix $searchPattern") | println("🔍 DEBUG: Found ${todayTickets.size} existing tickets with prefix $searchPattern") | ||||
| todayTickets.forEach { ticket -> | todayTickets.forEach { ticket -> | ||||
| @@ -631,10 +631,9 @@ open fun getCompletedJobOrderLotsHierarchical(userId: Long): Map<String, Any?> { | |||||
| LEFT JOIN fpsmsdb.uom_conversion uc ON uc.id = pol.uomId | 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.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_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.inventory_lot il ON il.id = ill.inventoryLotId | ||||
| LEFT JOIN fpsmsdb.warehouse w ON w.id = ill.warehouseId | 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.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 | LEFT JOIN fpsmsdb.jo_pick_order jpo ON jpo.pick_order_id = po.id AND jpo.item_id = pol.itemId | ||||
| WHERE po.deleted = false | WHERE po.deleted = false | ||||
| @@ -1323,10 +1322,10 @@ open fun getCompletedJobOrderPickOrderLotDetails(pickOrderId: Long): List<Map<St | |||||
| COALESCE(uc.udfudesc, 'N/A') as stockUnit, | COALESCE(uc.udfudesc, 'N/A') as stockUnit, | ||||
| -- Router Information | -- 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, | |||||
| w.id as routerId, | |||||
| w.order as routerIndex, | |||||
| w.code as routerRoute, | |||||
| w.area as routerArea, | |||||
| -- Set quantities to NULL for rejected lots | -- Set quantities to NULL for rejected lots | ||||
| CASE | CASE | ||||
| @@ -1397,14 +1396,13 @@ open fun getCompletedJobOrderPickOrderLotDetails(pickOrderId: Long): List<Map<St | |||||
| LEFT JOIN fpsmsdb.uom_conversion uc ON uc.id = pol.uomId | 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.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_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.inventory_lot il ON il.id = ill.inventoryLotId | ||||
| LEFT JOIN fpsmsdb.warehouse w ON w.id = ill.warehouseId | 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 AND sol.deleted = false | 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 | LEFT JOIN fpsmsdb.jo_pick_order jpo ON jpo.pick_order_id = po.id AND jpo.item_id = pol.itemId | ||||
| LEFT JOIN fpsmsdb.item_uom iu ON iu.itemId = b.itemId AND iu.stockUnit = 1 | LEFT JOIN fpsmsdb.item_uom iu ON iu.itemId = b.itemId AND iu.stockUnit = 1 | ||||
| LEFT JOIN fpsmsdb.uom_conversion uc_fg ON uc_fg.id = iu.uomId | LEFT JOIN fpsmsdb.uom_conversion uc_fg ON uc_fg.id = iu.uomId | ||||
| LEFT JOIN fpsmsdb.router_order ro ON r.router_id = ro.id | |||||
| LEFT JOIN fpsmsdb.uom_conversion uc_bom ON uc_bom.id = iu.uomId | LEFT JOIN fpsmsdb.uom_conversion uc_bom ON uc_bom.id = iu.uomId | ||||
| WHERE po.deleted = false | WHERE po.deleted = false | ||||
| AND po.id = :pickOrderId | AND po.id = :pickOrderId | ||||
| @@ -1415,8 +1413,7 @@ open fun getCompletedJobOrderPickOrderLotDetails(pickOrderId: Long): List<Map<St | |||||
| AND (spl.pickOrderLineId IS NOT NULL OR sol.pickOrderLineId IS NOT NULL) | AND (spl.pickOrderLineId IS NOT NULL OR sol.pickOrderLineId IS NOT NULL) | ||||
| ORDER BY | ORDER BY | ||||
| CASE WHEN sol.status = 'rejected' THEN 0 ELSE 1 END, | 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, | po.code ASC, | ||||
| i.code ASC, | i.code ASC, | ||||
| il.expiryDate ASC, | il.expiryDate ASC, | ||||
| @@ -1540,10 +1537,10 @@ open fun getCompletedJobOrderPickOrderLotDetailsForCompletedPick(pickOrderId: Lo | |||||
| COALESCE(uc.udfudesc, 'N/A') as stockUnit, | COALESCE(uc.udfudesc, 'N/A') as stockUnit, | ||||
| -- Router Information | -- 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, | |||||
| w.id as routerId | |||||
| w.order as routerIndex | |||||
| w.code as routerRoute | |||||
| w.code as routerArea | |||||
| -- Set quantities to NULL for rejected lots | -- Set quantities to NULL for rejected lots | ||||
| CASE | CASE | ||||
| @@ -1612,12 +1609,12 @@ open fun getCompletedJobOrderPickOrderLotDetailsForCompletedPick(pickOrderId: Lo | |||||
| LEFT JOIN fpsmsdb.uom_conversion uc ON uc.id = pol.uomId | 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.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_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.inventory_lot il ON il.id = ill.inventoryLotId | ||||
| LEFT JOIN fpsmsdb.warehouse w ON w.id = ill.warehouseId | 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 AND sol.deleted = false | 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 | LEFT JOIN fpsmsdb.jo_pick_order jpo ON jpo.pick_order_id = po.id AND jpo.item_id = pol.itemId | ||||
| LEFT JOIN fpsmsdb.router_order ro ON r.router_id = ro.id | |||||
| WHERE po.deleted = false | WHERE po.deleted = false | ||||
| AND po.id = :pickOrderId | AND po.id = :pickOrderId | ||||
| AND pol.deleted = false | AND pol.deleted = false | ||||
| @@ -1627,8 +1624,7 @@ open fun getCompletedJobOrderPickOrderLotDetailsForCompletedPick(pickOrderId: Lo | |||||
| AND (spl.pickOrderLineId IS NOT NULL OR sol.pickOrderLineId IS NOT NULL) | AND (spl.pickOrderLineId IS NOT NULL OR sol.pickOrderLineId IS NOT NULL) | ||||
| ORDER BY | ORDER BY | ||||
| CASE WHEN sol.status = 'rejected' THEN 0 ELSE 1 END, | 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, | po.code ASC, | ||||
| i.code ASC, | i.code ASC, | ||||
| il.expiryDate ASC, | il.expiryDate ASC, | ||||
| @@ -60,6 +60,7 @@ import com.ffii.fpsms.modules.master.web.models.MessageResponse | |||||
| import com.ffii.fpsms.modules.jobOrder.entity.JoPickOrderRepository | import com.ffii.fpsms.modules.jobOrder.entity.JoPickOrderRepository | ||||
| import com.ffii.fpsms.modules.jobOrder.entity.JoPickOrderRecordRepository | import com.ffii.fpsms.modules.jobOrder.entity.JoPickOrderRecordRepository | ||||
| import com.ffii.fpsms.modules.jobOrder.enums.JoPickOrderStatus | import com.ffii.fpsms.modules.jobOrder.enums.JoPickOrderStatus | ||||
| @Service | @Service | ||||
| open class PickOrderService( | open class PickOrderService( | ||||
| private val jdbcDao: JdbcDao, | private val jdbcDao: JdbcDao, | ||||
| @@ -84,7 +85,8 @@ open class PickOrderService( | |||||
| private val doPickOrderRepository: DoPickOrderRepository, | private val doPickOrderRepository: DoPickOrderRepository, | ||||
| private val userRepository: UserRepository, | private val userRepository: UserRepository, | ||||
| private val joPickOrderRepository: JoPickOrderRepository, // ✅ 添加这行 | private val joPickOrderRepository: JoPickOrderRepository, // ✅ 添加这行 | ||||
| private val joPickOrderRecordRepository: JoPickOrderRecordRepository | |||||
| private val joPickOrderRecordRepository: JoPickOrderRecordRepository, | |||||
| ) : AbstractBaseEntityService<PickOrder, Long, PickOrderRepository>(jdbcDao, pickOrderRepository) { | ) : AbstractBaseEntityService<PickOrder, Long, PickOrderRepository>(jdbcDao, pickOrderRepository) { | ||||
| @@ -331,7 +333,7 @@ open class PickOrderService( | |||||
| open fun assignPickCode(): String { | open fun assignPickCode(): String { | ||||
| val suffixFormat = "%03d" | val suffixFormat = "%03d" | ||||
| val pattern = "yyyyMMdd" | |||||
| val pattern = "yyMMdd" | |||||
| val formatter = DateTimeFormatter.ofPattern(pattern) | val formatter = DateTimeFormatter.ofPattern(pattern) | ||||
| val prefix = "P" | val prefix = "P" | ||||
| @@ -2698,66 +2700,7 @@ open fun autoAssignAndReleasePickOrderByStoreAndTicket(storeId: String, ticketNo | |||||
| } | } | ||||
| println("✅ Filtered result count: ${filteredResults.size}") | println("✅ Filtered result count: ${filteredResults.size}") | ||||
| /* | |||||
| // ✅ Add router information for each lot | |||||
| val enrichedResults = filteredResults.map { row -> | |||||
| val inventoryLotId = row["debugInventoryLotId"] as? Number | |||||
| // Get router information for this inventory lot | |||||
| val routerInfo = if (inventoryLotId != null) { | |||||
| try { | |||||
| val router = routerRepository.findFirstByInventoryLotIdAndDeletedFalse(inventoryLotId.toInt()) | |||||
| if (router != null) { | |||||
| mapOf( | |||||
| "routerIndex" to (router.routerOrder?.order ?: 0), | |||||
| "routerRoute" to "${router.routerOrder?.routeArea ?: ""}${router.route ?: ""}", | |||||
| "routerArea" to (router.routerOrder?.routeArea ?: ""), | |||||
| "routerItemCode" to (router.itemCode ?: 0), | |||||
| "routerItemName" to (router.itemName ?: ""), | |||||
| "routerUomId" to (router.uomId ?: 0), | |||||
| ) | |||||
| } else { | |||||
| mapOf( | |||||
| "routerIndex" to 0, | |||||
| "routerRoute" to "", | |||||
| "routerArea" to "", | |||||
| "routerItemCode" to 0, | |||||
| "routerItemName" to "", | |||||
| "routerUomId" to 0, | |||||
| "routerNoofCarton" to 0 | |||||
| ) | |||||
| } | |||||
| } catch (e: Exception) { | |||||
| println("⚠️ Error getting router info for inventoryLotId $inventoryLotId: ${e.message}") | |||||
| mapOf( | |||||
| "routerIndex" to 0, | |||||
| "routerRoute" to "", | |||||
| "routerArea" to "", | |||||
| "routerItemCode" to 0, | |||||
| "routerItemName" to "", | |||||
| "routerUomId" to 0, | |||||
| "routerNoofCarton" to 0 | |||||
| ) | |||||
| } | |||||
| } else { | |||||
| mapOf( | |||||
| "routerIndex" to 0, | |||||
| "routerRoute" to "", | |||||
| "routerArea" to "", | |||||
| "routerItemCode" to 0, | |||||
| "routerItemName" to "", | |||||
| "routerUomId" to 0, | |||||
| "routerNoofCarton" to 0 | |||||
| ) | |||||
| } | |||||
| // Combine original row with router information | |||||
| row.toMutableMap().apply { | |||||
| putAll(routerInfo) | |||||
| } | |||||
| } | |||||
| */ | |||||
| val enrichedResults = filteredResults | val enrichedResults = filteredResults | ||||
| return enrichedResults | return enrichedResults | ||||
| } | } | ||||
| @@ -3975,7 +3918,10 @@ open fun getLotDetailsByPickOrderId(pickOrderId: Long): List<Map<String, Any>> { | |||||
| println("❌ No pick order lines found for pick order: $pickOrderId") | println("❌ No pick order lines found for pick order: $pickOrderId") | ||||
| return emptyList() | return emptyList() | ||||
| } | } | ||||
| println("✅ Found ${pickOrderLines.size} pick order lines") | |||||
| // Build the SQL query similar to getAllPickOrderLotsWithDetailsWithoutAutoAssign | // Build the SQL query similar to getAllPickOrderLotsWithDetailsWithoutAutoAssign | ||||
| // but filtered by specific pickOrderId | // but filtered by specific pickOrderId | ||||
| val sql = """ | val sql = """ | ||||
| @@ -4010,9 +3956,9 @@ open fun getLotDetailsByPickOrderId(pickOrderId: Long): List<Map<String, Any>> { | |||||
| COALESCE(uc.udfudesc, 'N/A') as stockUnit, | COALESCE(uc.udfudesc, 'N/A') as stockUnit, | ||||
| -- Router Information | -- Router Information | ||||
| r.id as routerId, | |||||
| ro.`order` as routerIndex, | |||||
| CONCAT(COALESCE(ro.route_area, ''), COALESCE(r.route, '')) as routerRoute, | |||||
| w.id as routerId, | |||||
| w.`order` as routerIndex, | |||||
| -- Set quantities to NULL for rejected lots | -- Set quantities to NULL for rejected lots | ||||
| @@ -4090,7 +4036,6 @@ open fun getLotDetailsByPickOrderId(pickOrderId: Long): List<Map<String, Any>> { | |||||
| LEFT JOIN fpsmsdb.uom_conversion uc ON uc.id = pol.uomId | 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.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_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.inventory_lot il ON il.id = ill.inventoryLotId | ||||
| LEFT JOIN fpsmsdb.warehouse w ON w.id = ill.warehouseId | 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 AND sol.deleted = false | LEFT JOIN fpsmsdb.stock_out_line sol ON sol.pickOrderLineId = pol.id AND sol.inventoryLotLineId = ill.id AND sol.deleted = false | ||||
| @@ -4102,8 +4047,7 @@ open fun getLotDetailsByPickOrderId(pickOrderId: Long): List<Map<String, Any>> { | |||||
| AND (spl.pickOrderLineId IS NOT NULL OR sol.pickOrderLineId IS NOT NULL) | AND (spl.pickOrderLineId IS NOT NULL OR sol.pickOrderLineId IS NOT NULL) | ||||
| ORDER BY | ORDER BY | ||||
| CASE WHEN sol.status = 'rejected' THEN 0 ELSE 1 END, -- Show rejected lots first | CASE WHEN sol.status = 'rejected' THEN 0 ELSE 1 END, -- Show rejected lots first | ||||
| COALESCE(ro.`order`, 999999) ASC, | |||||
| COALESCE(r.route, 999999) ASC, | |||||
| COALESCE(w.order, 999999) ASC, | |||||
| po.code ASC, | po.code ASC, | ||||
| i.code ASC, | i.code ASC, | ||||
| il.expiryDate ASC, | il.expiryDate ASC, | ||||