kelvin.yau 1 day ago
parent
commit
6739ec7eb6
9 changed files with 134 additions and 63 deletions
  1. +100
    -55
      src/main/java/com/ffii/fpsms/modules/jobOrder/service/JoPickOrderService.kt
  2. +9
    -4
      src/main/java/com/ffii/fpsms/modules/jobOrder/service/JobOrderService.kt
  3. +6
    -1
      src/main/java/com/ffii/fpsms/modules/jobOrder/web/JobOrderController.kt
  4. +0
    -2
      src/main/java/com/ffii/fpsms/modules/master/entity/Bom.kt
  5. +1
    -0
      src/main/java/com/ffii/fpsms/modules/master/entity/projections/BomCombo.kt
  6. +1
    -0
      src/main/java/com/ffii/fpsms/modules/pickOrder/entity/PickOrderRepository.kt
  7. +2
    -0
      src/main/java/com/ffii/fpsms/modules/productProcess/entity/projections/ProductProcessInfo.kt
  8. +13
    -1
      src/main/java/com/ffii/fpsms/modules/productProcess/service/ProductProcessService.kt
  9. +2
    -0
      src/main/java/com/ffii/fpsms/modules/productProcess/web/model/SaveProductProcessRequest.kt

+ 100
- 55
src/main/java/com/ffii/fpsms/modules/jobOrder/service/JoPickOrderService.kt View File

@@ -77,7 +77,7 @@ open class JoPickOrderService(
}
// Update JoPickOrder status to released
open fun updateHandledByForPickOrder(pickOrderId: Long, userId: Long): List<JoPickOrder> {
open fun updateHandledByForPickOrder(pickOrderId: Long, userId: Long?): List<JoPickOrder> {
val joPickOrders = joPickOrderRepository.findByPickOrderId(pickOrderId)
// Get pick order details to populate new fields
@@ -111,7 +111,7 @@ open class JoPickOrderService(
}
// Update JoPickOrderRecord status to released
open fun updateRecordHandledByForPickOrder(pickOrderId: Long, userId: Long): List<JoPickOrderRecord> {
open fun updateRecordHandledByForPickOrder(pickOrderId: Long, userId: Long?): List<JoPickOrderRecord> {
val joPickOrderRecords = joPickOrderRecordRepository.findByPickOrderId(pickOrderId)
// Get pick order details to populate new fields
@@ -957,6 +957,47 @@ open fun assignJobOrderPickOrderToUser(pickOrderId: Long, userId: Long): Message
)
}
}
open fun unAssignJobOrderPickOrderToUser(pickOrderId: Long): MessageResponse {
println("=== unAssignJobOrderPickOrderToUser ===")
println("pickOrderId: $pickOrderId")
return try {
val pickOrder = pickOrderRepository.findById(pickOrderId).orElse(null)
if (pickOrder == null) {
return MessageResponse(
id = null,
code = null,
name = null,
type = null,
message = "Pick order not found",
errorPosition = null
)
}
pickOrder.assignTo = null
pickOrderRepository.save(pickOrder)
this.updateHandledByForPickOrder(pickOrderId, null)
this.updateRecordHandledByForPickOrder(pickOrderId, null)
MessageResponse(
id = pickOrder.id,
code = pickOrder.code,
name = pickOrder.jobOrder?.bom?.name,
type = null,
message = "Successfully unassigned",
errorPosition = null
)
} catch (e: Exception) {
println("❌ Error in unAssignJobOrderPickOrderToUser: ${e.message}")
e.printStackTrace()
MessageResponse(
id = null,
code = null,
name = null,
type = null,
message = "Error occurred: ${e.message}",
errorPosition = null
)
}
}
// Fix the updateMatchStatus method
open fun updateMatchStatus(pickOrderId: Long, itemId: Long, userId: Long, qty: Int): MessageResponse {
try {
@@ -1494,66 +1535,70 @@ open fun getCompletedJobOrderPickOrderLotDetails(pickOrderId: Long): List<Map<St
}
// ... existing code ...

open fun getCompletedJobOrderPickOrders(userId: Long): List<Map<String, Any?>> {
println("=== getCompletedJobOrderPickOrders ===")
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
open fun getCompletedJobOrderPickOrders(userId: Long): List<Map<String, Any?>> {
println("=== getCompletedJobOrderPickOrders ===")
println("userId: $userId")

println("Found ${completedPickOrders.size} completed job order pick orders for user $userId")
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)")

val completedJobOrderPickOrders = completedPickOrders.mapNotNull { pickOrder ->
val jobOrder = pickOrder.jobOrder
if (jobOrder != null) {
// Get JoPickOrder records for this pick order
val joPickOrders = findByPickOrderId(pickOrder.id!!)
val completedJobOrderPickOrders = allCompletedPickOrders.mapNotNull { pickOrder ->
val jobOrder = pickOrder.jobOrder
if (jobOrder != null) {
// Get JoPickOrder records for this pick order
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 }
// Calculate second scan completion status
val secondScanCompleted = joPickOrders.isNotEmpty() &&
joPickOrders.all { it.matchStatus == JoPickOrderStatus.completed }

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)}"
},
"pickOrderStatus" to pickOrder.status,
"completedDate" to pickOrder.completeDate?.let {
"${it.year}-${String.format("%02d", it.monthValue)}-${String.format("%02d", it.dayOfMonth)}"
},
"jobOrderId" to jobOrder.id,
"jobOrderCode" to jobOrder.code,
"jobOrderName" to jobOrder.bom?.name,
"reqQty" to jobOrder.reqQty,
"uom" to jobOrder.bom?.uom?.code,
"planStart" to jobOrder.planStart,
"planEnd" to jobOrder.planEnd,
"secondScanCompleted" to secondScanCompleted,
"totalItems" to joPickOrders.size,
"completedItems" to joPickOrders.count { it.matchStatus == JoPickOrderStatus.completed }
)
} else {
println("❌ Pick order ${pickOrder.id} has no job order, skipping.")
null
}
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)}"
},
"pickOrderStatus" to pickOrder.status,
"completedDate" to pickOrder.completeDate?.let {
"${it.year}-${String.format("%02d", it.monthValue)}-${String.format("%02d", it.dayOfMonth)}"
},
"jobOrderId" to jobOrder.id,
"jobOrderCode" to jobOrder.code,
"jobOrderName" to jobOrder.bom?.name,
"reqQty" to jobOrder.reqQty,
"uom" to jobOrder.bom?.uom?.code,
"planStart" to jobOrder.planStart,
"planEnd" to jobOrder.planEnd,
"secondScanCompleted" to secondScanCompleted,
"totalItems" to joPickOrders.size,
"completedItems" to joPickOrders.count { it.matchStatus == JoPickOrderStatus.completed }
)
} else {
println("❌ Pick order ${pickOrder.id} has no job order, skipping.")
null
}

