|
|
|
@@ -494,13 +494,6 @@ open class PickOrderService( |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
// Actual Pick Lots |
|
|
|
// val actualPickLots = pol.stockOutLines |
|
|
|
// val finalActualPickLots = actualPickLots.map { |
|
|
|
// ActualPickLotInConso( |
|
|
|
// |
|
|
|
// ) |
|
|
|
// } |
|
|
|
|
|
|
|
// Return |
|
|
|
PickOrderLineInConso( |
|
|
|
@@ -2221,245 +2214,257 @@ open fun autoAssignAndReleasePickOrderByStoreAndTicket(storeId: String, ticketNo |
|
|
|
} |
|
|
|
} |
|
|
|
@Transactional(rollbackFor = [java.lang.Exception::class]) |
|
|
|
open fun autoAssignAndReleasePickOrderByStore(userId: Long, storeId: String): MessageResponse { |
|
|
|
try { |
|
|
|
println("=== DEBUG: autoAssignAndReleasePickOrderByStore ===") |
|
|
|
println("userId: $userId, storeId: $storeId") |
|
|
|
|
|
|
|
val zero = BigDecimal.ZERO |
|
|
|
val releasedBy = SecurityUtils.getUser().getOrNull() |
|
|
|
val user = userService.find(userId).orElse(null) |
|
|
|
if (user == null) { |
|
|
|
return MessageResponse(id = null, name = "User not found", code = "ERROR", type = "pickorder", |
|
|
|
message = "User with ID $userId not found", errorPosition = null) |
|
|
|
} |
|
|
|
|
|
|
|
val sql = """ |
|
|
|
SELECT DISTINCT dpo.pick_order_id AS pickOrderId |
|
|
|
FROM do_pick_order dpo |
|
|
|
WHERE dpo.deleted = false |
|
|
|
AND dpo.ticket_status = 'pending' |
|
|
|
AND dpo.store_id = :storeId |
|
|
|
AND dpo.pick_order_id IS NOT NULL |
|
|
|
""".trimIndent() |
|
|
|
val idRows = jdbcDao.queryForList(sql, mapOf("storeId" to storeId)) |
|
|
|
val pickOrderIdsByStore = idRows.mapNotNull { row -> |
|
|
|
when (val id = row["pickOrderId"]) { |
|
|
|
is Number -> id.toLong() |
|
|
|
is String -> id.toLongOrNull() |
|
|
|
else -> null |
|
|
|
open fun autoAssignAndReleasePickOrderByStore(userId: Long, storeId: String): MessageResponse { |
|
|
|
try { |
|
|
|
println("=== DEBUG: autoAssignAndReleasePickOrderByStore ===") |
|
|
|
println("userId: $userId, storeId: $storeId") |
|
|
|
|
|
|
|
val zero = BigDecimal.ZERO |
|
|
|
val releasedBy = SecurityUtils.getUser().getOrNull() |
|
|
|
val user = userService.find(userId).orElse(null) |
|
|
|
if (user == null) { |
|
|
|
return MessageResponse(id = null, name = "User not found", code = "ERROR", type = "pickorder", |
|
|
|
message = "User with ID $userId not found", errorPosition = null) |
|
|
|
} |
|
|
|
}.toSet() |
|
|
|
println("Candidate pickOrderIds by store $storeId: $pickOrderIdsByStore") |
|
|
|
|
|
|
|
if (pickOrderIdsByStore.isEmpty()) { |
|
|
|
return MessageResponse(id = null, name = "No pick orders", code = "NO_ORDERS", type = "pickorder", |
|
|
|
message = "No pending pick orders found for store $storeId", errorPosition = null) |
|
|
|
} |
|
|
|
|
|
|
|
// Add this check after line 2142 (before finding availablePickOrders) |
|
|
|
// ✅ Check if user already has pick orders in progress |
|
|
|
val userExistingOrders = pickOrderRepository.findAllByAssignToAndStatusIn( |
|
|
|
user, |
|
|
|
listOf(PickOrderStatus.PENDING, PickOrderStatus.RELEASED) // Only active orders, not completed |
|
|
|
).filter { it.deliveryOrder != null } |
|
|
|
|
|
|
|
if (userExistingOrders.isNotEmpty()) { |
|
|
|
println("🔍 DEBUG: User $userId already has ${userExistingOrders.size} pick orders in progress:") |
|
|
|
userExistingOrders.forEach { po -> |
|
|
|
println("�� DEBUG: Existing order ${po.id}: code=${po.code}, status=${po.status}") |
|
|
|
|
|
|
|
val sql = """ |
|
|
|
SELECT DISTINCT dpo.pick_order_id AS pickOrderId |
|
|
|
FROM do_pick_order dpo |
|
|
|
WHERE dpo.deleted = false |
|
|
|
AND dpo.ticket_status = 'pending' |
|
|
|
AND dpo.store_id = :storeId |
|
|
|
AND dpo.pick_order_id IS NOT NULL |
|
|
|
""".trimIndent() |
|
|
|
val idRows = jdbcDao.queryForList(sql, mapOf("storeId" to storeId)) |
|
|
|
val pickOrderIdsByStore = idRows.mapNotNull { row -> |
|
|
|
when (val id = row["pickOrderId"]) { |
|
|
|
is Number -> id.toLong() |
|
|
|
is String -> id.toLongOrNull() |
|
|
|
else -> null |
|
|
|
} |
|
|
|
}.toSet() |
|
|
|
println("Candidate pickOrderIds by store $storeId: $pickOrderIdsByStore") |
|
|
|
|
|
|
|
if (pickOrderIdsByStore.isEmpty()) { |
|
|
|
return MessageResponse(id = null, name = "No pick orders", code = "NO_ORDERS", type = "pickorder", |
|
|
|
message = "No pending pick orders found for store $storeId", errorPosition = null) |
|
|
|
} |
|
|
|
return MessageResponse( |
|
|
|
id = null, |
|
|
|
name = "User already has pick orders", |
|
|
|
code = "USER_BUSY", |
|
|
|
type = "pickorder", |
|
|
|
message = "User $userId already has ${userExistingOrders.size} pick orders in progress. Cannot assign new orders.", |
|
|
|
errorPosition = null, |
|
|
|
entity = mapOf( |
|
|
|
"existingOrders" to userExistingOrders.map { mapOf( |
|
|
|
"id" to it.id, |
|
|
|
"code" to it.code, |
|
|
|
"status" to it.status?.value |
|
|
|
)} |
|
|
|
|
|
|
|
// ✅ Check if user already has pick orders in progress |
|
|
|
val userExistingOrders = pickOrderRepository.findAllByAssignToAndStatusIn( |
|
|
|
user, |
|
|
|
listOf(PickOrderStatus.PENDING, PickOrderStatus.RELEASED) |
|
|
|
).filter { it.deliveryOrder != null } |
|
|
|
|
|
|
|
if (userExistingOrders.isNotEmpty()) { |
|
|
|
println("🔍 DEBUG: User $userId already has ${userExistingOrders.size} pick orders in progress:") |
|
|
|
userExistingOrders.forEach { po -> |
|
|
|
println("🔍 DEBUG: Existing order ${po.id}: code=${po.code}, status=${po.status}") |
|
|
|
} |
|
|
|
return MessageResponse( |
|
|
|
id = null, |
|
|
|
name = "User already has pick orders", |
|
|
|
code = "USER_BUSY", |
|
|
|
type = "pickorder", |
|
|
|
message = "User $userId already has ${userExistingOrders.size} pick orders in progress. Cannot assign new orders.", |
|
|
|
errorPosition = null, |
|
|
|
entity = mapOf( |
|
|
|
"existingOrders" to userExistingOrders.map { mapOf( |
|
|
|
"id" to it.id, |
|
|
|
"code" to it.code, |
|
|
|
"status" to it.status?.value |
|
|
|
)} |
|
|
|
) |
|
|
|
) |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
// Continue with existing logic... |
|
|
|
val availablePickOrders = pickOrderRepository |
|
|
|
.findAll() |
|
|
|
.filter { it.id != null && pickOrderIdsByStore.contains(it.id!!) } |
|
|
|
.filter { it.deliveryOrder != null } |
|
|
|
.filter { it.assignTo == null } |
|
|
|
.filter { it.status == PickOrderStatus.PENDING || it.status == PickOrderStatus.RELEASED } |
|
|
|
.sortedBy { it.targetDate } |
|
|
|
.take(1) |
|
|
|
|
|
|
|
if (availablePickOrders.isEmpty()) { |
|
|
|
return MessageResponse(id = null, name = "No available pick orders", code = "NO_ORDERS", type = "pickorder", |
|
|
|
message = "No unassigned pick orders available for store $storeId", errorPosition = null) |
|
|
|
} |
|
|
|
|
|
|
|
val selected = availablePickOrders.first() |
|
|
|
val currUser = SecurityUtils.getUser().orElseThrow() |
|
|
|
|
|
|
|
// If still PENDING, perform full release flow; if already RELEASED, skip creation duplication |
|
|
|
if (selected.status == PickOrderStatus.PENDING) { |
|
|
|
val newConsoCode = assignConsoCode() |
|
|
|
|
|
|
|
val stockOut = StockOut().apply { |
|
|
|
this.type = "job" |
|
|
|
this.consoPickOrderCode = newConsoCode |
|
|
|
this.status = StockOutStatus.PENDING.status |
|
|
|
this.handler = currUser.id |
|
|
|
} |
|
|
|
val savedStockOut = stockOutRepository.saveAndFlush(stockOut) |
|
|
|
|
|
|
|
selected.apply { |
|
|
|
this.releasedBy = releasedBy |
|
|
|
status = PickOrderStatus.RELEASED |
|
|
|
this.consoCode = newConsoCode |
|
|
|
|
|
|
|
val availablePickOrders = pickOrderRepository |
|
|
|
.findAll() |
|
|
|
.filter { it.id != null && pickOrderIdsByStore.contains(it.id!!) } |
|
|
|
.filter { it.deliveryOrder != null } |
|
|
|
.filter { it.assignTo == null } |
|
|
|
.filter { it.status == PickOrderStatus.PENDING || it.status == PickOrderStatus.RELEASED } |
|
|
|
.sortedBy { it.targetDate } |
|
|
|
.take(1) |
|
|
|
|
|
|
|
if (availablePickOrders.isEmpty()) { |
|
|
|
return MessageResponse(id = null, name = "No available pick orders", code = "NO_ORDERS", type = "pickorder", |
|
|
|
message = "No unassigned pick orders available for store $storeId", errorPosition = null) |
|
|
|
} |
|
|
|
|
|
|
|
val suggestions = suggestedPickLotService.suggestionForPickOrders( |
|
|
|
SuggestedPickLotForPoRequest(pickOrders = listOf(selected)) |
|
|
|
) |
|
|
|
val saveSuggestedPickLots = suggestedPickLotService.saveAll(suggestions.suggestedList) |
|
|
|
pickOrderRepository.saveAndFlush(selected) |
|
|
|
|
|
|
|
val inventoryLotLines = inventoryLotLineRepository.findAllByIdIn( |
|
|
|
saveSuggestedPickLots.mapNotNull { it.suggestedLotLine?.id } |
|
|
|
) |
|
|
|
saveSuggestedPickLots.forEach { lot -> |
|
|
|
val lotLineId = lot.suggestedLotLine?.id |
|
|
|
if (lotLineId != null) { |
|
|
|
val idx = inventoryLotLines.indexOf(lot.suggestedLotLine) |
|
|
|
if (idx >= 0) { |
|
|
|
val currentHold = inventoryLotLines[idx].holdQty ?: zero |
|
|
|
val addHold = lot.qty ?: zero |
|
|
|
inventoryLotLines[idx].holdQty = currentHold.plus(addHold) |
|
|
|
|
|
|
|
val selected = availablePickOrders.first() |
|
|
|
val currUser = SecurityUtils.getUser().orElseThrow() |
|
|
|
|
|
|
|
// If still PENDING, perform full release flow |
|
|
|
if (selected.status == PickOrderStatus.PENDING) { |
|
|
|
val newConsoCode = assignConsoCode() |
|
|
|
|
|
|
|
val stockOut = StockOut().apply { |
|
|
|
this.type = "job" |
|
|
|
this.consoPickOrderCode = newConsoCode |
|
|
|
this.status = StockOutStatus.PENDING.status |
|
|
|
this.handler = currUser.id |
|
|
|
} |
|
|
|
val savedStockOut = stockOutRepository.saveAndFlush(stockOut) |
|
|
|
|
|
|
|
selected.apply { |
|
|
|
this.releasedBy = releasedBy |
|
|
|
status = PickOrderStatus.RELEASED |
|
|
|
this.consoCode = newConsoCode |
|
|
|
} |
|
|
|
|
|
|
|
val suggestions = suggestedPickLotService.suggestionForPickOrders( |
|
|
|
SuggestedPickLotForPoRequest(pickOrders = listOf(selected)) |
|
|
|
) |
|
|
|
val saveSuggestedPickLots = suggestedPickLotService.saveAll(suggestions.suggestedList) |
|
|
|
pickOrderRepository.saveAndFlush(selected) |
|
|
|
|
|
|
|
val inventoryLotLines = inventoryLotLineRepository.findAllByIdIn( |
|
|
|
saveSuggestedPickLots.mapNotNull { it.suggestedLotLine?.id } |
|
|
|
) |
|
|
|
saveSuggestedPickLots.forEach { lot -> |
|
|
|
val lotLineId = lot.suggestedLotLine?.id |
|
|
|
if (lotLineId != null) { |
|
|
|
val idx = inventoryLotLines.indexOf(lot.suggestedLotLine) |
|
|
|
if (idx >= 0) { |
|
|
|
val currentHold = inventoryLotLines[idx].holdQty ?: zero |
|
|
|
val addHold = lot.qty ?: zero |
|
|
|
inventoryLotLines[idx].holdQty = currentHold.plus(addHold) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
inventoryLotLineRepository.saveAll(inventoryLotLines) |
|
|
|
|
|
|
|
var precreated = 0 |
|
|
|
saveSuggestedPickLots.forEach { lot -> |
|
|
|
val polId = lot.pickOrderLine?.id |
|
|
|
val illId = lot.suggestedLotLine?.id |
|
|
|
if (polId != null && illId != null) { |
|
|
|
val existing = stockOutLIneRepository.findByPickOrderLineIdAndInventoryLotLineIdAndDeletedFalse(polId, illId) |
|
|
|
if (existing.isEmpty()) { |
|
|
|
val pol = pickOrderLineRepository.findById(polId).orElse(null) |
|
|
|
val ill = inventoryLotLineRepository.findById(illId).orElse(null) |
|
|
|
if (pol != null && ill != null) { |
|
|
|
val line = com.ffii.fpsms.modules.stock.entity.StockOutLine().apply { |
|
|
|
this.stockOut = savedStockOut |
|
|
|
this.pickOrderLine = pol |
|
|
|
this.inventoryLotLine = ill |
|
|
|
this.item = pol.item |
|
|
|
this.status = com.ffii.fpsms.modules.stock.web.model.StockOutLineStatus.PENDING.status |
|
|
|
this.qty = 0.0 |
|
|
|
inventoryLotLineRepository.saveAll(inventoryLotLines) |
|
|
|
|
|
|
|
var precreated = 0 |
|
|
|
saveSuggestedPickLots.forEach { lot -> |
|
|
|
val polId = lot.pickOrderLine?.id |
|
|
|
val illId = lot.suggestedLotLine?.id |
|
|
|
if (polId != null && illId != null) { |
|
|
|
val existing = stockOutLIneRepository.findByPickOrderLineIdAndInventoryLotLineIdAndDeletedFalse(polId, illId) |
|
|
|
if (existing.isEmpty()) { |
|
|
|
val pol = pickOrderLineRepository.findById(polId).orElse(null) |
|
|
|
val ill = inventoryLotLineRepository.findById(illId).orElse(null) |
|
|
|
if (pol != null && ill != null) { |
|
|
|
val line = com.ffii.fpsms.modules.stock.entity.StockOutLine().apply { |
|
|
|
this.stockOut = savedStockOut |
|
|
|
this.pickOrderLine = pol |
|
|
|
this.inventoryLotLine = ill |
|
|
|
this.item = pol.item |
|
|
|
this.status = com.ffii.fpsms.modules.stock.web.model.StockOutLineStatus.PENDING.status |
|
|
|
this.qty = 0.0 |
|
|
|
} |
|
|
|
stockOutLIneRepository.save(line) |
|
|
|
precreated++ |
|
|
|
} |
|
|
|
stockOutLIneRepository.save(line) |
|
|
|
precreated++ |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
println("Precreated $precreated stock out lines for store $storeId") |
|
|
|
} |
|
|
|
println("Precreated $precreated stock out lines for store $storeId") |
|
|
|
} |
|
|
|
|
|
|
|
// Assign user (both pending->released and already released) |
|
|
|
selected.assignTo = user |
|
|
|
pickOrderRepository.saveAndFlush(selected) |
|
|
|
val deliveryOrder = selected.deliveryOrder |
|
|
|
if (deliveryOrder != null) { |
|
|
|
val targetDate = deliveryOrder.estimatedArrivalDate?.toLocalDate() ?: LocalDate.now() |
|
|
|
val datePrefix = targetDate.format(DateTimeFormatter.ofPattern("ddMMyy")) |
|
|
|
|
|
|
|
println("�� DEBUG: Target date: $targetDate, Date prefix: $datePrefix") |
|
|
|
|
|
|
|
val storeId = if (deliveryOrder.supplier?.code == "P06B") "4/F" else "2/F" |
|
|
|
println("🔍 DEBUG: Determined store ID: $storeId") |
|
|
|
|
|
|
|
// Get next ticket number for this date and store |
|
|
|
val nextTicketNumber = doPickOrderService.getNextTicketNumber(datePrefix, storeId) |
|
|
|
println("🔍 DEBUG: Next ticket number: $nextTicketNumber") |
|
|
|
|
|
|
|
// Assign user (both pending->released and already released) |
|
|
|
selected.assignTo = user |
|
|
|
pickOrderRepository.saveAndFlush(selected) |
|
|
|
|
|
|
|
// ✅ Find truck by shop ID with earliest departure time |
|
|
|
val truck = deliveryOrder.shop?.id?.let { shopId -> |
|
|
|
println("🔍 DEBUG: Looking for truck with shop ID: $shopId") |
|
|
|
val trucks = truckRepository.findByShopIdAndDeletedFalse(shopId) |
|
|
|
println("🔍 DEBUG: Found ${trucks.size} trucks for shop $shopId") |
|
|
|
val selectedTruck = trucks.minByOrNull { it.departureTime ?: LocalTime.MAX } |
|
|
|
println("🔍 DEBUG: Selected truck: ID=${selectedTruck?.id}, DepartureTime=${selectedTruck?.departureTime}") |
|
|
|
selectedTruck |
|
|
|
// ✅ 更新 DoPickOrderRecord,填充新字段 |
|
|
|
val deliveryOrder = selected.deliveryOrder |
|
|
|
if (deliveryOrder != null) { |
|
|
|
val targetDate = deliveryOrder.estimatedArrivalDate?.toLocalDate() ?: LocalDate.now() |
|
|
|
val datePrefix = targetDate.format(DateTimeFormatter.ofPattern("ddMMyy")) |
|
|
|
|
|
|
|
println("🔍 DEBUG: Target date: $targetDate, Date prefix: $datePrefix") |
|
|
|
|
|
|
|
// ✅ Find truck by shop ID with earliest departure time |
|
|
|
val truck = deliveryOrder.shop?.id?.let { shopId -> |
|
|
|
println("🔍 DEBUG: Looking for truck with shop ID: $shopId") |
|
|
|
val trucks = truckRepository.findByShopIdAndDeletedFalse(shopId) |
|
|
|
println("🔍 DEBUG: Found ${trucks.size} trucks for shop $shopId") |
|
|
|
val selectedTruck = trucks.minByOrNull { it.departureTime ?: LocalTime.MAX } |
|
|
|
println("🔍 DEBUG: Selected truck: ID=${selectedTruck?.id}, DepartureTime=${selectedTruck?.departureTime}") |
|
|
|
selectedTruck |
|
|
|
} |
|
|
|
|
|
|
|
// ✅ 根据 truck 的 Store_id 字段确定 storeId |
|
|
|
val determinedStoreId = when (truck?.storeId) { |
|
|
|
4 -> "4/F" |
|
|
|
2 -> "2/F" |
|
|
|
else -> "2/F" |
|
|
|
} |
|
|
|
|
|
|
|
// Get next ticket number for this date and store |
|
|
|
val nextTicketNumber = doPickOrderService.getNextTicketNumber(datePrefix, determinedStoreId) |
|
|
|
println("🔍 DEBUG: Next ticket number: $nextTicketNumber") |
|
|
|
|
|
|
|
println("🔍 DEBUG: Processing ${deliveryOrder.deliveryOrderLines.size} delivery order lines") |
|
|
|
|
|
|
|
// ✅ UPDATE existing do_pick_order_record entries instead of creating new ones |
|
|
|
val existingRecords = doPickOrderRecordRepository.findByPickOrderId(selected.id!!) |
|
|
|
println("🔍 DEBUG: Found ${existingRecords.size} existing DoPickOrderRecord entries for pick order ${selected.id}") |
|
|
|
|
|
|
|
if (existingRecords.isNotEmpty()) { |
|
|
|
// ✅ Update existing records |
|
|
|
existingRecords.forEach { record -> |
|
|
|
record.handledBy = user.id |
|
|
|
record.ticketStatus = DoPickOrderStatus.released |
|
|
|
// ✅ 填充新字段 |
|
|
|
record.truckLanceCode = truck?.truckLanceCode |
|
|
|
record.shopCode = deliveryOrder.shop?.code |
|
|
|
record.shopName = deliveryOrder.shop?.name |
|
|
|
record.requiredDeliveryDate = targetDate |
|
|
|
println("🔍 DEBUG: Updating existing DoPickOrderRecord ID: ${record.id} - handledBy: ${user.id}, status: released") |
|
|
|
} |
|
|
|
doPickOrderRecordRepository.saveAll(existingRecords) |
|
|
|
println("✅ Updated ${existingRecords.size} existing DoPickOrderRecord entries") |
|
|
|
} else { |
|
|
|
// ✅ Only create new records if none exist (fallback) |
|
|
|
println("⚠️ No existing DoPickOrderRecord entries found, creating new ones") |
|
|
|
deliveryOrder.deliveryOrderLines.forEach { line -> |
|
|
|
println("🔍 DEBUG: Processing line - Store ID: $determinedStoreId") |
|
|
|
|
|
|
|
val doPickOrderRecord = DoPickOrderRecord( |
|
|
|
storeId = determinedStoreId, |
|
|
|
ticketNo = nextTicketNumber, |
|
|
|
ticketStatus = DoPickOrderStatus.released, |
|
|
|
truckId = truck?.id, |
|
|
|
pickOrderId = selected.id, |
|
|
|
truckDepartureTime = truck?.departureTime, |
|
|
|
shopId = deliveryOrder.shop?.id, |
|
|
|
handledBy = user.id, |
|
|
|
// ✅ 填充新增字段 |
|
|
|
truckLanceCode = truck?.truckLanceCode, |
|
|
|
shopCode = deliveryOrder.shop?.code, |
|
|
|
shopName = deliveryOrder.shop?.name, |
|
|
|
requiredDeliveryDate = targetDate |
|
|
|
) |
|
|
|
|
|
|
|
println("🔍 DEBUG: Creating new DoPickOrderRecord - Store: $determinedStoreId, Ticket: $nextTicketNumber, Truck: ${truck?.id}") |
|
|
|
|
|
|
|
val savedDoPickOrderRecord = doPickOrderRecordRepository.save(doPickOrderRecord) |
|
|
|
println("🔍 DEBUG: Saved new DoPickOrderRecord - ID: ${savedDoPickOrderRecord.id}") |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
println("🔍 DEBUG: Processing ${deliveryOrder.deliveryOrderLines.size} delivery order lines") |
|
|
|
doPickOrderService.updateHandledByForPickOrder(selected.id!!, user.id!!) |
|
|
|
println("✅ Updated DoPickOrder handledBy to user $userId for pick order ${selected.id}") |
|
|
|
|
|
|
|
// Replace lines 2253-2275 with this: |
|
|
|
// ✅ UPDATE existing do_pick_order_record entries instead of creating new ones |
|
|
|
val existingRecords = doPickOrderRecordRepository.findByPickOrderId(selected.id!!) |
|
|
|
println("🔍 DEBUG: Found ${existingRecords.size} existing DoPickOrderRecord entries for pick order ${selected.id}") |
|
|
|
|
|
|
|
if (existingRecords.isNotEmpty()) { |
|
|
|
// ✅ Update existing records |
|
|
|
existingRecords.forEach { record -> |
|
|
|
record.handledBy = user.id |
|
|
|
record.ticketStatus = DoPickOrderStatus.released |
|
|
|
println("🔍 DEBUG: Updating existing DoPickOrderRecord ID: ${record.id} - handledBy: ${user.id}, status: released") |
|
|
|
} |
|
|
|
doPickOrderRecordRepository.saveAll(existingRecords) |
|
|
|
println("✅ Updated ${existingRecords.size} existing DoPickOrderRecord entries") |
|
|
|
} else { |
|
|
|
// ✅ Only create new records if none exist (fallback) |
|
|
|
println("⚠️ No existing DoPickOrderRecord entries found, creating new ones") |
|
|
|
deliveryOrder.deliveryOrderLines.forEach { line -> |
|
|
|
val storeId = if (deliveryOrder.supplier?.code == "P06B") "4/F" else "2/F" |
|
|
|
println(" DEBUG: Processing line - Item ID: ${line.item?.id}, Store ID: $storeId") |
|
|
|
|
|
|
|
val doPickOrderRecord = DoPickOrderRecord( |
|
|
|
storeId = storeId, |
|
|
|
ticketNo = nextTicketNumber, |
|
|
|
ticketStatus = DoPickOrderStatus.released, // ✅ Set to released |
|
|
|
truckId = truck?.id, |
|
|
|
pickOrderId = selected.id, |
|
|
|
truckDepartureTime = truck?.departureTime, |
|
|
|
itemId = line.item?.id, |
|
|
|
shopId = deliveryOrder.shop?.id, |
|
|
|
shopPoSupplierId = deliveryOrder.shop?.id, |
|
|
|
handledBy = user.id |
|
|
|
) |
|
|
|
|
|
|
|
println(" DEBUG: Creating new DoPickOrderRecord - Store: $storeId, Ticket: $nextTicketNumber, Truck: ${truck?.id}") |
|
|
|
|
|
|
|
val savedDoPickOrderRecord = doPickOrderRecordRepository.save(doPickOrderRecord) |
|
|
|
println("🔍 DEBUG: Saved new DoPickOrderRecord - ID: ${savedDoPickOrderRecord.id}") |
|
|
|
} |
|
|
|
} |
|
|
|
return MessageResponse( |
|
|
|
id = null, |
|
|
|
name = "Pick order assigned", |
|
|
|
code = "SUCCESS", |
|
|
|
type = "pickorder", |
|
|
|
message = "Assigned to user $userId for store $storeId", |
|
|
|
errorPosition = null, |
|
|
|
entity = mapOf("pickOrderIds" to listOf(selected.id!!), "storeId" to storeId, "status" to selected.status?.value) |
|
|
|
) |
|
|
|
} catch (e: Exception) { |
|
|
|
e.printStackTrace() |
|
|
|
return MessageResponse( |
|
|
|
id = null, name = "Failed to auto-assign by store", code = "ERROR", type = "pickorder", |
|
|
|
message = "Failed to auto-assign by store: ${e.message}", errorPosition = null |
|
|
|
) |
|
|
|
} |
|
|
|
doPickOrderService.updateHandledByForPickOrder(selected.id!!, user.id!!) |
|
|
|
println("✅ Updated DoPickOrder handledBy to user $userId for pick order ${selected.id}") |
|
|
|
return MessageResponse( |
|
|
|
id = null, |
|
|
|
name = "Pick order assigned", |
|
|
|
code = "SUCCESS", |
|
|
|
type = "pickorder", |
|
|
|
message = "Assigned to user $userId for store $storeId", |
|
|
|
errorPosition = null, |
|
|
|
entity = mapOf("pickOrderIds" to listOf(selected.id!!), "storeId" to storeId, "status" to selected.status?.value) |
|
|
|
) |
|
|
|
} catch (e: Exception) { |
|
|
|
e.printStackTrace() |
|
|
|
return MessageResponse( |
|
|
|
id = null, name = "Failed to auto-assign by store", code = "ERROR", type = "pickorder", |
|
|
|
message = "Failed to auto-assign by store: ${e.message}", errorPosition = null |
|
|
|
) |
|
|
|
} |
|
|
|
} |
|
|
|
open fun getAllPickOrderLotsWithDetailsWithAutoAssign(userId: Long): List<Map<String, Any>> { |
|
|
|
println("=== Debug: getAllPickOrderLotsWithDetailsWithAutoAssign ===") |
|
|
|
println("today: ${LocalDate.now()}") |
|
|
|
@@ -2642,13 +2647,13 @@ if (existingRecords.isNotEmpty()) { |
|
|
|
val router = routerRepository.findFirstByInventoryLotIdAndDeletedFalse(inventoryLotId.toInt()) |
|
|
|
if (router != null) { |
|
|
|
mapOf( |
|
|
|
"routerIndex" to (router.index ?: 0), |
|
|
|
"routerRoute" to (router.route ?: ""), |
|
|
|
"routerArea" to (router.area ?: ""), |
|
|
|
"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), |
|
|
|
"routerNoofCarton" to (router.noofCarton ?: 0) |
|
|
|
|
|
|
|
) |
|
|
|
} else { |
|
|
|
mapOf( |
|
|
|
@@ -2715,7 +2720,7 @@ if (existingRecords.isNotEmpty()) { |
|
|
|
val truckInfo = if (shop?.id != null) { |
|
|
|
try { |
|
|
|
jdbcDao.queryForMap(""" |
|
|
|
SELECT truckNo, DepartureTime |
|
|
|
SELECT TruckLanceCode, DepartureTime |
|
|
|
FROM truck |
|
|
|
WHERE shopId = :shopId AND deleted = false |
|
|
|
LIMIT 1 |
|
|
|
@@ -2741,7 +2746,7 @@ if (existingRecords.isNotEmpty()) { |
|
|
|
"shopAddress" to buildShopAddress(shop), |
|
|
|
"shopPoNo" to (supplier?.code ?: ""), |
|
|
|
"numberOfCartons" to (po.pickOrderLines.size), |
|
|
|
"truckNo" to (truckInfo?.get("truckNo") ?: ""), // ✅ Add truck number |
|
|
|
"TruckLanceCode" to (truckInfo?.get("TruckLanceCode") ?: ""), // ✅ Add truck number |
|
|
|
"DepartureTime" to (truckInfo?.get("DepartureTime") ?: ""), // ✅ Add departure time |
|
|
|
"qrCodeData" to (po.id ?: 0L) |
|
|
|
) |
|
|
|
@@ -2767,10 +2772,7 @@ if (existingRecords.isNotEmpty()) { |
|
|
|
println("❌ Pick order not found with ID: $pickOrderId") |
|
|
|
return emptyList() |
|
|
|
} |
|
|
|
if (doPickOrderRepository.findByPickOrderId(pickOrderId).firstOrNull()?.hide == true) { |
|
|
|
println("🔍 Pick order $pickOrderId is hidden, returning empty list") |
|
|
|
return emptyList() |
|
|
|
} |
|
|
|
|
|
|
|
println("🔍 Found pick order: ${pickOrder.code}, type: ${pickOrder.type?.value}, status: ${pickOrder.status?.value}") |
|
|
|
|
|
|
|
if (pickOrder.type?.value != "do") { |
|
|
|
@@ -2801,14 +2803,14 @@ if (existingRecords.isNotEmpty()) { |
|
|
|
val trucksForShop = truckRepository.findByShopIdAndDeletedFalse(shop.id) |
|
|
|
println("🔍 Trucks for shop ${shop.id}: ${trucksForShop.size}") |
|
|
|
trucksForShop.forEach { t -> |
|
|
|
println(" - Truck ID: ${t.id}, TruckNo: ${t.truckNo}, ShopId: ${t.shop?.id}, Deleted: ${t.deleted}") |
|
|
|
println(" - Truck ID: ${t.id}, truckLanceCode: ${t.truckLanceCode}, ShopId: ${t.shop?.id}, Deleted: ${t.deleted}") |
|
|
|
} |
|
|
|
|
|
|
|
// Take the first truck (or null if none found) |
|
|
|
val selectedTruck = trucksForShop.firstOrNull() |
|
|
|
|
|
|
|
if (selectedTruck != null) { |
|
|
|
println("✅ Selected truck: ID=${selectedTruck.id}, TruckNo=${selectedTruck.truckNo}, DepartureTime=${selectedTruck.departureTime}") |
|
|
|
println("✅ Selected truck: ID=${selectedTruck.id}, truckLanceCode=${selectedTruck.truckLanceCode}, DepartureTime=${selectedTruck.departureTime}") |
|
|
|
} else { |
|
|
|
println("❌ No truck found for shopId ${shop.id}") |
|
|
|
} |
|
|
|
@@ -2854,7 +2856,7 @@ if (existingRecords.isNotEmpty()) { |
|
|
|
"shopAddress" to buildShopAddress(shop), |
|
|
|
"shopPoNo" to (supplier?.code ?: ""), |
|
|
|
"numberOfCartons" to (pickOrder.pickOrderLines.size), |
|
|
|
"truckNo" to (truck?.truckNo ?: ""), // ✅ Use entity property |
|
|
|
"truckLanceCode" to (truck?.truckLanceCode ?: ""), // ✅ Use entity property |
|
|
|
"DepartureTime" to (truck?.departureTime?.toString() ?: ""), |
|
|
|
"ticketNo" to ticketNo, |
|
|
|
"storeId" to dpoStoreId, |
|
|
|
@@ -2880,10 +2882,7 @@ if (existingRecords.isNotEmpty()) { |
|
|
|
println("❌ Pick order not found with ID: $pickOrderId") |
|
|
|
return emptyList() |
|
|
|
} |
|
|
|
if (doPickOrderRepository.findByPickOrderId(pickOrderId).firstOrNull()?.hide == true) { |
|
|
|
println("🔍 Pick order $pickOrderId is hidden, returning empty list") |
|
|
|
return emptyList() |
|
|
|
} |
|
|
|
|
|
|
|
println("🔍 Found pick order: ${pickOrder.code}, type: ${pickOrder.type?.value}, status: ${pickOrder.status?.value}") |
|
|
|
|
|
|
|
if (pickOrder.type?.value != "do") { |
|
|
|
@@ -2914,14 +2913,14 @@ if (existingRecords.isNotEmpty()) { |
|
|
|
val trucksForShop = truckRepository.findByShopIdAndDeletedFalse(shop.id) |
|
|
|
println("🔍 Trucks for shop ${shop.id}: ${trucksForShop.size}") |
|
|
|
trucksForShop.forEach { t -> |
|
|
|
println(" - Truck ID: ${t.id}, TruckNo: ${t.truckNo}, ShopId: ${t.shop?.id}, Deleted: ${t.deleted}") |
|
|
|
println(" - Truck ID: ${t.id}, TruckLanceCode: ${t.truckLanceCode}, ShopId: ${t.shop?.id}, Deleted: ${t.deleted}") |
|
|
|
} |
|
|
|
|
|
|
|
// Take the first truck (or null if none found) |
|
|
|
val selectedTruck = trucksForShop.firstOrNull() |
|
|
|
|
|
|
|
if (selectedTruck != null) { |
|
|
|
println("✅ Selected truck: ID=${selectedTruck.id}, TruckNo=${selectedTruck.truckNo}, DepartureTime=${selectedTruck.departureTime}") |
|
|
|
println("✅ Selected truck: ID=${selectedTruck.id}, TruckLanceCode=${selectedTruck.truckLanceCode}, DepartureTime=${selectedTruck.departureTime}") |
|
|
|
} else { |
|
|
|
println("❌ No truck found for shopId ${shop.id}") |
|
|
|
} |
|
|
|
@@ -2967,7 +2966,7 @@ if (existingRecords.isNotEmpty()) { |
|
|
|
"shopAddress" to buildShopAddress(shop), |
|
|
|
"shopPoNo" to (supplier?.code ?: ""), |
|
|
|
"numberOfCartons" to (pickOrder.pickOrderLines.size), |
|
|
|
"truckNo" to (truck?.truckNo ?: ""), // ✅ Use entity property |
|
|
|
"TruckLanceCode" to (truck?.truckLanceCode ?: ""), // ✅ Use entity property |
|
|
|
"DepartureTime" to (truck?.departureTime?.toString() ?: ""), |
|
|
|
"ticketNo" to ticketNo, |
|
|
|
"storeId" to dpoStoreId, |
|
|
|
@@ -3093,16 +3092,18 @@ open fun getAllPickOrderLotsWithDetailsWithoutAutoAssign(userId: Long): List<Map |
|
|
|
w.name as location, |
|
|
|
COALESCE(uc.udfudesc, 'N/A') as stockUnit, |
|
|
|
|
|
|
|
-- Router Information |
|
|
|
-- Router Information |
|
|
|
r.id as routerId, |
|
|
|
r.index as routerIndex, |
|
|
|
r.route as routerRoute, |
|
|
|
|
|
|
|
ro.`order` as routerIndex, |
|
|
|
CONCAT(COALESCE(ro.route_area, ''), COALESCE(r.route, '')) as routerRoute, |
|
|
|
ro.route_area as routerArea, |
|
|
|
|
|
|
|
|
|
|
|
-- ✅ 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, |
|
|
|
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, |
|
|
|
@@ -3168,31 +3169,32 @@ open fun getAllPickOrderLotsWithDetailsWithoutAutoAssign(userId: Long): List<Map |
|
|
|
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.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.stock_out_line sol ON sol.pickOrderLineId = pol.id AND sol.inventoryLotLineId = ill.id AND sol.deleted = false |
|
|
|
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, -- Show rejected lots first |
|
|
|
COALESCE(r.index, 0) ASC, |
|
|
|
po.code ASC, |
|
|
|
i.code ASC, |
|
|
|
il.expiryDate ASC, |
|
|
|
il.lotNo ASC |
|
|
|
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.router_order ro ON r.router_id = ro.id |
|
|
|
LEFT 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 AND sol.deleted = false |
|
|
|
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() |
|
|
|
|
|
|
|
println("🔍 Executing SQL for all pick order lots with details (no auto-assign): $sql") |
|
|
|
@@ -3219,13 +3221,13 @@ open fun getAllPickOrderLotsWithDetailsWithoutAutoAssign(userId: Long): List<Map |
|
|
|
val router = routerRepository.findFirstByInventoryLotIdAndDeletedFalse(inventoryLotId.toInt()) |
|
|
|
if (router != null) { |
|
|
|
mapOf( |
|
|
|
"routerIndex" to (router.index ?: 0), |
|
|
|
|
|
|
|
"routerRoute" to (router.route ?: ""), |
|
|
|
"routerArea" to (router.area ?: ""), |
|
|
|
|
|
|
|
"routerItemCode" to (router.itemCode ?: 0), |
|
|
|
"routerItemName" to (router.itemName ?: ""), |
|
|
|
"routerUomId" to (router.uomId ?: 0), |
|
|
|
"routerNoofCarton" to (router.noofCarton ?: 0) |
|
|
|
|
|
|
|
|
|
|
|
) |
|
|
|
} else { |
|
|
|
mapOf( |
|
|
|
@@ -3295,12 +3297,9 @@ open fun getAllPickOrderLotsWithDetailsHierarchical(userId: Long): Map<String, A |
|
|
|
).filter { it.deliveryOrder != null } // Only pick orders with doId |
|
|
|
|
|
|
|
println("🔍 DEBUG: Found ${allAssignedPickOrders.size} pick orders assigned to user $userId") |
|
|
|
val visiblePickOrders = allAssignedPickOrders.filter { pickOrder -> |
|
|
|
val doPickOrders = doPickOrderRepository.findByPickOrderId(pickOrder.id!!) |
|
|
|
doPickOrders.none { it.hide } // 只显示 hide = false 的订单 |
|
|
|
} |
|
|
|
|
|
|
|
// ✅ NEW LOGIC: Filter based on assignment and status |
|
|
|
val filteredPickOrders = if (visiblePickOrders.isNotEmpty()) { |
|
|
|
val filteredPickOrders = if (allAssignedPickOrders.isNotEmpty()) { |
|
|
|
// Check if there are any RELEASED orders assigned to this user (active work) |
|
|
|
val assignedReleasedOrders = allAssignedPickOrders.filter { |
|
|
|
it.status == PickOrderStatus.RELEASED && it.assignTo?.id == userId |
|
|
|
@@ -3315,7 +3314,7 @@ open fun getAllPickOrderLotsWithDetailsHierarchical(userId: Long): Map<String, A |
|
|
|
val completedOrders = allAssignedPickOrders.filter { it.status == PickOrderStatus.COMPLETED } |
|
|
|
if (completedOrders.isNotEmpty()) { |
|
|
|
val latestCompleted = completedOrders.maxByOrNull { it.completeDate ?: it.modified ?: LocalDateTime.MIN } |
|
|
|
println(" DEBUG: No assigned RELEASED orders, showing latest completed order: ${latestCompleted?.code}") |
|
|
|
println("🔍 DEBUG: No assigned RELEASED orders, showing latest completed order: ${latestCompleted?.code}") |
|
|
|
listOfNotNull(latestCompleted) |
|
|
|
} else { |
|
|
|
println("🔍 DEBUG: No orders found") |
|
|
|
@@ -3372,9 +3371,9 @@ open fun getAllPickOrderLotsWithDetailsHierarchical(userId: Long): Map<String, A |
|
|
|
|
|
|
|
-- Router Information |
|
|
|
r.id as routerId, |
|
|
|
r.index as routerIndex, |
|
|
|
r.route as routerRoute, |
|
|
|
r.area as routerArea, |
|
|
|
ro.`order` as routerIndex, |
|
|
|
CONCAT(COALESCE(ro.route_area, ''), COALESCE(r.route, '')) as routerRoute, |
|
|
|
ro.route_area as routerArea, |
|
|
|
|
|
|
|
-- ✅ FIXED: Set quantities to NULL for rejected lots |
|
|
|
CASE |
|
|
|
@@ -3455,7 +3454,8 @@ open fun getAllPickOrderLotsWithDetailsHierarchical(userId: Long): Map<String, A |
|
|
|
ON sol.pickOrderLineId = pol.id AND sol.inventoryLotLineId = ll.lotLineId AND sol.deleted = false |
|
|
|
|
|
|
|
LEFT JOIN fpsmsdb.inventory_lot_line ill ON ill.id = ll.lotLineId |
|
|
|
LEFT JOIN fpsmsdb.router r ON r.inventoryLotId = ill.id AND r.deleted = false |
|
|
|
LEFT JOIN router r ON r.inventoryLotId = ill.inventoryLotId AND r.deleted = false |
|
|
|
LEFT JOIN router_order ro ON r.router_id = ro.id |
|
|
|
LEFT JOIN fpsmsdb.inventory_lot il ON il.id = ill.inventoryLotId |
|
|
|
LEFT JOIN fpsmsdb.warehouse w ON w.id = ill.warehouseId |
|
|
|
|
|
|
|
@@ -3470,7 +3470,8 @@ open fun getAllPickOrderLotsWithDetailsHierarchical(userId: Long): Map<String, A |
|
|
|
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(r.index, 0) ASC, |
|
|
|
COALESCE(ro.`order`, 999999) ASC, |
|
|
|
COALESCE(r.route, 999999) ASC, |
|
|
|
po.code ASC, |
|
|
|
i.code ASC, |
|
|
|
il.expiryDate ASC, |
|
|
|
@@ -3807,48 +3808,7 @@ open fun confirmLotSubstitution(req: LotSubstitutionConfirmRequest): MessageResp |
|
|
|
errorPosition = null |
|
|
|
) |
|
|
|
} |
|
|
|
open fun updateDoPickOrderHideStatus(pickOrderId: Long, hide: Boolean): MessageResponse { |
|
|
|
return try { |
|
|
|
// ✅ 修复:根据 pickOrderId 查找 do_pick_order 记录 |
|
|
|
val doPickOrders = doPickOrderRepository.findByPickOrderId(pickOrderId) |
|
|
|
if (doPickOrders.isEmpty()) { |
|
|
|
MessageResponse( |
|
|
|
id = null, |
|
|
|
name = "Pick order not found", |
|
|
|
code = "ERROR", |
|
|
|
type = "pickorder", |
|
|
|
message = "No do_pick_order found for pickOrderId $pickOrderId", |
|
|
|
errorPosition = "pickOrderId" |
|
|
|
) |
|
|
|
} else { |
|
|
|
// ✅ 更新所有相关的 do_pick_order 记录 |
|
|
|
doPickOrders.forEach { doPickOrder -> |
|
|
|
doPickOrder.hide = hide |
|
|
|
doPickOrderRepository.save(doPickOrder) |
|
|
|
} |
|
|
|
|
|
|
|
MessageResponse( |
|
|
|
id = null, |
|
|
|
name = "Hide status updated", |
|
|
|
code = "SUCCESS", |
|
|
|
type = "pickorder", |
|
|
|
message = "Updated hide status for ${doPickOrders.size} do_pick_order records to $hide", |
|
|
|
errorPosition = null |
|
|
|
) |
|
|
|
} |
|
|
|
} catch (e: Exception) { |
|
|
|
println("❌ Error in updateDoPickOrderHideStatus: ${e.message}") |
|
|
|
e.printStackTrace() |
|
|
|
MessageResponse( |
|
|
|
id = null, |
|
|
|
name = "Failed to update hide status", |
|
|
|
code = "ERROR", |
|
|
|
type = "pickorder", |
|
|
|
message = "Failed to update hide status: ${e.message}", |
|
|
|
errorPosition = null |
|
|
|
) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
open fun getCompletedDoPickOrders( |
|
|
|
userId: Long, |
|
|
|
pickOrderCode: String?, |
|
|
|
@@ -3914,7 +3874,7 @@ open fun getCompletedDoPickOrders( |
|
|
|
"ticketNo" to firstFgOrder["ticketNo"], |
|
|
|
"shopPoNo" to firstFgOrder["shopPoNo"], |
|
|
|
"numberOfCartons" to firstFgOrder["numberOfCartons"], |
|
|
|
"truckNo" to firstFgOrder["truckNo"], |
|
|
|
"TruckLanceCode" to firstFgOrder["TruckLanceCode"], |
|
|
|
"storeId" to firstFgOrder["storeId"], |
|
|
|
"completedDate" to (pickOrder.completeDate?.toString() ?: pickOrder.modified?.toString()), |
|
|
|
"fgPickOrders" to fgPickOrders |
|
|
|
@@ -3990,8 +3950,9 @@ open fun getLotDetailsByPickOrderId(pickOrderId: Long): List<Map<String, Any>> { |
|
|
|
|
|
|
|
-- Router Information |
|
|
|
r.id as routerId, |
|
|
|
r.index as routerIndex, |
|
|
|
r.route as routerRoute, |
|
|
|
ro.`order` as routerIndex, |
|
|
|
CONCAT(COALESCE(ro.route_area, ''), COALESCE(r.route, '')) as routerRoute, |
|
|
|
|
|
|
|
|
|
|
|
-- Set quantities to NULL for rejected lots |
|
|
|
CASE |
|
|
|
@@ -4080,7 +4041,8 @@ open fun getLotDetailsByPickOrderId(pickOrderId: Long): List<Map<String, Any>> { |
|
|
|
AND (spl.pickOrderLineId IS NOT NULL OR sol.pickOrderLineId IS NOT NULL) |
|
|
|
ORDER BY |
|
|
|
CASE WHEN sol.status = 'rejected' THEN 0 ELSE 1 END, -- Show rejected lots first |
|
|
|
COALESCE(r.index, 0) ASC, |
|
|
|
COALESCE(ro.`order`, 999999) ASC, |
|
|
|
COALESCE(r.route, 999999) ASC, |
|
|
|
po.code ASC, |
|
|
|
i.code ASC, |
|
|
|
il.expiryDate ASC, |
|
|
|
|