|
|
|
@@ -45,18 +45,33 @@ open class JoPickOrderService( |
|
|
|
// ✅ Update JoPickOrder status to released |
|
|
|
open fun updateHandledByForPickOrder(pickOrderId: Long, userId: Long): List<JoPickOrder> { |
|
|
|
val joPickOrders = joPickOrderRepository.findByPickOrderId(pickOrderId) |
|
|
|
|
|
|
|
// Get pick order details to populate new fields |
|
|
|
val pickOrder = pickOrderRepository.findById(pickOrderId).orElse(null) |
|
|
|
|
|
|
|
joPickOrders.forEach { |
|
|
|
it.handledBy = userId |
|
|
|
it.second_qr_scan_status = JoPickOrderStatus.pending // Set initial status |
|
|
|
it.matchStatus = JoPickOrderStatus.pending // Set initial status |
|
|
|
|
|
|
|
// Set ticket release time (similar to pick order released date) |
|
|
|
it.ticketReleaseTime = LocalDateTime.now() |
|
|
|
|
|
|
|
// Populate additional fields from pick order |
|
|
|
pickOrder?.let { po -> |
|
|
|
it.pickOrderCode = po.code |
|
|
|
it.targetDate = po.targetDate |
|
|
|
it.jobOrderId = po.jobOrder?.id |
|
|
|
it.jobOrderCode = po.jobOrder?.code |
|
|
|
} |
|
|
|
} |
|
|
|
return joPickOrderRepository.saveAll(joPickOrders) |
|
|
|
} |
|
|
|
|
|
|
|
// ✅ Complete JoPickOrder |
|
|
|
open fun completeJoPickOrdersForPickOrder(pickOrderId: Long): List<JoPickOrder> { |
|
|
|
val joPickOrders = joPickOrderRepository.findByPickOrderId(pickOrderId) |
|
|
|
joPickOrders.forEach { |
|
|
|
it.second_qr_scan_status = JoPickOrderStatus.completed |
|
|
|
it.matchStatus = JoPickOrderStatus.completed |
|
|
|
it.ticketCompleteTime = LocalDateTime.now() // Set complete time |
|
|
|
} |
|
|
|
return joPickOrderRepository.saveAll(joPickOrders) |
|
|
|
} |
|
|
|
@@ -64,9 +79,24 @@ open class JoPickOrderService( |
|
|
|
// ✅ Update JoPickOrderRecord status to released |
|
|
|
open fun updateRecordHandledByForPickOrder(pickOrderId: Long, userId: Long): List<JoPickOrderRecord> { |
|
|
|
val joPickOrderRecords = joPickOrderRecordRepository.findByPickOrderId(pickOrderId) |
|
|
|
|
|
|
|
// Get pick order details to populate new fields |
|
|
|
val pickOrder = pickOrderRepository.findById(pickOrderId).orElse(null) |
|
|
|
|
|
|
|
joPickOrderRecords.forEach { |
|
|
|
it.handledBy = userId |
|
|
|
it.second_qr_scan_status = JoPickOrderStatus.pending // Set initial status |
|
|
|
it.matchStatus = JoPickOrderStatus.pending // Set initial status |
|
|
|
|
|
|
|
// Set ticket release time |
|
|
|
it.ticketReleaseTime = LocalDateTime.now() |
|
|
|
|
|
|
|
// Populate additional fields from pick order |
|
|
|
pickOrder?.let { po -> |
|
|
|
it.pickOrderCode = po.code |
|
|
|
it.targetDate = po.targetDate |
|
|
|
it.jobOrderId = po.jobOrder?.id |
|
|
|
it.jobOrderCode = po.jobOrder?.code |
|
|
|
} |
|
|
|
} |
|
|
|
return joPickOrderRecordRepository.saveAll(joPickOrderRecords) |
|
|
|
} |
|
|
|
@@ -75,7 +105,8 @@ open class JoPickOrderService( |
|
|
|
open fun completeJoPickOrderRecordsForPickOrder(pickOrderId: Long): List<JoPickOrderRecord> { |
|
|
|
val joPickOrderRecords = joPickOrderRecordRepository.findByPickOrderId(pickOrderId) |
|
|
|
joPickOrderRecords.forEach { |
|
|
|
it.second_qr_scan_status = JoPickOrderStatus.completed |
|
|
|
it.matchStatus = JoPickOrderStatus.completed |
|
|
|
it.ticketCompleteTime = LocalDateTime.now() // Set complete time |
|
|
|
} |
|
|
|
return joPickOrderRecordRepository.saveAll(joPickOrderRecords) |
|
|
|
} |
|
|
|
@@ -93,31 +124,68 @@ open class JoPickOrderService( |
|
|
|
// ✅ Create JoPickOrder records for a pick order |
|
|
|
@Transactional |
|
|
|
open fun createJoPickOrdersForPickOrder(pickOrderId: Long, itemIds: List<Long>): List<JoPickOrder> { |
|
|
|
// Get pick order and item details |
|
|
|
val pickOrder = pickOrderRepository.findById(pickOrderId).orElse(null) |
|
|
|
|
|
|
|
val joPickOrders = itemIds.map { itemId -> |
|
|
|
// Get item code from database - 修复:使用 queryForList |
|
|
|
val itemCodeResult = jdbcDao.queryForList( |
|
|
|
"SELECT code FROM fpsmsdb.items WHERE id = :itemId", |
|
|
|
mapOf("itemId" to itemId) |
|
|
|
) |
|
|
|
val itemCode = if (itemCodeResult.isNotEmpty()) { |
|
|
|
itemCodeResult.first()["code"] as String? |
|
|
|
} else { |
|
|
|
null |
|
|
|
} |
|
|
|
|
|
|
|
JoPickOrder( |
|
|
|
pickOrderId = pickOrderId, |
|
|
|
itemId = itemId, |
|
|
|
second_qr_scan_status = JoPickOrderStatus.pending, |
|
|
|
handledBy = null |
|
|
|
matchStatus = JoPickOrderStatus.pending, |
|
|
|
handledBy = null, |
|
|
|
jobOrderId = pickOrder?.jobOrder?.id, |
|
|
|
jobOrderCode = pickOrder?.jobOrder?.code, |
|
|
|
targetDate = pickOrder?.targetDate, |
|
|
|
itemCode = itemCode, |
|
|
|
pickOrderCode = pickOrder?.code |
|
|
|
) |
|
|
|
} |
|
|
|
return joPickOrderRepository.saveAll(joPickOrders) |
|
|
|
} |
|
|
|
|
|
|
|
// ✅ Create JoPickOrderRecord records for a pick order |
|
|
|
@Transactional |
|
|
|
open fun createJoPickOrderRecordsForPickOrder(pickOrderId: Long, itemIds: List<Long>): List<JoPickOrderRecord> { |
|
|
|
// Get pick order and item details |
|
|
|
val pickOrder = pickOrderRepository.findById(pickOrderId).orElse(null) |
|
|
|
|
|
|
|
val joPickOrderRecords = itemIds.map { itemId -> |
|
|
|
// Get item code from database - 修复:使用 queryForList |
|
|
|
val itemCodeResult = jdbcDao.queryForList( |
|
|
|
"SELECT code FROM fpsmsdb.items WHERE id = :itemId", |
|
|
|
mapOf("itemId" to itemId) |
|
|
|
) |
|
|
|
val itemCode = if (itemCodeResult.isNotEmpty()) { |
|
|
|
itemCodeResult.first()["code"] as String? |
|
|
|
} else { |
|
|
|
null |
|
|
|
} |
|
|
|
|
|
|
|
JoPickOrderRecord( |
|
|
|
pickOrderId = pickOrderId, |
|
|
|
itemId = itemId, |
|
|
|
second_qr_scan_status = JoPickOrderStatus.pending, |
|
|
|
handledBy = null |
|
|
|
matchStatus = JoPickOrderStatus.pending, |
|
|
|
handledBy = null, |
|
|
|
jobOrderId = pickOrder?.jobOrder?.id, |
|
|
|
jobOrderCode = pickOrder?.jobOrder?.code, |
|
|
|
targetDate = pickOrder?.targetDate, |
|
|
|
itemCode = itemCode, |
|
|
|
pickOrderCode = pickOrder?.code, |
|
|
|
|
|
|
|
) |
|
|
|
} |
|
|
|
return joPickOrderRecordRepository.saveAll(joPickOrderRecords) |
|
|
|
} |
|
|
|
|
|
|
|
open fun getAllJobOrderLotsWithDetailsHierarchical(userId: Long): Map<String, Any?> { |
|
|
|
println("=== Debug: getAllJobOrderLotsWithDetailsHierarchical ===") |
|
|
|
println("today: ${LocalDate.now()}") |
|
|
|
@@ -139,10 +207,7 @@ open class JoPickOrderService( |
|
|
|
|
|
|
|
println("🔍 DEBUG: Found ${allAssignedPickOrders.size} job order pick orders assigned to user $userId") |
|
|
|
|
|
|
|
val visiblePickOrders = allAssignedPickOrders.filter { pickOrder -> |
|
|
|
val joPickOrders = findByPickOrderId(pickOrder.id!!) |
|
|
|
joPickOrders.none { it.hide } // Only show hide = false orders |
|
|
|
} |
|
|
|
val visiblePickOrders = allAssignedPickOrders |
|
|
|
|
|
|
|
// Filter based on assignment and status |
|
|
|
val filteredPickOrders = if (visiblePickOrders.isNotEmpty()) { |
|
|
|
@@ -283,9 +348,11 @@ open class JoPickOrderService( |
|
|
|
END as processingStatus, |
|
|
|
|
|
|
|
-- JoPickOrder second scan status |
|
|
|
jpo.second_qr_scan_status as secondQrScanStatus, |
|
|
|
jpo.second_qr_scan_by as secondQrScanBy, |
|
|
|
jpo.second_qr_scan_qty as secondQrScanQty |
|
|
|
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 |
|
|
|
@@ -385,9 +452,9 @@ open class JoPickOrderService( |
|
|
|
"routerArea" to row["routerArea"], |
|
|
|
"routerRoute" to row["routerRoute"], |
|
|
|
"uomShortDesc" to row["uomShortDesc"], |
|
|
|
"secondQrScanStatus" to row["secondQrScanStatus"], |
|
|
|
"secondQrScanBy" to row["secondQrScanBy"], |
|
|
|
"secondQrScanQty" to row["secondQrScanQty"] |
|
|
|
"match_status" to row["match_status"], |
|
|
|
"match_by" to row["match_by"], |
|
|
|
"match_qty" to row["match_qty"] |
|
|
|
) |
|
|
|
} |
|
|
|
) |
|
|
|
@@ -430,10 +497,7 @@ open fun getCompletedJobOrderLotsHierarchical(userId: Long): Map<String, Any?> { |
|
|
|
|
|
|
|
println("🔍 DEBUG: Found ${completedPickOrders.size} completed job order pick orders assigned to user $userId") |
|
|
|
|
|
|
|
val visiblePickOrders = completedPickOrders.filter { pickOrder -> |
|
|
|
val joPickOrders = findByPickOrderId(pickOrder.id!!) |
|
|
|
joPickOrders.none { it.hide } // Only show hide = false orders |
|
|
|
} |
|
|
|
val visiblePickOrders = completedPickOrders |
|
|
|
|
|
|
|
if (visiblePickOrders.isEmpty()) { |
|
|
|
println("🔍 DEBUG: No visible completed job orders found") |
|
|
|
@@ -560,9 +624,9 @@ open fun getCompletedJobOrderLotsHierarchical(userId: Long): Map<String, Any?> { |
|
|
|
END as processingStatus, |
|
|
|
|
|
|
|
-- JoPickOrder second scan status |
|
|
|
jpo.second_qr_scan_status as secondQrScanStatus, |
|
|
|
jpo.second_qr_scan_by as secondQrScanBy, |
|
|
|
jpo.second_qr_scan_qty as secondQrScanQty |
|
|
|
jpo.match_status as match_status, |
|
|
|
jpo.match_by as match_by, |
|
|
|
jpo.match_qty as match_qty |
|
|
|
|
|
|
|
FROM fpsmsdb.pick_order po |
|
|
|
JOIN fpsmsdb.job_order jo ON jo.id = po.joId |
|
|
|
@@ -585,7 +649,7 @@ open fun getCompletedJobOrderLotsHierarchical(userId: Long): Map<String, Any?> { |
|
|
|
AND ill.deleted = false |
|
|
|
AND il.deleted = false |
|
|
|
AND (spl.pickOrderLineId IS NOT NULL OR sol.pickOrderLineId IS NOT NULL) |
|
|
|
AND jpo.second_qr_scan_status = 'pending' OR jpo.second_qr_scan_status = 'scanned' |
|
|
|
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, |
|
|
|
@@ -663,7 +727,7 @@ open fun getCompletedJobOrderLotsHierarchical(userId: Long): Map<String, Any?> { |
|
|
|
"routerArea" to row["routerArea"], |
|
|
|
"routerRoute" to row["routerRoute"], |
|
|
|
"uomShortDesc" to row["uomShortDesc"], |
|
|
|
"secondQrScanStatus" to row["secondQrScanStatus"] |
|
|
|
"match_status" to row["match_status"] |
|
|
|
) |
|
|
|
} |
|
|
|
) |
|
|
|
@@ -693,7 +757,7 @@ open fun getCompletedJobOrderLotsHierarchical(userId: Long): Map<String, Any?> { |
|
|
|
// Get all completed JoPickOrderRecord records for the user |
|
|
|
val allRecords = joPickOrderRecordRepository.findAll() |
|
|
|
val completedRecords = allRecords.filter { |
|
|
|
it.second_qr_scan_status == JoPickOrderStatus.completed && |
|
|
|
it.matchStatus == JoPickOrderStatus.completed && |
|
|
|
it.handledBy == userId |
|
|
|
} |
|
|
|
|
|
|
|
@@ -712,9 +776,9 @@ open fun getCompletedJobOrderLotsHierarchical(userId: Long): Map<String, Any?> { |
|
|
|
"jobOrderCode" to jobOrder?.code, |
|
|
|
"jobOrderName" to jobOrder?.bom?.name, |
|
|
|
"itemId" to record.itemId, |
|
|
|
"secondQrScanStatus" to record.second_qr_scan_status, |
|
|
|
"secondQrScanBy" to record.second_qr_scan_by, |
|
|
|
"secondQrScanQty" to record.second_qr_scan_qty, |
|
|
|
"match_status" to record.matchStatus, |
|
|
|
"match_by" to record.matchBy, |
|
|
|
"match_qty" to record.matchQty, |
|
|
|
"handledBy" to record.handledBy, |
|
|
|
"created" to record.created, |
|
|
|
"completeDate" to pickOrder.completeDate |
|
|
|
@@ -816,7 +880,7 @@ open fun assignJobOrderPickOrderToUser(pickOrderId: Long, userId: Long): Message |
|
|
|
|
|
|
|
// ✅ 修复:使用 this 而不是 joPickOrderService |
|
|
|
this.updateHandledByForPickOrder(pickOrderId, userId) |
|
|
|
|
|
|
|
this.updateRecordHandledByForPickOrder(pickOrderId, userId) |
|
|
|
MessageResponse( |
|
|
|
id = pickOrder.id, |
|
|
|
code = pickOrder.code, |
|
|
|
@@ -838,10 +902,10 @@ open fun assignJobOrderPickOrderToUser(pickOrderId: Long, userId: Long): Message |
|
|
|
) |
|
|
|
} |
|
|
|
} |
|
|
|
// ✅ Fix the updateSecondQrScanStatus method |
|
|
|
open fun updateSecondQrScanStatus(pickOrderId: Long, itemId: Long): MessageResponse { |
|
|
|
// ✅ Fix the updateMatchStatus method |
|
|
|
open fun updateMatchStatus(pickOrderId: Long, itemId: Long): MessageResponse { |
|
|
|
try { |
|
|
|
println("=== Debug: updateSecondQrScanStatus ===") |
|
|
|
println("=== Debug: updateMatchStatus ===") |
|
|
|
println("pickOrderId: $pickOrderId, itemId: $itemId") |
|
|
|
|
|
|
|
val joPickOrder = joPickOrderRepository.findByPickOrderIdAndItemId(pickOrderId, itemId) |
|
|
|
@@ -858,7 +922,7 @@ open fun updateSecondQrScanStatus(pickOrderId: Long, itemId: Long): MessageRespo |
|
|
|
} |
|
|
|
|
|
|
|
val joPickOrderEntity = joPickOrder.get() |
|
|
|
joPickOrderEntity.second_qr_scan_status = JoPickOrderStatus.scanned // ✅ Use enum instead of string |
|
|
|
joPickOrderEntity.matchStatus = JoPickOrderStatus.scanned // ✅ Use enum instead of string |
|
|
|
joPickOrderRepository.save(joPickOrderEntity) |
|
|
|
|
|
|
|
return MessageResponse( |
|
|
|
@@ -902,14 +966,14 @@ open fun submitSecondScanQty(request: SecondScanSubmitRequest): MessageResponse |
|
|
|
} |
|
|
|
|
|
|
|
val joPickOrderEntity = joPickOrder.get() |
|
|
|
joPickOrderEntity.second_qr_scan_qty = request.qty.toInt() |
|
|
|
joPickOrderEntity.matchQty = request.qty.toInt() |
|
|
|
|
|
|
|
// ✅ Always set status to completed when submitting quantity |
|
|
|
joPickOrderEntity.second_qr_scan_status = JoPickOrderStatus.completed |
|
|
|
joPickOrderEntity.matchStatus = JoPickOrderStatus.completed |
|
|
|
|
|
|
|
joPickOrderRepository.save(joPickOrderEntity) |
|
|
|
|
|
|
|
println("✅ Updated jo_pick_order: status=${joPickOrderEntity.second_qr_scan_status}, qty=${joPickOrderEntity.second_qr_scan_qty}") |
|
|
|
println("✅ Updated jo_pick_order: status=${joPickOrderEntity.matchStatus}, qty=${joPickOrderEntity.matchQty}") |
|
|
|
|
|
|
|
return MessageResponse( |
|
|
|
id = null, |
|
|
|
@@ -992,8 +1056,8 @@ open fun recordSecondScanIssue(request: SecondScanIssueRequest): MessageResponse |
|
|
|
|
|
|
|
|
|
|
|
val joPickOrderEntity = joPickOrder.get() |
|
|
|
joPickOrderEntity.second_qr_scan_status = JoPickOrderStatus.completed |
|
|
|
joPickOrderEntity.second_qr_scan_qty = request.qty.toInt() |
|
|
|
joPickOrderEntity.matchStatus = JoPickOrderStatus.completed |
|
|
|
joPickOrderEntity.matchQty = request.qty.toInt() |
|
|
|
joPickOrderRepository.save(joPickOrderEntity) |
|
|
|
|
|
|
|
// ✅ Create pick execution issue with complete data |
|
|
|
@@ -1065,7 +1129,7 @@ open fun getCompletedJobOrderPickOrdersWithCompletedSecondScan(userId: Long): Li |
|
|
|
// Check if all items in this pick order have completed second scan |
|
|
|
val joPickOrders = findByPickOrderId(pickOrder.id!!) |
|
|
|
val allSecondScanCompleted = joPickOrders.isNotEmpty() && |
|
|
|
joPickOrders.all { it.second_qr_scan_status == JoPickOrderStatus.completed } |
|
|
|
joPickOrders.all { it.matchStatus == JoPickOrderStatus.completed } |
|
|
|
|
|
|
|
if (allSecondScanCompleted) { |
|
|
|
mapOf( |
|
|
|
@@ -1089,7 +1153,7 @@ open fun getCompletedJobOrderPickOrdersWithCompletedSecondScan(userId: Long): Li |
|
|
|
"planEnd" to jobOrder.planEnd, |
|
|
|
"secondScanCompleted" to true, |
|
|
|
"totalItems" to joPickOrders.size, |
|
|
|
"completedItems" to joPickOrders.count { it.second_qr_scan_status == JoPickOrderStatus.completed } |
|
|
|
"completedItems" to joPickOrders.count { it.matchStatus == JoPickOrderStatus.completed } |
|
|
|
) |
|
|
|
} else { |
|
|
|
println("❌ Pick order ${pickOrder.id} has incomplete second scan, skipping.") |
|
|
|
@@ -1221,9 +1285,9 @@ open fun getCompletedJobOrderPickOrderLotDetails(pickOrderId: Long): List<Map<St |
|
|
|
END as processingStatus, |
|
|
|
|
|
|
|
-- JoPickOrder second scan status |
|
|
|
jpo.second_qr_scan_status as secondQrScanStatus, |
|
|
|
jpo.second_qr_scan_by as secondQrScanBy, |
|
|
|
jpo.second_qr_scan_qty as secondQrScanQty |
|
|
|
jpo.match_status as match_status, |
|
|
|
jpo.match_by as match_by, |
|
|
|
jpo.match_qty as match_qty |
|
|
|
|
|
|
|
FROM fpsmsdb.pick_order po |
|
|
|
JOIN fpsmsdb.job_order jo ON jo.id = po.joId |
|
|
|
@@ -1296,7 +1360,7 @@ open fun getCompletedJobOrderPickOrderLotDetails(pickOrderId: Long): List<Map<St |
|
|
|
|
|
|
|
// Calculate second scan completion status |
|
|
|
val secondScanCompleted = joPickOrders.isNotEmpty() && |
|
|
|
joPickOrders.all { it.second_qr_scan_status == JoPickOrderStatus.completed } |
|
|
|
joPickOrders.all { it.matchStatus == JoPickOrderStatus.completed } |
|
|
|
|
|
|
|
mapOf( |
|
|
|
"id" to pickOrder.id, |
|
|
|
@@ -1319,7 +1383,7 @@ open fun getCompletedJobOrderPickOrderLotDetails(pickOrderId: Long): List<Map<St |
|
|
|
"planEnd" to jobOrder.planEnd, |
|
|
|
"secondScanCompleted" to secondScanCompleted, |
|
|
|
"totalItems" to joPickOrders.size, |
|
|
|
"completedItems" to joPickOrders.count { it.second_qr_scan_status == JoPickOrderStatus.completed } |
|
|
|
"completedItems" to joPickOrders.count { it.matchStatus == JoPickOrderStatus.completed } |
|
|
|
) |
|
|
|
} else { |
|
|
|
println("❌ Pick order ${pickOrder.id} has no job order, skipping.") |
|
|
|
@@ -1438,9 +1502,9 @@ open fun getCompletedJobOrderPickOrderLotDetailsForCompletedPick(pickOrderId: Lo |
|
|
|
END as processingStatus, |
|
|
|
|
|
|
|
-- JoPickOrder second scan status |
|
|
|
jpo.second_qr_scan_status as secondQrScanStatus, |
|
|
|
jpo.second_qr_scan_by as secondQrScanBy, |
|
|
|
jpo.second_qr_scan_qty as secondQrScanQty |
|
|
|
jpo.match_status as match_status, |
|
|
|
jpo.match_by as match_by, |
|
|
|
jpo.match_qty as match_qty |
|
|
|
|
|
|
|
FROM fpsmsdb.pick_order po |
|
|
|
JOIN fpsmsdb.job_order jo ON jo.id = po.joId |
|
|
|
|