println("Returning ${completedJobOrderPickOrders.size} completed job order pick orders")
completedJobOrderPickOrders
} catch (e: Exception) {
println("❌ Error in getCompletedJobOrderPickOrders: ${e.message}")
e.printStackTrace()
emptyList()
}

println("Returning ${completedJobOrderPickOrders.size} completed job order pick orders")
completedJobOrderPickOrders
} catch (e: Exception) {
println("❌ Error in getCompletedJobOrderPickOrders: ${e.message}")
e.printStackTrace()
emptyList()
}
}

// ... rest of the code ...



+ 9
- 4
src/main/java/com/ffii/fpsms/modules/jobOrder/service/JobOrderService.kt View File

@@ -182,10 +182,15 @@ open class JobOrderService(
}
.filter { info ->
// Filter by jobTypeName if provided
request.jobTypeName == null ||
request.jobTypeName.isBlank() ||
info.jobTypeName?.equals(request.jobTypeName, ignoreCase = true) == true ||
info.jobTypeName?.contains(request.jobTypeName, ignoreCase = true) == true
val jobTypeNameMatch = request.jobTypeName == null ||
request.jobTypeName.isBlank() ||
info.jobTypeName?.equals(request.jobTypeName, ignoreCase = true) == true ||
info.jobTypeName?.contains(request.jobTypeName, ignoreCase = true) == true
val notCompletedPutaway = info.stockInLineStatus != "completed"
jobTypeNameMatch && notCompletedPutaway
}

// 修复:使用 response.totalElements,这是过滤后的总数


+ 6
- 1
src/main/java/com/ffii/fpsms/modules/jobOrder/web/JobOrderController.kt View File

@@ -127,7 +127,12 @@ class JobOrderController(
): MessageResponse {
return joPickOrderService.assignJobOrderPickOrderToUser(pickOrderId, userId)
}

