Commit fe9d7bb2d0ce78f9e15b7e37a7675afbf6c333ea

Authored by YunaiV
1 parent 892ce3e1

✨ feat(mes): 添加领料出库单行物料在工单 BOM 中校验功能

新增物料在工单 BOM 中的校验逻辑,确保领料单行的物料有效性,避免错误领料。
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/detail/MesWmProductionIssueDetailSaveReqVO.java
... ... @@ -35,9 +35,6 @@ public class MesWmProductionIssueDetailSaveReqVO {
35 35 @Schema(description = "批次号", example = "BATCH20260101001")
36 36 private String batchCode;
37 37  
38   - @Schema(description = "库存记录编号", example = "1")
39   - private Long materialStockId;
40   -
41 38 @Schema(description = "仓库编号", example = "1")
42 39 private Long warehouseId;
43 40  
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/line/MesWmProductionIssueLineSaveReqVO.java
1 1 package cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.line;
2 2  
3 3 import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.DecimalMin;
  5 +import jakarta.validation.constraints.NotNull;
4 6 import lombok.Data;
5 7  
6 8 import java.math.BigDecimal;
... ... @@ -13,12 +15,16 @@ public class MesWmProductionIssueLineSaveReqVO {
13 15 private Long id;
14 16  
15 17 @Schema(description = "领料单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  18 + @NotNull(message = "领料单ID不能为空")
16 19 private Long issueId;
17 20  
18 21 @Schema(description = "物料ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  22 + @NotNull(message = "物料ID不能为空")
19 23 private Long itemId;
20 24  
21 25 @Schema(description = "领料数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
  26 + @NotNull(message = "领料数量不能为空")
  27 + @DecimalMin(value = "0", inclusive = false, message = "领料数量必须大于 0")
22 28 private BigDecimal quantity;
23 29  
24 30 @Schema(description = "批次ID", example = "1")
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/materialrequest/MesWmMaterialRequestDO.java
... ... @@ -69,6 +69,8 @@ public class MesWmMaterialRequestDO extends BaseDO {
69 69 * 备注
70 70 */
71 71 private String remark;
  72 +
  73 + // TODO @AI:删除 attribute1-4 字段
72 74 /**
73 75 * 预留字段1
74 76 */
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/materialrequest/MesWmMaterialRequestLineDO.java
... ... @@ -54,6 +54,8 @@ public class MesWmMaterialRequestLineDO extends BaseDO {
54 54 * 备注
55 55 */
56 56 private String remark;
  57 +
  58 + // TODO @AI:删除 attribute1-4 字段
57 59 /**
58 60 * 预留字段1
59 61 */
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
... ... @@ -366,6 +366,7 @@ public interface ErrorCodeConstants {
366 366 ErrorCode WM_PRODUCTION_ISSUE_WORKSTATION_NOT_EXISTS = new ErrorCode(1_040_708_005, "工作站不存在");
367 367 ErrorCode WM_PRODUCTION_ISSUE_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_708_006, "生产领料出库单已完成或已取消,无法取消");
368 368 ErrorCode WM_PRODUCTION_ISSUE_LINE_NOT_EXISTS = new ErrorCode(1_040_708_100, "生产领料出库单行不存在");
  369 + ErrorCode WM_PRODUCTION_ISSUE_LINE_ITEM_NOT_IN_BOM = new ErrorCode(1_040_708_101, "当前物料不在生产工单的 BOM 物料清单中");
369 370 ErrorCode WM_PRODUCTION_ISSUE_DETAIL_NOT_EXISTS = new ErrorCode(1_040_708_200, "生产领料出库单明细不存在");
370 371  
371 372 }
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMaterialRequestStatusEnum.java
... ... @@ -7,7 +7,6 @@ import lombok.Getter;
7 7  
8 8 import java.util.Arrays;
9 9  
10   -// TODO @AI:这里需要迁移下;
11 10 /**
12 11 * MES 领料申请单状态枚举
13 12 *
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueLineServiceImpl.java
1 1 package cn.iocoder.yudao.module.mes.service.wm.productionissue;
2 2  
  3 +import cn.hutool.core.collection.CollUtil;
3 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
5 6 import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.line.MesWmProductionIssueLinePageReqVO;
6 7 import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.line.MesWmProductionIssueLineSaveReqVO;
  8 +import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderBomDO;
  9 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueDO;
7 10 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueLineDO;
8 11 import cn.iocoder.yudao.module.mes.dal.mysql.wm.productionissue.MesWmProductionIssueLineMapper;
9 12 import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
  13 +import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderBomService;
10 14 import jakarta.annotation.Resource;
11 15 import org.springframework.context.annotation.Lazy;
12 16 import org.springframework.stereotype.Service;
... ... @@ -15,6 +19,7 @@ import org.springframework.validation.annotation.Validated;
15 19 import java.util.List;
16 20  
17 21 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  22 +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_PRODUCTION_ISSUE_LINE_ITEM_NOT_IN_BOM;
18 23 import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_PRODUCTION_ISSUE_LINE_NOT_EXISTS;
19 24  
20 25 /**
... ... @@ -32,11 +37,13 @@ public class MesWmProductionIssueLineServiceImpl implements MesWmProductionIssue
32 37 private MesWmProductionIssueService issueService;
33 38 @Resource
34 39 private MesMdItemService itemService;
  40 + @Resource
  41 + private MesProWorkOrderBomService workOrderBomService;
35 42  
36 43 @Override
37 44 public Long createProductionIssueLine(MesWmProductionIssueLineSaveReqVO createReqVO) {
38   - // 校验父数据存在
39   - issueService.validateProductionIssueExists(createReqVO.getIssueId());
  45 + // 校验父数据存在 + 校验物料在工单 BOM 中
  46 + validateItemInWorkOrderBom(createReqVO.getIssueId(), createReqVO.getItemId());
40 47 // 校验物料存在
41 48 itemService.validateItemExists(createReqVO.getItemId());
42 49  
... ... @@ -50,8 +57,8 @@ public class MesWmProductionIssueLineServiceImpl implements MesWmProductionIssue
50 57 public void updateProductionIssueLine(MesWmProductionIssueLineSaveReqVO updateReqVO) {
51 58 // 校验存在
52 59 validateProductionIssueLineExists(updateReqVO.getId());
53   - // 校验父数据存在
54   - issueService.validateProductionIssueExists(updateReqVO.getIssueId());
  60 + // 校验父数据存在 + 校验物料在工单 BOM 中
  61 + validateItemInWorkOrderBom(updateReqVO.getIssueId(), updateReqVO.getItemId());
55 62 // 校验物料存在
56 63 itemService.validateItemExists(updateReqVO.getItemId());
57 64  
... ... @@ -97,4 +104,19 @@ public class MesWmProductionIssueLineServiceImpl implements MesWmProductionIssue
97 104 return line;
98 105 }
99 106  
  107 + private void validateItemInWorkOrderBom(Long issueId, Long itemId) {
  108 + // 校验领料单存在,并获取工单编号
  109 + MesWmProductionIssueDO issue = issueService.validateProductionIssueExists(issueId);
  110 + // 校验物料是否在工单 BOM 中(防错料)
  111 + List<MesProWorkOrderBomDO> workOrderBoms = workOrderBomService.getWorkOrderBomListByWorkOrderId(issue.getWorkOrderId());
  112 + if (CollUtil.isEmpty(workOrderBoms)) {
  113 + return;
  114 + }
  115 + MesProWorkOrderBomDO workOrderBom = CollUtil.findOne(workOrderBoms,
  116 + bom -> bom.getItemId().equals(itemId));
  117 + if (workOrderBom == null) {
  118 + throw exception(WM_PRODUCTION_ISSUE_LINE_ITEM_NOT_IN_BOM);
  119 + }
  120 + }
  121 +
100 122 }
... ...