| @@ -574,6 +574,7 @@ open class ProductProcessService( | |||||
| jobOrderCode = jobOrder?.code?:"", | jobOrderCode = jobOrder?.code?:"", | ||||
| jobOrderStatus = jobOrder?.status?.value?:"", | jobOrderStatus = jobOrder?.status?.value?:"", | ||||
| jobType = jobType?.name?:"", | jobType = jobType?.name?:"", | ||||
| bomDescription = bom?.description?:"", | |||||
| itemId = bom?.item?.id?:0, | itemId = bom?.item?.id?:0, | ||||
| itemCode = bom?.item?.code?:"", | itemCode = bom?.item?.code?:"", | ||||
| itemName = bom?.item?.name?:"", | itemName = bom?.item?.name?:"", | ||||
| @@ -650,8 +651,8 @@ open class ProductProcessService( | |||||
| // 使用 bom_material.uom_name 而不是关联的 uom 对象 | // 使用 bom_material.uom_name 而不是关联的 uom 对象 | ||||
| val uom = uomConversionRepository.findByCodeAndDeletedFalse(bomMaterial?.uomName?:"") | val uom = uomConversionRepository.findByCodeAndDeletedFalse(bomMaterial?.uomName?:"") | ||||
| val uomName = uom?.udfShortDesc | |||||
| val shortUom = uom?.udfShortDesc | |||||
| val uomName = uom?.udfudesc | |||||
| val shortUom = uom?.udfudesc | |||||
| // 然后遍历 bomProcessIds 找到第一个匹配的 BomProcessMaterial | // 然后遍历 bomProcessIds 找到第一个匹配的 BomProcessMaterial | ||||
| val bomProcessMaterial = bomMaterial?.id?.let { bomMaterialId -> | val bomProcessMaterial = bomMaterial?.id?.let { bomMaterialId -> | ||||
| bomProcessIds.firstNotNullOfOrNull { bomProcessId -> | bomProcessIds.firstNotNullOfOrNull { bomProcessId -> | ||||
| @@ -684,7 +685,7 @@ open class ProductProcessService( | |||||
| } | } | ||||
| } | } | ||||
| open fun createProductProcessByJobOrderId(jobOrderId: Long): MessageResponse { | |||||
| open fun createProductProcessByJobOrderId(jobOrderId: Long, productionPriority: Int?=50): MessageResponse { | |||||
| val jobOrder = jobOrderRepository.findById(jobOrderId).orElse(null) | val jobOrder = jobOrderRepository.findById(jobOrderId).orElse(null) | ||||
| val bom = bomRepository.findById(jobOrder?.bom?.id ?: 0L).orElse(null) | val bom = bomRepository.findById(jobOrder?.bom?.id ?: 0L).orElse(null) | ||||
| // val bom = jobOrder.bom.let { bomRepository.findById(it).orElse(null) } | // val bom = jobOrder.bom.let { bomRepository.findById(it).orElse(null) } | ||||
| @@ -701,7 +702,7 @@ open class ProductProcessService( | |||||
| this.status = ProductProcessStatus.PENDING | this.status = ProductProcessStatus.PENDING | ||||
| this.date = jobOrder?.planEnd?.toLocalDate() | this.date = jobOrder?.planEnd?.toLocalDate() | ||||
| this.bom = bom | this.bom = bom | ||||
| this.productionPriority = 50 | |||||
| this.productionPriority = productionPriority | |||||
| } | } | ||||
| productProcessRepository.save(productProcess) | productProcessRepository.save(productProcess) | ||||
| @@ -919,7 +920,14 @@ open class ProductProcessService( | |||||
| } | } | ||||
| open fun getJobOrderProcessLineDetail(productProcessLineId: Long): JobOrderProcessLineDetailResponse { | open fun getJobOrderProcessLineDetail(productProcessLineId: Long): JobOrderProcessLineDetailResponse { | ||||
| val productProcessLine = productProcessLineRepository.findById(productProcessLineId).orElse(null) | val productProcessLine = productProcessLineRepository.findById(productProcessLineId).orElse(null) | ||||
| val bomProcess = bomProcessRepository.findById(productProcessLine?.bomProcess?.id?:0L).orElse(null) | |||||
| val bomProcessId = productProcessLine?.bomProcess?.id | |||||
| println("bomProcessId ${bomProcessId}") | |||||
| val bomProcess: BomProcess? = bomProcessId?.let { | |||||
| bomProcessRepository.findAll().firstOrNull { it.id == bomProcessId } | |||||
| } | |||||
| println("bomProcess ${bomProcess?.id}") | |||||
| println("bomProcess durationInMinute ${bomProcess?.durationInMinute}") | |||||
| val productProcessIssue = productionProcessIssueRepository.findByProductProcessLineId(productProcessLineId).filter{it.status == "Paused"}.firstOrNull() | val productProcessIssue = productionProcessIssueRepository.findByProductProcessLineId(productProcessLineId).filter{it.status == "Paused"}.firstOrNull() | ||||
| // ✅ 计算所有已恢复的暂停记录的总暂停时间(毫秒) | // ✅ 计算所有已恢复的暂停记录的总暂停时间(毫秒) | ||||
| @@ -939,7 +947,7 @@ open class ProductProcessService( | |||||
| operatorId = productProcessLine.operator?.id?:0, | operatorId = productProcessLine.operator?.id?:0, | ||||
| operatorName = productProcessLine.operator?.name?:"", | operatorName = productProcessLine.operator?.name?:"", | ||||
| handlerId = productProcessLine.handler?.id?:0, | handlerId = productProcessLine.handler?.id?:0, | ||||
| durationInMinutes = bomProcess?.durationInMinute?:0, | |||||
| durationInMinutes = bomProcess?.durationInMinute, | |||||
| productProcessIssueId = productProcessIssue?.id?:0, | productProcessIssueId = productProcessIssue?.id?:0, | ||||
| productProcessIssueStatus = productProcessIssue?.status?:"", | productProcessIssueStatus = productProcessIssue?.status?:"", | ||||
| @@ -974,6 +982,7 @@ open class ProductProcessService( | |||||
| byproductUom = productProcessLine.byproductUom?:"" | byproductUom = productProcessLine.byproductUom?:"" | ||||
| ) | ) | ||||
| } | } | ||||
| open fun updateProductProcessLineStatus(productProcessLineId: Long, status: String): MessageResponse { | open fun updateProductProcessLineStatus(productProcessLineId: Long, status: String): MessageResponse { | ||||
| println("📋 Service: Updating ProductProcessLine Status: $productProcessLineId") | println("📋 Service: Updating ProductProcessLine Status: $productProcessLineId") | ||||
| val productProcessLine = productProcessLineRepository.findById(productProcessLineId).orElse(null) | val productProcessLine = productProcessLineRepository.findById(productProcessLineId).orElse(null) | ||||
| @@ -994,15 +1003,53 @@ open class ProductProcessService( | |||||
| errorPosition = null, | errorPosition = null, | ||||
| ) | ) | ||||
| } | } | ||||
| open fun passProductProcessLine(productProcessLineId: Long): MessageResponse { | |||||
| val productProcessLine = productProcessLineRepository.findById(productProcessLineId).orElse(null) | |||||
| val productProcess = productProcessRepository.findById(productProcessLine?.productProcess?.id?:0L).orElse(null) | |||||
| // 如果 startTime 为空,才设置它(保留已存在的 startTime) | |||||
| println("📋 Service: ProductProcessLine StartTime: ${productProcessLine.startTime}") | |||||
| println("📋 Service: ProductProcess StartTime: ${productProcess.startTime}") | |||||
| if (productProcessLine.startTime == null) { | |||||
| productProcessLine.startTime = LocalDateTime.now() | |||||
| productProcessLineRepository.save(productProcessLine) | |||||
| } | |||||
| if (productProcess.startTime == null) { | |||||
| productProcess.startTime = LocalDateTime.now() | |||||
| productProcessRepository.save(productProcess) | |||||
| } | |||||
| // 总是设置 endTime(因为 Pass 意味着完成) | |||||
| productProcessLine.endTime = LocalDateTime.now() | |||||
| productProcessLineRepository.save(productProcessLine) | |||||
| println("📋 Service: ProductProcessLine EndTime: ${productProcessLine.endTime}") | |||||
| // 更新状态为 "Pass" | |||||
| updateProductProcessLineStatus(productProcessLineId, "Pass") | |||||
| // 检查是否所有 lines 都完成(Completed 或 Pass) | |||||
| // 注意:这里应该传入 productProcessId,而不是 productProcessLineId | |||||
| val productProcessId = productProcessLine?.productProcess?.id ?: 0L | |||||
| ifAllLinesCompletedOrPassed(productProcessId) | |||||
| return MessageResponse( | |||||
| id = productProcessLineId, | |||||
| code = "200", | |||||
| name = "ProductProcessLine Passed", | |||||
| type = "success", | |||||
| message = "ProductProcessLine Passed", | |||||
| errorPosition = null, | |||||
| ) | |||||
| } | |||||
| open fun CompleteProductProcessStatusIfAllLinesCompleted(productProcessId: Long): MessageResponse { | open fun CompleteProductProcessStatusIfAllLinesCompleted(productProcessId: Long): MessageResponse { | ||||
| val productProcess = productProcessRepository.findById(productProcessId).orElse(null) | val productProcess = productProcessRepository.findById(productProcessId).orElse(null) | ||||
| println("📋 Service: ProductProcess: $productProcess") | println("📋 Service: ProductProcess: $productProcess") | ||||
| val productProcessLines = productProcessLineRepository.findByProductProcess_Id(productProcessId) | val productProcessLines = productProcessLineRepository.findByProductProcess_Id(productProcessId) | ||||
| println("📋 Service: ProductProcessLines: $productProcessLines") | println("📋 Service: ProductProcessLines: $productProcessLines") | ||||
| if(productProcessLines.all { it.status == "Completed" }) { | |||||
| if(productProcessLines.all { it.status == "Completed" || it.status == "Pass" }) { | |||||
| productProcess.status = ProductProcessStatus.COMPLETED | productProcess.status = ProductProcessStatus.COMPLETED | ||||
| if (productProcess.endTime == null) { | |||||
| productProcess.endTime = LocalDateTime.now() | |||||
| } | |||||
| productProcessRepository.save(productProcess) | productProcessRepository.save(productProcess) | ||||
| println("📋 Service: ProductProcess Status Updated: ${productProcess.status}") | println("📋 Service: ProductProcess Status Updated: ${productProcess.status}") | ||||
| } | } | ||||
| @@ -1115,7 +1162,9 @@ open class ProductProcessService( | |||||
| val itemUom = itemUomRepository.findByItemIdAndStockUnitIsTrueAndDeletedIsFalse(productProcesses.item?.id?:0L) | val itemUom = itemUomRepository.findByItemIdAndStockUnitIsTrueAndDeletedIsFalse(productProcesses.item?.id?:0L) | ||||
| val bomUom = uomConversionRepository.findById(itemUom?.uom?.id?:0L).orElse(null) | val bomUom = uomConversionRepository.findById(itemUom?.uom?.id?:0L).orElse(null) | ||||
| //val silHandlerId = stockInLine?.escalationLog?.firstOrNull { it.status == "pending" }?.handler?.id | //val silHandlerId = stockInLine?.escalationLog?.firstOrNull { it.status == "pending" }?.handler?.id | ||||
| val timeNeedToComplete = bomProcessRepository.findByBomId(productProcesses.bom?.id ?: 0L) | |||||
| .filter { !it.deleted } | |||||
| .sumOf { it.durationInMinute ?: 0 } | |||||
| AllJoborderProductProcessInfoResponse( | AllJoborderProductProcessInfoResponse( | ||||
| id = productProcesses.id ?: 0L, | id = productProcesses.id ?: 0L, | ||||
| productProcessCode = productProcesses.productProcessCode, | productProcessCode = productProcesses.productProcessCode, | ||||
| @@ -1131,9 +1180,11 @@ open class ProductProcessService( | |||||
| "pending" | "pending" | ||||
| }, | }, | ||||
| RequiredQty = jobOrder?.reqQty?.toInt() ?: 0, | RequiredQty = jobOrder?.reqQty?.toInt() ?: 0, | ||||
| Uom = bomUom?.udfShortDesc, | |||||
| Uom = bomUom?.udfudesc, | |||||
| productionPriority = productProcesses.productionPriority, | |||||
| date = productProcesses.date, | date = productProcesses.date, | ||||
| bomId = productProcesses.bom?.id, | bomId = productProcesses.bom?.id, | ||||
| TimeNeedToComplete = timeNeedToComplete, | |||||
| assignedTo = pickOrder?.assignTo?.id, | assignedTo = pickOrder?.assignTo?.id, | ||||
| itemName = productProcesses.item?.name, | itemName = productProcesses.item?.name, | ||||
| itemCode = productProcesses.item?.code, | itemCode = productProcesses.item?.code, | ||||
| @@ -1270,7 +1321,7 @@ open class ProductProcessService( | |||||
| val productProcess = productProcessRepository.findById(productProcessId).orElse(null) | val productProcess = productProcessRepository.findById(productProcessId).orElse(null) | ||||
| val jobOrder = jobOrderRepository.findById(productProcess?.jobOrder?.id?:0L).orElse(null) | val jobOrder = jobOrderRepository.findById(productProcess?.jobOrder?.id?:0L).orElse(null) | ||||
| if(jobOrder != null) { | if(jobOrder != null) { | ||||
| jobOrder.status = JobOrderStatus.STORING | |||||
| jobOrder.status = JobOrderStatus.PENDING_QC | |||||
| jobOrderRepository.save(jobOrder) | jobOrderRepository.save(jobOrder) | ||||
| stockInLineService.create( | stockInLineService.create( | ||||
| SaveStockInLineRequest( | SaveStockInLineRequest( | ||||
| @@ -1295,6 +1346,47 @@ open class ProductProcessService( | |||||
| errorPosition = null, | errorPosition = null, | ||||
| ) | ) | ||||
| } | } | ||||
| open fun ifAllLinesCompletedOrPassed(productProcessId: Long): MessageResponse { | |||||
| // 获取所有 product process lines | |||||
| val allproductProcessLines = productProcessLineRepository.findByProductProcess_Id(productProcessId) | |||||
| // 检查是否所有 lines 都是 "Completed" 或 "Pass" | |||||
| if(allproductProcessLines.all { it.status == "Completed" || it.status == "Pass" }) { | |||||
| // 更新 product process 的 endTime 和状态 | |||||
| updateProductProcessEndTime(productProcessId) | |||||
| updateProductProcessStatus(productProcessId, ProductProcessStatus.COMPLETED) | |||||
| val productProcess = productProcessRepository.findById(productProcessId).orElse(null) | |||||
| val jobOrder = jobOrderRepository.findById(productProcess?.jobOrder?.id ?: 0L).orElse(null) | |||||
| if(jobOrder != null) { | |||||
| jobOrder.status = JobOrderStatus.STORING | |||||
| jobOrderRepository.save(jobOrder) | |||||
| stockInLineService.create( | |||||
| SaveStockInLineRequest( | |||||
| itemId = productProcess?.item?.id ?: 0L, | |||||
| acceptedQty = jobOrder?.reqQty ?: BigDecimal.ZERO, | |||||
| productLotNo = jobOrder?.code, | |||||
| productionDate = LocalDate.now(), | |||||
| jobOrderId = jobOrder.id, | |||||
| acceptQty = jobOrder?.reqQty ?: BigDecimal.ZERO, | |||||
| expiryDate = null, | |||||
| status = "", | |||||
| ) | |||||
| ) | |||||
| } | |||||
| } | |||||
| return MessageResponse( | |||||
| id = productProcessId, | |||||
| code = "200", | |||||
| name = "ProductProcess Check Completed", | |||||
| type = "success", | |||||
| message = "ProductProcess Check Completed", | |||||
| errorPosition = null, | |||||
| ) | |||||
| } | |||||
| open fun SaveProductProcessIssueTime(request: SaveProductProcessIssueTimeRequest): MessageResponse { | open fun SaveProductProcessIssueTime(request: SaveProductProcessIssueTimeRequest): MessageResponse { | ||||
| println("📋 Service: Saving ProductProcess Issue Time: ${request.productProcessLineId}") | println("📋 Service: Saving ProductProcess Issue Time: ${request.productProcessLineId}") | ||||