| @@ -517,8 +517,10 @@ open class ProductProcessService( | |||||
| line.handler = user | line.handler = user | ||||
| line.startTime = LocalDateTime.now() | line.startTime = LocalDateTime.now() | ||||
| line.status = "InProgress" | |||||
| val saved = productProcessLineRepository.save(line) | val saved = productProcessLineRepository.save(line) | ||||
| syncProductProcessStatusFromLines(saved.productProcess.id) | |||||
| println(" Service: Line started, handlerId: ${saved.handler?.id}") | println(" Service: Line started, handlerId: ${saved.handler?.id}") | ||||
| return saved | return saved | ||||
| } | } | ||||
| @@ -1163,6 +1165,7 @@ open class ProductProcessService( | |||||
| } | } | ||||
| productProcessLine.startTime = LocalDateTime.now() | productProcessLine.startTime = LocalDateTime.now() | ||||
| productProcessLineRepository.save(productProcessLine) | productProcessLineRepository.save(productProcessLine) | ||||
| syncProductProcessStatusFromLines(productProcessLine.productProcess?.id ?: 0L) | |||||
| return MessageResponse( | return MessageResponse( | ||||
| id = null, | id = null, | ||||
| code = null, | code = null, | ||||
| @@ -1249,8 +1252,7 @@ open class ProductProcessService( | |||||
| // productProcessLine.endTime = LocalDateTime.now() | // productProcessLine.endTime = LocalDateTime.now() | ||||
| productProcessLineRepository.save(productProcessLine) | productProcessLineRepository.save(productProcessLine) | ||||
| println(" Service: ProductProcessLine Status Updated: ${productProcessLine.status}") | println(" Service: ProductProcessLine Status Updated: ${productProcessLine.status}") | ||||
| CompleteProductProcessStatusIfAllLinesCompleted(productProcessLine.productProcess?.id ?: 0) | |||||
| syncProductProcessStatusFromLines(productProcessLine.productProcess?.id ?: 0L) | |||||
| return MessageResponse( | return MessageResponse( | ||||
| id = productProcessLineId, | id = productProcessLineId, | ||||
| @@ -1285,10 +1287,8 @@ open class ProductProcessService( | |||||
| // 更新状态为 "Pass" | // 更新状态为 "Pass" | ||||
| updateProductProcessLineStatus(productProcessLineId, "Pass") | updateProductProcessLineStatus(productProcessLineId, "Pass") | ||||
| // 检查是否所有 lines 都完成(Completed 或 Pass) | |||||
| // 注意:这里应该传入 productProcessId,而不是 productProcessLineId | |||||
| val productProcessId = productProcessLine?.productProcess?.id ?: 0L | val productProcessId = productProcessLine?.productProcess?.id ?: 0L | ||||
| ifAllLinesCompletedOrPassed(productProcessId) | |||||
| syncProductProcessStatusFromLines(productProcessId) | |||||
| return MessageResponse( | return MessageResponse( | ||||
| id = productProcessLineId, | id = productProcessLineId, | ||||
| @@ -1940,24 +1940,68 @@ open class ProductProcessService( | |||||
| ) | ) | ||||
| } | } | ||||
| private fun normalizeLineStatus(status: String?): String = | |||||
| status?.trim()?.lowercase()?.replace(" ", "") ?: "" | |||||
| private fun isLineDone(status: String?): Boolean { | |||||
| val n = normalizeLineStatus(status) | |||||
| return n == "completed" || n == "pass" | |||||
| } | |||||
| private fun isLineActive(status: String?): Boolean { | |||||
| val n = normalizeLineStatus(status) | |||||
| return n == "inprogress" || n == "paused" | |||||
| } | |||||
| /** | |||||
| * Align parent [ProductProcess.status] with all line states. | |||||
| * - All Completed/Pass -> completed (via [ifAllLinesCompletedOrPassed]) | |||||
| * - Any line started but not all done -> in_progress | |||||
| * - Does not override STOPPED or CANCELLED on the parent. | |||||
| */ | |||||
| open fun syncProductProcessStatusFromLines(productProcessId: Long) { | |||||
| if (productProcessId <= 0L) return | |||||
| val productProcess = productProcessRepository.findById(productProcessId).orElse(null) ?: return | |||||
| if (productProcess.status == ProductProcessStatus.STOPPED || | |||||
| productProcess.status == ProductProcessStatus.CANCELLED | |||||
| ) { | |||||
| return | |||||
| } | |||||
| val lines = productProcessLineRepository.findByProductProcess_Id(productProcessId) | |||||
| if (lines.isEmpty()) return | |||||
| if (lines.all { isLineDone(it.status) }) { | |||||
| ifAllLinesCompletedOrPassed(productProcessId) | |||||
| return | |||||
| } | |||||
| val anyStarted = lines.any { line -> | |||||
| isLineActive(line.status) || | |||||
| isLineDone(line.status) || | |||||
| line.startTime != null | |||||
| } | |||||
| if (anyStarted) { | |||||
| if (productProcess.startTime == null) { | |||||
| productProcess.startTime = | |||||
| lines.mapNotNull { it.startTime }.minOrNull() ?: LocalDateTime.now() | |||||
| } | |||||
| if (productProcess.status != ProductProcessStatus.IN_PROGRESS) { | |||||
| productProcess.status = ProductProcessStatus.IN_PROGRESS | |||||
| } | |||||
| productProcessRepository.save(productProcess) | |||||
| } | |||||
| } | |||||
| open fun StartProductProcessLine(productProcessLineId: Long): MessageResponse { | open fun StartProductProcessLine(productProcessLineId: Long): MessageResponse { | ||||
| updateProductProcessLineStartTime(productProcessLineId) | |||||
| //updateProductProcessLineStatus(productProcessLineId, "InProgress") | |||||
| val productProcessLine = productProcessLineRepository.findById(productProcessLineId).orElse(null) | val productProcessLine = productProcessLineRepository.findById(productProcessLineId).orElse(null) | ||||
| val allproductProcessLines = | |||||
| productProcessLineRepository.findByProductProcess_Id(productProcessLine.productProcess?.id ?: 0L) | |||||
| if (allproductProcessLines.all { it.status == "Pending" }) { | |||||
| updateProductProcessLineStatus(productProcessLineId, "InProgress") | |||||
| updateProductProcessStartTime(productProcessLine.productProcess.id) | |||||
| updateProductProcessStatus(productProcessLine.productProcess.id, ProductProcessStatus.IN_PROGRESS) | |||||
| } else { | |||||
| updateProductProcessLineStatus(productProcessLineId, "InProgress") | |||||
| println(" Service: ProductProcess Lines are not Pending") | |||||
| println(" Service: ProductProcess Lines: ${allproductProcessLines.map { it.status }}") | |||||
| println(" Service: ProductProcess Line: ${productProcessLine.status}") | |||||
| } | |||||
| updateProductProcessLineStartTime(productProcessLineId) | |||||
| updateProductProcessLineStatus(productProcessLineId, "InProgress") | |||||
| val productProcessId = productProcessLine?.productProcess?.id ?: 0L | |||||
| syncProductProcessStatusFromLines(productProcessId) | |||||
| return MessageResponse( | return MessageResponse( | ||||
| id = productProcessLine.id, | |||||
| id = productProcessLine?.id, | |||||
| code = "200", | code = "200", | ||||
| name = "ProductProcess StartTime Updated", | name = "ProductProcess StartTime Updated", | ||||
| type = "success", | type = "success", | ||||
| @@ -1976,47 +2020,7 @@ open class ProductProcessService( | |||||
| productProcessLine.startTime = LocalDateTime.now() | productProcessLine.startTime = LocalDateTime.now() | ||||
| productProcessLineRepository.save(productProcessLine) | productProcessLineRepository.save(productProcessLine) | ||||
| } | } | ||||
| if (allproductProcessLines.all { it.status == "Completed" || it.status == "Pass" }) { | |||||
| 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) | |||||
| val existingSil = jobOrder.id?.let { stockInLineRepository.findFirstByJobOrder_IdAndDeletedFalse(it) } | |||||
| if (existingSil != null) { | |||||
| stockInLineService.update( | |||||
| SaveStockInLineRequest( | |||||
| id = existingSil.id, | |||||
| itemId = existingSil.item?.id ?: productProcess?.item?.id ?: 0L, | |||||
| acceptedQty = jobOrder.reqQty ?: BigDecimal.ZERO, | |||||
| acceptQty = jobOrder.reqQty ?: BigDecimal.ZERO, | |||||
| productLotNo = jobOrder.code, | |||||
| productionDate = LocalDate.now(), | |||||
| jobOrderId = jobOrder.id, | |||||
| expiryDate = null, | |||||
| status = "pending", | |||||
| receiptDate = null, | |||||
| ) | |||||
| ) | |||||
| } else { | |||||
| 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 = "pending", | |||||
| ) | |||||
| ) | |||||
| } | |||||
| } | |||||
| } | |||||
| syncProductProcessStatusFromLines(productProcessId) | |||||
| return MessageResponse( | return MessageResponse( | ||||
| id = productProcessLine.id, | id = productProcessLine.id, | ||||
| code = "200", | code = "200", | ||||
| @@ -2144,6 +2148,7 @@ open class ProductProcessService( | |||||
| productionProcessIssueRepository.save(productProcessLineIssue) | productionProcessIssueRepository.save(productProcessLineIssue) | ||||
| productProcessLine.status = "InProgress" | productProcessLine.status = "InProgress" | ||||
| productProcessLineRepository.save(productProcessLine) | productProcessLineRepository.save(productProcessLine) | ||||
| syncProductProcessStatusFromLines(productProcessLine.productProcess?.id ?: 0L) | |||||
| return MessageResponse( | return MessageResponse( | ||||
| id = 0, | id = 0, | ||||