Commit 6976335596078ba3c6849c1a962907cbb6dfa04c

Authored by YunaiV
1 parent eca2c176

✨ feat(mes): 新增生产工单编码及状态管理功能

新增生产工单编码规则和状态管理逻辑,优化工单创建和更新流程。
同时,更新前端表单以支持新的工单状态和来源单据字段,提升用户体验。
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/workorder/vo/MesProWorkorderSaveReqVO.java
@@ -70,4 +70,4 @@ public class MesProWorkOrderSaveReqVO { @@ -70,4 +70,4 @@ public class MesProWorkOrderSaveReqVO {
70 @Schema(description = "备注", example = "备注") 70 @Schema(description = "备注", example = "备注")
71 private String remark; 71 private String remark;
72 72
73 - } 73 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
@@ -238,8 +238,9 @@ public interface ErrorCodeConstants { @@ -238,8 +238,9 @@ public interface ErrorCodeConstants {
238 // ========== MES 生产管理-生产工单(1-040-502-000) ========== 238 // ========== MES 生产管理-生产工单(1-040-502-000) ==========
239 ErrorCode PRO_WORK_ORDER_NOT_EXISTS = new ErrorCode(1_040_502_000, "生产工单不存在"); 239 ErrorCode PRO_WORK_ORDER_NOT_EXISTS = new ErrorCode(1_040_502_000, "生产工单不存在");
240 ErrorCode PRO_WORK_ORDER_CODE_DUPLICATE = new ErrorCode(1_040_502_001, "生产工单编码已存在"); 240 ErrorCode PRO_WORK_ORDER_CODE_DUPLICATE = new ErrorCode(1_040_502_001, "生产工单编码已存在");
241 - ErrorCode PRO_WORK_ORDER_NOT_PREPARE = new ErrorCode(1_040_502_002, "只能删除草稿状态的工单"); 241 + ErrorCode PRO_WORK_ORDER_NOT_PREPARE = new ErrorCode(1_040_502_002, "只有草稿状态的工单才能执行此操作");
242 ErrorCode PRO_WORK_ORDER_NOT_CONFIRMED = new ErrorCode(1_040_502_003, "只有已确认状态的工单才能执行此操作"); 242 ErrorCode PRO_WORK_ORDER_NOT_CONFIRMED = new ErrorCode(1_040_502_003, "只有已确认状态的工单才能执行此操作");
  243 + ErrorCode PRO_WORK_ORDER_HAS_CHILDREN = new ErrorCode(1_040_502_004, "存在子工单,无法删除");
243 ErrorCode PRO_WORK_ORDER_BOM_NOT_EXISTS = new ErrorCode(1_040_502_100, "生产工单BOM不存在"); 244 ErrorCode PRO_WORK_ORDER_BOM_NOT_EXISTS = new ErrorCode(1_040_502_100, "生产工单BOM不存在");
244 245
245 // ========== MES 生产管理-生产任务(1-040-503-000) ========== 246 // ========== MES 生产管理-生产任务(1-040-503-000) ==========
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/md/autocode/MesMdAutoCodeRuleCodeEnum.java
@@ -44,7 +44,8 @@ public enum MesMdAutoCodeRuleCodeEnum { @@ -44,7 +44,8 @@ public enum MesMdAutoCodeRuleCodeEnum {
44 DV_REPAIR_CODE("DV_REPAIR_CODE", "维修单编码"), 44 DV_REPAIR_CODE("DV_REPAIR_CODE", "维修单编码"),
45 WM_SALES_NOTICE_CODE("WM_SALES_NOTICE_CODE", "发货通知单编码"), 45 WM_SALES_NOTICE_CODE("WM_SALES_NOTICE_CODE", "发货通知单编码"),
46 WM_RETURN_SALES_CODE("WM_RETURN_SALES_CODE", "销售退货单编码"), 46 WM_RETURN_SALES_CODE("WM_RETURN_SALES_CODE", "销售退货单编码"),
47 - WM_MISC_ISSUE_CODE("WM_MISC_ISSUE_CODE", "杂项出库单编码"); 47 + WM_MISC_ISSUE_CODE("WM_MISC_ISSUE_CODE", "杂项出库单编码"),
  48 + PRO_WORK_ORDER_CODE("PRO_WORK_ORDER_CODE", "生产工单编码");
48 49
49 /** 50 /**
50 * 规则代码 51 * 规则代码
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/workorder/MesProWorkorderServiceImpl.java
@@ -56,6 +56,7 @@ public class MesProWorkOrderServiceImpl implements MesProWorkOrderService { @@ -56,6 +56,7 @@ public class MesProWorkOrderServiceImpl implements MesProWorkOrderService {
56 @Override 56 @Override
57 @Transactional(rollbackFor = Exception.class) 57 @Transactional(rollbackFor = Exception.class)
58 public Long createWorkOrder(MesProWorkOrderSaveReqVO createReqVO) { 58 public Long createWorkOrder(MesProWorkOrderSaveReqVO createReqVO) {
  59 + // TODO @AI:validateXXXSaveData
59 // 1.1 校验编码唯一 60 // 1.1 校验编码唯一
60 validateWorkOrderCodeUnique(null, createReqVO.getCode()); 61 validateWorkOrderCodeUnique(null, createReqVO.getCode());
61 // 1.2 校验产品存在 62 // 1.2 校验产品存在
@@ -69,9 +70,7 @@ public class MesProWorkOrderServiceImpl implements MesProWorkOrderService { @@ -69,9 +70,7 @@ public class MesProWorkOrderServiceImpl implements MesProWorkOrderService {
69 } 70 }
70 // 2.2 插入工单 71 // 2.2 插入工单
71 MesProWorkOrderDO workOrder = BeanUtils.toBean(createReqVO, MesProWorkOrderDO.class); 72 MesProWorkOrderDO workOrder = BeanUtils.toBean(createReqVO, MesProWorkOrderDO.class);
72 - if (workOrder.getStatus() == null) {  
73 - workOrder.setStatus(MesProWorkOrderStatusEnum.PREPARE.getStatus());  
74 - } 73 + workOrder.setStatus(MesProWorkOrderStatusEnum.PREPARE.getStatus());
75 workOrderMapper.insert(workOrder); 74 workOrderMapper.insert(workOrder);
76 75
77 // 3. 自动生成 BOM:根据产品 BOM 生成工单 BOM 76 // 3. 自动生成 BOM:根据产品 BOM 生成工单 BOM
@@ -88,9 +87,14 @@ public class MesProWorkOrderServiceImpl implements MesProWorkOrderService { @@ -88,9 +87,14 @@ public class MesProWorkOrderServiceImpl implements MesProWorkOrderService {
88 public void updateWorkOrder(MesProWorkOrderSaveReqVO updateReqVO) { 87 public void updateWorkOrder(MesProWorkOrderSaveReqVO updateReqVO) {
89 // 1.1 校验存在 88 // 1.1 校验存在
90 MesProWorkOrderDO oldWorkOrder = validateWorkOrderExists(updateReqVO.getId()); 89 MesProWorkOrderDO oldWorkOrder = validateWorkOrderExists(updateReqVO.getId());
91 - // 1.2 校验编码唯一 90 + // TODO @AI:validateXXXSaveData
  91 + // 1.2 只有草稿状态才能编辑
  92 + if (ObjUtil.notEqual(oldWorkOrder.getStatus(), MesProWorkOrderStatusEnum.PREPARE.getStatus())) {
  93 + throw exception(PRO_WORK_ORDER_NOT_PREPARE);
  94 + }
  95 + // 1.3 校验编码唯一
92 validateWorkOrderCodeUnique(updateReqVO.getId(), updateReqVO.getCode()); 96 validateWorkOrderCodeUnique(updateReqVO.getId(), updateReqVO.getCode());
93 - // 1.3 校验批次配置 97 + // 1.4 校验批次配置
94 validateBatchConfig(updateReqVO.getProductId(), updateReqVO.getClientId()); 98 validateBatchConfig(updateReqVO.getProductId(), updateReqVO.getClientId());
95 99
96 // 2. 判断产品或数量是否变更,如果变更则重新生成 BOM(updated=true 会先清理旧数据) 100 // 2. 判断产品或数量是否变更,如果变更则重新生成 BOM(updated=true 会先清理旧数据)
@@ -114,6 +118,11 @@ public class MesProWorkOrderServiceImpl implements MesProWorkOrderService { @@ -114,6 +118,11 @@ public class MesProWorkOrderServiceImpl implements MesProWorkOrderService {
114 if (ObjUtil.notEqual(workOrder.getStatus(), MesProWorkOrderStatusEnum.PREPARE.getStatus())) { 118 if (ObjUtil.notEqual(workOrder.getStatus(), MesProWorkOrderStatusEnum.PREPARE.getStatus())) {
115 throw exception(PRO_WORK_ORDER_NOT_PREPARE); 119 throw exception(PRO_WORK_ORDER_NOT_PREPARE);
116 } 120 }
  121 + // 1.3 校验是否有子工单
  122 + Long childCount = workOrderMapper.selectCount(MesProWorkOrderDO::getParentId, id);
  123 + if (childCount > 0) {
  124 + throw exception(PRO_WORK_ORDER_HAS_CHILDREN);
  125 + }
117 126
118 // 2. 删除工单 + BOM 127 // 2. 删除工单 + BOM
119 workOrderMapper.deleteById(id); 128 workOrderMapper.deleteById(id);
@@ -227,7 +236,7 @@ public class MesProWorkOrderServiceImpl implements MesProWorkOrderService { @@ -227,7 +236,7 @@ public class MesProWorkOrderServiceImpl implements MesProWorkOrderService {
227 } 236 }
228 237
229 private void validateBatchConfig(Long productId, Long clientId) { 238 private void validateBatchConfig(Long productId, Long clientId) {
230 - // 如果产品有 clientFlag=true,则 clientId 必填 239 + // 如果产品有 clientFlag =true,则 clientId 必填
231 MesMdItemBatchConfigDO batchConfig = itemBatchConfigService.getItemBatchConfigByItemId(productId); 240 MesMdItemBatchConfigDO batchConfig = itemBatchConfigService.getItemBatchConfigByItemId(productId);
232 if (batchConfig != null && Boolean.TRUE.equals(batchConfig.getClientFlag()) && clientId == null) { 241 if (batchConfig != null && Boolean.TRUE.equals(batchConfig.getClientFlag()) && clientId == null) {
233 // 产品要求批次管理中必须填写客户 242 // 产品要求批次管理中必须填写客户