Commit 6976335596078ba3c6849c1a962907cbb6dfa04c
1 parent
eca2c176
✨ feat(mes): 新增生产工单编码及状态管理功能
新增生产工单编码规则和状态管理逻辑,优化工单创建和更新流程。 同时,更新前端表单以支持新的工单状态和来源单据字段,提升用户体验。
Showing
4 changed files
with
20 additions
and
9 deletions
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/workorder/vo/MesProWorkorderSaveReqVO.java
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 | // 产品要求批次管理中必须填写客户 |