| | |
| | | import cn.iocoder.yudao.module.mes.enums.pro.MesProMpsStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.pro.MesProFeedbackStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.pro.MesProWorkOrderSourceTypeEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.pro.MesProWorkOrderStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService; |
| | | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; |
| | | import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProductService; |
| | |
| | | throw exception(PRO_MPS_NOT_ISSUED); |
| | | } |
| | | |
| | | // 级联取消关联的生产工单 |
| | | // 级联取消关联的生产工单(跟随工单当前状态,且不误伤合并下发的共享工单) |
| | | if (mps.getWorkOrderId() != null) { |
| | | try { |
| | | // 1. 统计该工单被多少条 MPS 引用:合并下发的多条 MPS 共享同一个工单 |
| | | Long refCount = mpsMapper.selectCount(MesProMpsDO::getWorkOrderId, mps.getWorkOrderId()); |
| | | if (refCount != null && refCount > 1) { |
| | | // 共享工单:只取消当前 MPS,不动工单 |
| | | log.info("[cancelMps] 生产工单({}) 被 {} 条 MPS 共用,跳过级联取消工单", |
| | | mps.getWorkOrderId(), refCount); |
| | | } else { |
| | | MesProWorkOrderDO workOrder = workOrderService.getWorkOrder(mps.getWorkOrderId()); |
| | | if (workOrder != null |
| | | && MesProWorkOrderStatusEnum.CONFIRMED.getStatus().equals(workOrder.getStatus())) { |
| | | // 只有"已确认"状态的工单才需要级联取消 |
| | | workOrderService.cancelWorkOrder(mps.getWorkOrderId()); |
| | | log.info("[cancelMps] 级联取消生产工单,workOrderId={}", mps.getWorkOrderId()); |
| | | } catch (Exception e) { |
| | | // 工单可能已完成或已取消,记录日志但不阻止 MPS 取消 |
| | | log.warn("[cancelMps] 取消生产工单失败,workOrderId={},原因:{}", mps.getWorkOrderId(), e.getMessage()); |
| | | } else { |
| | | // 工单已是草稿/已完成/已取消,无需级联取消,直接取消 MPS |
| | | log.info("[cancelMps] 生产工单({}) 状态为 {},无需级联取消", |
| | | mps.getWorkOrderId(), workOrder != null ? workOrder.getStatus() : "null"); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | * 判断单个 MPS 是否完成 |
| | | */ |
| | | private boolean isMpsFinished(MesProMpsDO mps) { |
| | | // 已取消的 MPS 视为终态,不再阻塞生产完成判断(与 checkCanCreateSalesNotice 的口径保持一致) |
| | | if (MesProMpsStatusEnum.CANCELED.getStatus().equals(mps.getStatus())) { |
| | | return true; |
| | | } |
| | | // 1. 已生产数量 >= 计划数量 |
| | | BigDecimal quantityProduced = ObjUtil.defaultIfNull(mps.getQuantityProduced(), BigDecimal.ZERO); |
| | | if (quantityProduced.compareTo(mps.getQuantity()) < 0) { |