kelvin.yau 20 години тому
джерело
коміт
562a6ac924
4 змінених файлів з 233 додано та 302 видалено
  1. +222
    -294
      src/main/java/com/ffii/fpsms/modules/jobOrder/service/JoPickOrderService.kt
  2. +8
    -6
      src/main/java/com/ffii/fpsms/modules/jobOrder/web/JobOrderController.kt
  3. +2
    -1
      src/main/java/com/ffii/fpsms/modules/jobOrder/web/model/CreateJobOrderRequest.kt
  4. +1
    -1
      src/main/java/com/ffii/fpsms/modules/productProcess/service/ProductProcessService.kt

+ 222
- 294
src/main/java/com/ffii/fpsms/modules/jobOrder/service/JoPickOrderService.kt Переглянути файл

@@ -414,7 +414,14 @@ open class JoPickOrderService(
val uom = pol.uom
val lineId = pol.id!!
val lineSuggestedLots = suggestedPickLots.filter { it.pickOrderLine?.id == pol.id }

val jpo = joPickOrders.firstOrNull { it.itemId == item?.id }
println("jpo: $jpo")
val user = userService.find(jpo?.handledBy?:0L)
println("user: $user")
val handlerName = jpo?.handledBy?.let { uid ->
userService.find(uid).orElse(null)?.name
}
println("handlerName: $handlerName")
// 构建 lots 数据
val lots = lineSuggestedLots.mapNotNull { spl ->
val ill = spl.suggestedLotLine
@@ -428,7 +435,10 @@ open class JoPickOrderService(
it.pickOrderLine?.id == pol.id && it.inventoryLotLine?.id == ill.id
}
val jpo = joPickOrders.firstOrNull { it.itemId == item?.id }

val handlerName = jpo?.handledBy?.let { uid ->
userService.find(uid).orElse(null)?.name
}
println("handlerName: $handlerName")
val availableQty = if (sol?.status == "rejected") {
null
} else {
@@ -490,7 +500,8 @@ open class JoPickOrderService(
uomCode = uom?.code,
uomDesc = uom?.udfudesc,
status = pol.status?.value,
lots = lots
lots = lots,
handler = handlerName
)
}

@@ -536,273 +547,194 @@ open class JoPickOrderService(
}
// Get completed job order pick orders (for second tab)
// Fix the getCompletedJobOrderLotsHierarchical method
open fun getCompletedJobOrderLotsHierarchical(userId: Long): Map<String, Any?> {
println("=== Debug: getCompletedJobOrderLotsHierarchical ===")
println("today: ${LocalDate.now()}")
println("userId filter: $userId")
open fun getCompletedJobOrderLotsHierarchical(userId: Long): Map<String, Any?> {
println("=== Debug: getCompletedJobOrderLotsHierarchical (repo version) ===")
println("today: ${LocalDate.now()}")
println("userId filter: $userId")
// Get all COMPLETED pick orders assigned to the user with joId
val user = userService.find(userId).orElse(null)
if (user == null) {
println("❌ User not found: $userId")
return emptyMap()
}
val user = userService.find(userId).orElse(null)
if (user == null) {
println("❌ User not found: $userId")
return mapOf("pickOrder" to null, "pickOrderLines" to emptyList<Map<String, Any?>>())
}
// Get all COMPLETED pick orders assigned to user that have joId
val completedPickOrders = pickOrderRepository.findAllByAssignToIdAndStatusIn(
userId,
listOf(PickOrderStatus.COMPLETED)
).filter { it.jobOrder != null } // Only pick orders with joId

println("🔍 DEBUG: Found ${completedPickOrders.size} completed job order pick orders assigned to user $userId")

val visiblePickOrders = completedPickOrders
// 1. 找出当前用户所有 COMPLETED 的 JO pick order
val completedPickOrders = pickOrderRepository
.findAllByAssignToIdAndStatusIn(userId, listOf(PickOrderStatus.COMPLETED))
.filter { it.jobOrder != null }
if (visiblePickOrders.isEmpty()) {
println("🔍 DEBUG: No visible completed job orders found")
return mapOf(
"pickOrder" to null as Any?,
"pickOrderLines" to emptyList<Map<String, Any>>() as Any?
)
}
println("🔍 DEBUG: Found ${completedPickOrders.size} completed job order pick orders assigned to user $userId")
// For completed orders, show the latest one
val latestCompletedOrder = visiblePickOrders.maxByOrNull {
it.completeDate ?: it.modified ?: LocalDateTime.MIN
}
if (completedPickOrders.isEmpty()) {
return mapOf("pickOrder" to null, "pickOrderLines" to emptyList<Map<String, Any?>>())
}
if (latestCompletedOrder == null) {
println("🔍 DEBUG: No latest completed order found")
return mapOf(
"pickOrder" to null as Any?,
"pickOrderLines" to emptyList<Map<String, Any>>() as Any?
)
}
// 2. 取最新的一张
val latestCompletedOrder = completedPickOrders.maxByOrNull {
it.completeDate ?: it.modified ?: LocalDateTime.MIN
} ?: return mapOf("pickOrder" to null, "pickOrderLines" to emptyList<Map<String, Any?>>())
println("🔍 DEBUG: Using latest completed order: ${latestCompletedOrder.code}")
println("🔍 DEBUG: Using latest completed order: ${latestCompletedOrder.code}")
// Use the same SQL query approach as getAllJobOrderLotsWithDetailsHierarchical
val pickOrderIds = listOf(latestCompletedOrder.id!!)
val pickOrderIdsStr = pickOrderIds.joinToString(",")
val pickOrder = latestCompletedOrder
val jobOrder = pickOrder.jobOrder!!
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,
'jo' 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
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))
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
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

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 = '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)
AND (jpo.match_status = 'pending' OR jpo.match_status = 'scanned')
ORDER BY
CASE WHEN sol.status = 'rejected' THEN 0 ELSE 1 END,
COALESCE(w.`order`, 999999) ASC,
po.code ASC,
i.code ASC,
il.expiryDate ASC,
il.lotNo ASC
""".trimIndent()
// 3. 组装 pickOrder 信息
val pickOrderInfo = mapOf(
"id" to pickOrder.id,
"code" to pickOrder.code,
"consoCode" to pickOrder.consoCode,
"targetDate" to pickOrder.targetDate?.let {
"${it.year}-${"%02d".format(it.monthValue)}-${"%02d".format(it.dayOfMonth)}"
},
"type" to "jo",
"status" to pickOrder.status?.value,
"assignTo" to pickOrder.assignTo?.id,
"jobOrder" to mapOf(
"id" to jobOrder.id,
"code" to jobOrder.code,
"name" to "Job Order ${jobOrder.code}"
)
)
println("🔍 Executing SQL for completed job order hierarchical structure: $sql")
println("🔍 With parameters: userId = $userId, pickOrderIds = $pickOrderIdsStr")
// 4. 找出所有 pick order line
val pickOrderLines = pickOrderLineRepository
.findAllByPickOrderId(pickOrder.id!!)
.filter { it.deleted == false }
// Execute SQL query and build hierarchical structure
try {
val results = jdbcDao.queryForList(sql, mapOf("userId" to userId))
if (results.isEmpty()) {
return mapOf(
"pickOrder" to null as Any?,
"pickOrderLines" to emptyList<Map<String, Any>>() as Any?
)
if (pickOrderLines.isEmpty()) {
return mapOf("pickOrder" to pickOrderInfo, "pickOrderLines" to emptyList<Map<String, Any?>>())
}
// Build hierarchical structure
val pickOrderInfo = results.firstOrNull()?.let { firstRow: Map<String, Any?> ->
mapOf(
"id" to firstRow["pickOrderId"],
"code" to firstRow["pickOrderCode"],
"consoCode" to firstRow["pickOrderConsoCode"],
"targetDate" to firstRow["pickOrderTargetDate"],
"type" to firstRow["pickOrderType"],
"status" to firstRow["pickOrderStatus"],
"assignTo" to firstRow["pickOrderAssignTo"],
"jobOrder" to mapOf(
"id" to firstRow["jobOrderId"],
"code" to firstRow["jobOrderCode"],
"name" to "Job Order ${firstRow["jobOrderCode"]}"
val pickOrderLineIds = pickOrderLines.mapNotNull { it.id }
// 5. 建议拣货 lot
val suggestedPickLots = if (pickOrderLineIds.isNotEmpty()) {
suggestPickLotRepository
.findAllByPickOrderLineIdIn(pickOrderLineIds)
.filter { it.deleted == false }
} else emptyList()
val inventoryLotLineIds = suggestedPickLots.mapNotNull { it.suggestedLotLine?.id }
val inventoryLotLines = if (inventoryLotLineIds.isNotEmpty()) {
inventoryLotLineRepository
.findAllByIdIn(inventoryLotLineIds)
.filter { it.deleted == false }
} else emptyList()
val inventoryLotIds = inventoryLotLines.mapNotNull { it.inventoryLot?.id }.distinct()
val inventoryLots = if (inventoryLotIds.isNotEmpty()) {
inventoryLotRepository
.findAllByIdIn(inventoryLotIds)
.filter { it.deleted == false }
} else emptyList()
// 6. stock_out_line(含所有状态)
val stockOutLines = if (pickOrderLineIds.isNotEmpty() && inventoryLotLineIds.isNotEmpty()) {
pickOrderLineIds.flatMap { polId ->
inventoryLotLineIds.flatMap { illId ->
stockOutLineRepository.findByPickOrderLineIdAndInventoryLotLineIdAndDeletedFalse(polId, illId)
}
}
} else emptyList()
// 7. 对应的 jo_pick_order(用于 match_* 和 handler)
val joPickOrders = joPickOrderRepository.findByPickOrderId(pickOrder.id!!)
// 8. 组装每一行 + lots
val pickOrderLinesResult = pickOrderLines.map { pol ->
val item = pol.item
val uom = pol.uom
val lineSuggestedLots = suggestedPickLots.filter { it.pickOrderLine?.id == pol.id }
val jpo = joPickOrders.firstOrNull { it.itemId == item?.id }
val handlerName = jpo?.matchBy?.let { uid ->
userService.find(uid).orElse(null)?.name
}
val lots = lineSuggestedLots.mapNotNull { spl ->
val ill = spl.suggestedLotLine ?: return@mapNotNull null
if (ill.deleted == true) return@mapNotNull null
val il = ill.inventoryLot ?: return@mapNotNull null
if (il.deleted == true) return@mapNotNull null
val warehouse = ill.warehouse
val sol = stockOutLines.firstOrNull {
it.pickOrderLine?.id == pol.id && it.inventoryLotLine?.id == ill.id
}
val availableQty = if (sol?.status == "rejected") {
null
} else {
(ill.inQty ?: BigDecimal.ZERO) -
(ill.outQty ?: BigDecimal.ZERO) -
(ill.holdQty ?: BigDecimal.ZERO)
}
val lotAvailability = when {
il.expiryDate != null && il.expiryDate!!.isBefore(LocalDate.now()) -> "expired"
sol?.status == "rejected" -> "rejected"
availableQty != null && availableQty <= BigDecimal.ZERO -> "insufficient_stock"
ill.status == InventoryLotLineStatus.UNAVAILABLE -> "status_unavailable"
else -> "available"
}
val processingStatus = when (sol?.status) {
"completed" -> "completed"
"rejected" -> "rejected"
"created" -> "pending"
else -> "pending"
}
mapOf(
"lotId" to ill.id,
"lotNo" to il.lotNo,
"expiryDate" to il.expiryDate?.let {
"${it.year}-${"%02d".format(it.monthValue)}-${"%02d".format(it.dayOfMonth)}"
},
"location" to warehouse?.name,
"availableQty" to availableQty?.toDouble(),
"requiredQty" to (spl.qty?.toDouble() ?: 0.0),
"actualPickQty" to (sol?.qty ?: 0.0),
"processingStatus" to processingStatus,
"lotAvailability" to lotAvailability,
"pickOrderId" to pickOrder.id,
"pickOrderCode" to pickOrder.code,
"pickOrderConsoCode" to pickOrder.consoCode,
"pickOrderLineId" to pol.id,
"stockOutLineId" to sol?.id,
"stockOutLineStatus" to sol?.status,
"stockOutLineQty" to (sol?.qty ?: 0.0),
"routerIndex" to warehouse?.order,
"routerArea" to warehouse?.code,
"routerRoute" to warehouse?.code,
"uomShortDesc" to uom?.udfShortDesc,
"matchStatus" to jpo?.matchStatus?.value,
"matchBy" to jpo?.matchBy,
"matchQty" to jpo?.matchQty,
"handler" to handlerName
)
)
}
// Group by pick order line
val groupedByLine = results.groupBy { row: Map<String, Any?> -> row["pickOrderLineId"] }
val pickOrderLines = groupedByLine.map { (lineId: Any?, lineRows: List<Map<String, Any?>>) ->
val firstLineRow = lineRows.first()
}
mapOf(
"id" to lineId,
"itemId" to firstLineRow["itemId"],
"itemCode" to firstLineRow["itemCode"],
"itemName" to firstLineRow["itemName"],
"requiredQty" to firstLineRow["pickOrderLineRequiredQty"],
"uomCode" to firstLineRow["uomCode"],
"uomDesc" to firstLineRow["uomDesc"],
"lots" to lineRows.map { row: Map<String, Any?> ->
mapOf(
"lotId" to row["lotId"],
"lotNo" to row["lotNo"],
"expiryDate" to row["expiryDate"],
"location" to row["location"],
"availableQty" to row["availableQty"],
"requiredQty" to row["requiredQty"],
"actualPickQty" to row["actualPickQty"],
"processingStatus" to row["processingStatus"],
"lotAvailability" to row["lotAvailability"],
"pickOrderId" to row["pickOrderId"],
"pickOrderCode" to row["pickOrderCode"],
"suggestedPickLotId" to row["suggestedPickLotId"],
"stockOutLineQty" to row["stockOutLineQty"],
"pickOrderConsoCode" to row["pickOrderConsoCode"],
"pickOrderLineId" to row["pickOrderLineId"],
"stockOutLineId" to row["stockOutLineId"],
"stockOutLineStatus" to row["stockOutLineStatus"],
"routerIndex" to row["routerIndex"],
"routerArea" to row["routerArea"],
"routerRoute" to row["routerRoute"],
"uomShortDesc" to row["uomShortDesc"],
"matchStatus" to row["match_status"],
"matchBy" to row["match_by"],
"matchQty" to row["match_qty"]
)
}
"id" to pol.id,
"itemId" to item?.id,
"itemCode" to item?.code,
"itemName" to item?.name,
"requiredQty" to pol.qty?.toDouble(),
"uomCode" to uom?.code,
"uomDesc" to uom?.udfudesc,
"handler" to handlerName,
"lots" to lots
)
}
return mapOf(
"pickOrder" to pickOrderInfo as Any?,
"pickOrderLines" to pickOrderLines as Any?
)
} catch (e: Exception) {
println("❌ Error executing completed Job Order SQL: ${e.message}")
e.printStackTrace()
return mapOf(
"pickOrder" to null as Any?,
"pickOrderLines" to emptyList<Map<String, Any>>() as Any?
"pickOrder" to pickOrderInfo,
"pickOrderLines" to pickOrderLinesResult
)
}
}

// Get completed job order pick order records (for third tab)
@@ -1310,40 +1242,35 @@ private fun generateIssueNoForJo(): String {
return "SKO-${yearMonth}-${nextSequence.toString().padStart(3, '0')}"
}
open fun getCompletedJobOrderPickOrdersWithCompletedSecondScan(userId: Long): List<Map<String, Any?>> {
open fun getCompletedJobOrderPickOrdersWithCompletedSecondScan(): List<Map<String, Any?>> {
println("=== getCompletedJobOrderPickOrdersWithCompletedSecondScan ===")
println("userId: $userId")

return try {
// Get all completed pick orders assigned to user that have joId
val completedPickOrders = pickOrderRepository.findAllByAssignToIdAndStatusIn(
userId,
listOf(PickOrderStatus.COMPLETED)
).filter { it.jobOrder != null } // Only pick orders with joId
// 1. 先找出所有 COMPLETED 的 JO pick order(不再依赖 assignTo / userId)
val completedPickOrders = pickOrderRepository
.findAllByStatusIn(listOf(PickOrderStatus.COMPLETED))
.filter { it.jobOrder != null } // 只要有 jobOrder 的

println("Found ${completedPickOrders.size} completed job order pick orders for user $userId")
println("Found ${completedPickOrders.size} completed job order pick orders (all users)")

// 2. 只保留「所有 item 的 second scan 都完成」的 pick order
val completedJobOrderPickOrders = completedPickOrders.mapNotNull { pickOrder ->
val jobOrder = pickOrder.jobOrder
if (jobOrder != null) {
// Check if all items in this pick order have completed second scan
val joPickOrders = findByPickOrderId(pickOrder.id!!)
val allSecondScanCompleted = joPickOrders.isNotEmpty() &&
joPickOrders.all { it.matchStatus == JoPickOrderStatus.completed }
val allSecondScanCompleted = joPickOrders.isNotEmpty() &&
joPickOrders.all { it.matchStatus == JoPickOrderStatus.completed }
if (allSecondScanCompleted) {
mapOf(
"id" to pickOrder.id,
"pickOrderId" to pickOrder.id,
"pickOrderCode" to pickOrder.code,
"pickOrderConsoCode" to pickOrder.consoCode,
"pickOrderTargetDate" to pickOrder.targetDate?.let {
"${it.year}-${String.format("%02d", it.monthValue)}-${String.format("%02d", it.dayOfMonth)}"
},
"pickOrderTargetDate" to pickOrder.targetDate,
"pickOrderStatus" to pickOrder.status,
"completedDate" to pickOrder.completeDate?.let {
"${it.year}-${String.format("%02d", it.monthValue)}-${String.format("%02d", it.dayOfMonth)}"
},
// ✅ 完成时间改用 jobOrder.planEnd
"completedDate" to jobOrder.planEnd,
"jobOrderId" to jobOrder.id,
"jobOrderCode" to jobOrder.code,
"jobOrderName" to jobOrder.bom?.name,
@@ -1537,30 +1464,25 @@ open fun getCompletedJobOrderPickOrderLotDetails(pickOrderId: Long): List<Map<St
}
// ... existing code ...

open fun getCompletedJobOrderPickOrders(userId: Long): List<Map<String, Any?>> {
println("=== getCompletedJobOrderPickOrders ===")
println("userId: $userId")
open fun getCompletedJobOrderPickOrders(): List<Map<String, Any?>> {
println("=== getCompletedJobOrderPickOrders (no user filter) ===")

return try {
// 修复:先查找所有 COMPLETED 状态的 job order pick orders(不限制 assignTo)
val allCompletedPickOrders = pickOrderRepository.findAllByStatusIn(
listOf(PickOrderStatus.COMPLETED)
).filter {
it.jobOrder != null && // 只查找有 job order 的
(it.assignTo?.id == userId || it.assignTo == null) // 分配给当前用户或未分配
}
println("Found ${allCompletedPickOrders.size} completed job order pick orders (including unassigned)")
// 1. 找出所有 COMPLETED 状态、且有关联 JobOrder 的 pick order(不再按 assignTo 过滤)
val allCompletedPickOrders = pickOrderRepository
.findAllByStatusIn(listOf(PickOrderStatus.COMPLETED))
.filter { it.jobOrder != null }

println("Found ${allCompletedPickOrders.size} completed job order pick orders")

// 2. 组装返回数据
val completedJobOrderPickOrders = allCompletedPickOrders.mapNotNull { pickOrder ->
val jobOrder = pickOrder.jobOrder
if (jobOrder != null) {
// Get JoPickOrder records for this pick order
// 对应的 JoPickOrder 记录(用于 second scan 状态统计)
val joPickOrders = findByPickOrderId(pickOrder.id!!)
println("Pick Order ${pickOrder.code}: joPickOrders.size=${joPickOrders.size}")

// Calculate second scan completion status
val secondScanCompleted = joPickOrders.isNotEmpty() &&
joPickOrders.all { it.matchStatus == JoPickOrderStatus.completed }

@@ -1570,12 +1492,11 @@ open fun getCompletedJobOrderPickOrders(userId: Long): List<Map<String, Any?>> {
"pickOrderCode" to pickOrder.code,
"pickOrderConsoCode" to pickOrder.consoCode,
"pickOrderTargetDate" to pickOrder.targetDate?.let {
"${it.year}-${String.format("%02d", it.monthValue)}-${String.format("%02d", it.dayOfMonth)}"
"${it.year}-${"%02d".format(it.monthValue)}-${"%02d".format(it.dayOfMonth)}"
},
"pickOrderStatus" to pickOrder.status,
"completedDate" to pickOrder.completeDate?.let {
"${it.year}-${String.format("%02d", it.monthValue)}-${String.format("%02d", it.dayOfMonth)}"
},
// 完成时间:按你的需求用 jobOrder.planEnd
"completedDate" to jobOrder.planEnd,
"jobOrderId" to jobOrder.id,
"jobOrderCode" to jobOrder.code,
"jobOrderName" to jobOrder.bom?.name,
@@ -1944,7 +1865,10 @@ open fun getJobOrderLotsHierarchicalByPickOrderId(pickOrderId: Long): JobOrderLo
val uom = pol.uom
val lineId = pol.id!!
val lineSuggestedLots = suggestedPickLots.filter { it.pickOrderLine?.id == pol.id }
val jpo = joPickOrders.firstOrNull { it.itemId == item?.id }
val handlerName = jpo?.handledBy?.let { uid ->
userService.find(uid).orElse(null)?.name
}
// 构建 lots 数据
val lots = lineSuggestedLots.mapNotNull { spl ->
val ill = spl.suggestedLotLine
@@ -1958,7 +1882,10 @@ open fun getJobOrderLotsHierarchicalByPickOrderId(pickOrderId: Long): JobOrderLo
it.pickOrderLine?.id == pol.id && it.inventoryLotLine?.id == ill.id
}
val jpo = joPickOrders.firstOrNull { it.itemId == item?.id }
val handlerName = jpo?.handledBy?.let { uid ->
userService.find(uid).orElse(null)?.name
}
println("handlerName: $handlerName")
val availableQty = if (sol?.status == "rejected") {
null
} else {
@@ -2019,7 +1946,8 @@ open fun getJobOrderLotsHierarchicalByPickOrderId(pickOrderId: Long): JobOrderLo
uomCode = uom?.code,
uomDesc = uom?.udfudesc,
status = pol.status?.value,
lots = lots
lots = lots,
handler=handlerName
)
}


+ 8
- 6
src/main/java/com/ffii/fpsms/modules/jobOrder/web/JobOrderController.kt Переглянути файл

@@ -180,10 +180,12 @@ fun recordSecondScanIssue(
)
return joPickOrderService.recordSecondScanIssue(request)
}
@GetMapping("/completed-job-order-pick-orders-with-completed-second-scan/{userId}")
fun getCompletedJobOrderPickOrdersWithCompletedSecondScan(@PathVariable userId: Long): List<Map<String, Any?>> {
return joPickOrderService.getCompletedJobOrderPickOrdersWithCompletedSecondScan(userId)
/*
@GetMapping("/completed-job-order-pick-orders-with-completed-second-scan")
fun getCompletedJobOrderPickOrdersWithCompletedSecondScan(): List<Map<String, Any?>> {
return joPickOrderService.getCompletedJobOrderPickOrdersWithCompletedSecondScan()
}
*/
@GetMapping("/completed-job-order-pick-order-lot-details/{pickOrderId}")
fun getCompletedJobOrderPickOrderLotDetails(@PathVariable pickOrderId: Long): List<Map<String, Any?>> {
return joPickOrderService.getCompletedJobOrderPickOrderLotDetails(pickOrderId)
@@ -224,9 +226,9 @@ fun recordSecondScanIssue(
}


@GetMapping("/completed-job-order-pick-orders-only/{userId}")
fun getCompletedJobOrderPickOrders(@PathVariable userId: Long): List<Map<String, Any?>> {
return joPickOrderService.getCompletedJobOrderPickOrders(userId)
@GetMapping("/completed-job-order-pick-orders-only")
fun getCompletedJobOrderPickOrders(): List<Map<String, Any?>> {
return joPickOrderService.getCompletedJobOrderPickOrders()
}

@GetMapping("/completed-job-order-pick-order-lot-details-completed-pick/{pickOrderId}")


+ 2
- 1
src/main/java/com/ffii/fpsms/modules/jobOrder/web/model/CreateJobOrderRequest.kt Переглянути файл

@@ -89,7 +89,8 @@ data class PickOrderLineWithLotsResponse(
val uomCode: String?,
val uomDesc: String?,
val status: String?,
val lots: List<LotDetailResponse>
val lots: List<LotDetailResponse>,
val handler: String?
)

data class LotDetailResponse(


+ 1
- 1
src/main/java/com/ffii/fpsms/modules/productProcess/service/ProductProcessService.kt Переглянути файл

@@ -1121,7 +1121,7 @@ open class ProductProcessService(
// 过滤掉已完成上架的 job order
val jobOrder = jobOrderRepository.findById(response.jobOrderId ?: 0L).orElse(null)
val stockInLineStatus = jobOrder?.stockInLines?.firstOrNull()?.status
stockInLineStatus != "completed"
stockInLineStatus != "completed" && jobOrder?.status != JobOrderStatus.PLANNING
}
}



Завантаження…
Відмінити
Зберегти