@PostMapping("/unassign-job-order-pick-order/{pickOrderId}")
fun unAssignJobOrderPickOrderToUser(
@PathVariable pickOrderId: Long
): MessageResponse {
return joPickOrderService.unAssignJobOrderPickOrderToUser(pickOrderId)
}
@PostMapping("/update-match-status")
fun updateMatchStatus(@RequestBody request: UpdateMatchStatusRequest): MessageResponse {
return joPickOrderService.updateMatchStatus(


+ 0
- 2
src/main/java/com/ffii/fpsms/modules/master/entity/Bom.kt View File

@@ -28,10 +28,8 @@ open class Bom : BaseEntity<Long>() {

@Column
open var timeSequence: Int? = null

@Column
open var complexity: Int? = null

@JsonBackReference
@OneToOne
@JoinColumn(name = "itemId")


+ 1
- 0
src/main/java/com/ffii/fpsms/modules/master/entity/projections/BomCombo.kt View File

@@ -10,4 +10,5 @@ interface BomCombo {
@get:Value("#{target.code} - #{target.name} - #{target.item.itemUoms.^[salesUnit == true && deleted == false]?.uom.udfudesc}")
val label: String;
val outputQty: BigDecimal;
val outputQtyUom: String?;
}

+ 1
- 0
src/main/java/com/ffii/fpsms/modules/pickOrder/entity/PickOrderRepository.kt View File

@@ -81,4 +81,5 @@ fun findAllByStatusAndAssignToIsNullAndDeletedFalse(status: PickOrderStatus): Li
//fun findAllByJoid(jobOrderId: Long): List<PickOrder>
fun findAllByJobOrder_Id(jobOrderId: Long): List<PickOrder>
fun findTopByJobOrder_IdOrderByCreatedDesc(jobOrderId: Long): PickOrder?
fun findAllByStatusIn(statuses: List<PickOrderStatus>): List<PickOrder>
}

+ 2
- 0
src/main/java/com/ffii/fpsms/modules/productProcess/entity/projections/ProductProcessInfo.kt View File

@@ -33,6 +33,8 @@ data class ProductProcessInfo(
val itemName: String?,
val outputQtyUom: String?,
val outputQty: Int?,
val timeSequence: Int?,
val complexity: Int?,
val productionPriority: Int?,
val productProcessLines: List<ProductProcessLineInfo>?,
val totalStockQty: Int?,


+ 13
- 1
src/main/java/com/ffii/fpsms/modules/productProcess/service/ProductProcessService.kt View File

@@ -42,7 +42,7 @@ import com.ffii.fpsms.modules.master.entity.BomProcessMaterialRepository
import com.ffii.fpsms.modules.master.entity.BomMaterialRepository
import com.ffii.fpsms.modules.productProcess.entity.ProductionProcessIssue
import com.ffii.fpsms.modules.jobOrder.entity.JobTypeRepository
import com.ffii.fpsms.modules.pickOrder.entity.PickOrderRepository
import java.time.ZoneOffset
@Service
@Transactional
@@ -65,6 +65,7 @@ open class ProductProcessService(
private val bomMaterialRepository: BomMaterialRepository,
private val equipmentDetailRepository: EquipmentDetailRepository,
private val jobTypeRepository: JobTypeRepository,
private val pickOrderRepository: PickOrderRepository,
) {
open fun findAll(pageable: Pageable): Page<ProductProcess> {
@@ -589,6 +590,8 @@ open class ProductProcessService(
itemId = bom?.item?.id?:0,
itemCode = bom?.item?.code?:"",
itemName = bom?.item?.name?:"",
timeSequence = bom?.timeSequence?:0,
complexity = bom?.complexity?:0,
isDark = calculateColourScore(bom?.isDark?:0),
isDense = bom?.isDense?:0,
isFloat = calculateFloatScore(bom?.isFloat?:0),
@@ -1094,6 +1097,8 @@ open class ProductProcessService(
val FinishedProductProcessLineCount = productProcessLineRepository.findByProductProcess_Id(productProcesses.id?:0L).count { it.status == "Completed" }
val stockInLine = jobOrder?.stockInLines?.firstOrNull()
val stockInLineId = stockInLine?.id
val pickOrder = pickOrderRepository.findAllByJobOrder_Id(jobOrder?.id?:0L).firstOrNull()

//val silHandlerId = stockInLine?.escalationLog?.firstOrNull { it.status == "pending" }?.handler?.id

AllJoborderProductProcessInfoResponse(
@@ -1105,7 +1110,9 @@ open class ProductProcessService(
RequiredQty = jobOrder?.reqQty?.toInt() ?: 0,
date = productProcesses.date,
bomId = productProcesses.bom?.id,
assignedTo = pickOrder?.assignTo?.id,
itemName = productProcesses.item?.name,
pickOrderId = pickOrder?.id,
jobOrderId = productProcesses.jobOrder?.id,
stockInLineId = stockInLineId,
jobOrderCode = jobOrder?.code,
@@ -1125,6 +1132,11 @@ open class ProductProcessService(
)
}
)
}.filter { response ->
// 过滤掉已完成上架的 job order
val jobOrder = jobOrderRepository.findById(response.jobOrderId ?: 0L).orElse(null)
val stockInLineStatus = jobOrder?.stockInLines?.firstOrNull()?.status
stockInLineStatus != "completed"
}
}



+ 2
- 0
src/main/java/com/ffii/fpsms/modules/productProcess/web/model/SaveProductProcessRequest.kt View File

@@ -166,6 +166,8 @@ data class AllJoborderProductProcessInfoResponse(
val RequiredQty: Int?,
val jobOrderId: Long?,
val jobOrderCode: String?,
val assignedTo: Long?,
val pickOrderId: Long?,
val productProcessLineCount: Int,
val FinishedProductProcessLineCount: Int,
val stockInLineId: Long?,


Loading…
Cancel
Save