Commit fe9d7bb2d0ce78f9e15b7e37a7675afbf6c333ea
1 parent
892ce3e1
✨ feat(mes): 添加领料出库单行物料在工单 BOM 中校验功能
新增物料在工单 BOM 中的校验逻辑,确保领料单行的物料有效性,避免错误领料。
Showing
7 changed files
with
37 additions
and
8 deletions
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,9 +35,6 @@ public class MesWmProductionIssueDetailSaveReqVO { | ||
| 35 | @Schema(description = "批次号", example = "BATCH20260101001") | 35 | @Schema(description = "批次号", example = "BATCH20260101001") |
| 36 | private String batchCode; | 36 | private String batchCode; |
| 37 | 37 | ||
| 38 | - @Schema(description = "库存记录编号", example = "1") | ||
| 39 | - private Long materialStockId; | ||
| 40 | - | ||
| 41 | @Schema(description = "仓库编号", example = "1") | 38 | @Schema(description = "仓库编号", example = "1") |
| 42 | private Long warehouseId; | 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 | package cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.line; | 1 | package cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.line; |
| 2 | 2 | ||
| 3 | import io.swagger.v3.oas.annotations.media.Schema; | 3 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | +import jakarta.validation.constraints.DecimalMin; | ||
| 5 | +import jakarta.validation.constraints.NotNull; | ||
| 4 | import lombok.Data; | 6 | import lombok.Data; |
| 5 | 7 | ||
| 6 | import java.math.BigDecimal; | 8 | import java.math.BigDecimal; |
| @@ -13,12 +15,16 @@ public class MesWmProductionIssueLineSaveReqVO { | @@ -13,12 +15,16 @@ public class MesWmProductionIssueLineSaveReqVO { | ||
| 13 | private Long id; | 15 | private Long id; |
| 14 | 16 | ||
| 15 | @Schema(description = "领料单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | 17 | @Schema(description = "领料单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 18 | + @NotNull(message = "领料单ID不能为空") | ||
| 16 | private Long issueId; | 19 | private Long issueId; |
| 17 | 20 | ||
| 18 | @Schema(description = "物料ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | 21 | @Schema(description = "物料ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 22 | + @NotNull(message = "物料ID不能为空") | ||
| 19 | private Long itemId; | 23 | private Long itemId; |
| 20 | 24 | ||
| 21 | @Schema(description = "领料数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") | 25 | @Schema(description = "领料数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00") |
| 26 | + @NotNull(message = "领料数量不能为空") | ||
| 27 | + @DecimalMin(value = "0", inclusive = false, message = "领料数量必须大于 0") | ||
| 22 | private BigDecimal quantity; | 28 | private BigDecimal quantity; |
| 23 | 29 | ||
| 24 | @Schema(description = "批次ID", example = "1") | 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,6 +69,8 @@ public class MesWmMaterialRequestDO extends BaseDO { | ||
| 69 | * 备注 | 69 | * 备注 |
| 70 | */ | 70 | */ |
| 71 | private String remark; | 71 | private String remark; |
| 72 | + | ||
| 73 | + // TODO @AI:删除 attribute1-4 字段 | ||
| 72 | /** | 74 | /** |
| 73 | * 预留字段1 | 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,6 +54,8 @@ public class MesWmMaterialRequestLineDO extends BaseDO { | ||
| 54 | * 备注 | 54 | * 备注 |
| 55 | */ | 55 | */ |
| 56 | private String remark; | 56 | private String remark; |
| 57 | + | ||
| 58 | + // TODO @AI:删除 attribute1-4 字段 | ||
| 57 | /** | 59 | /** |
| 58 | * 预留字段1 | 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,6 +366,7 @@ public interface ErrorCodeConstants { | ||
| 366 | ErrorCode WM_PRODUCTION_ISSUE_WORKSTATION_NOT_EXISTS = new ErrorCode(1_040_708_005, "工作站不存在"); | 366 | ErrorCode WM_PRODUCTION_ISSUE_WORKSTATION_NOT_EXISTS = new ErrorCode(1_040_708_005, "工作站不存在"); |
| 367 | ErrorCode WM_PRODUCTION_ISSUE_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_708_006, "生产领料出库单已完成或已取消,无法取消"); | 367 | ErrorCode WM_PRODUCTION_ISSUE_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_708_006, "生产领料出库单已完成或已取消,无法取消"); |
| 368 | ErrorCode WM_PRODUCTION_ISSUE_LINE_NOT_EXISTS = new ErrorCode(1_040_708_100, "生产领料出库单行不存在"); | 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 | ErrorCode WM_PRODUCTION_ISSUE_DETAIL_NOT_EXISTS = new ErrorCode(1_040_708_200, "生产领料出库单明细不存在"); | 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
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueLineServiceImpl.java
| 1 | package cn.iocoder.yudao.module.mes.service.wm.productionissue; | 1 | package cn.iocoder.yudao.module.mes.service.wm.productionissue; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.collection.CollUtil; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 5 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 5 | import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.line.MesWmProductionIssueLinePageReqVO; | 6 | import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.line.MesWmProductionIssueLinePageReqVO; |
| 6 | import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.line.MesWmProductionIssueLineSaveReqVO; | 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 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueLineDO; | 10 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueLineDO; |
| 8 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.productionissue.MesWmProductionIssueLineMapper; | 11 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.productionissue.MesWmProductionIssueLineMapper; |
| 9 | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; | 12 | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; |
| 13 | +import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderBomService; | ||
| 10 | import jakarta.annotation.Resource; | 14 | import jakarta.annotation.Resource; |
| 11 | import org.springframework.context.annotation.Lazy; | 15 | import org.springframework.context.annotation.Lazy; |
| 12 | import org.springframework.stereotype.Service; | 16 | import org.springframework.stereotype.Service; |
| @@ -15,6 +19,7 @@ import org.springframework.validation.annotation.Validated; | @@ -15,6 +19,7 @@ import org.springframework.validation.annotation.Validated; | ||
| 15 | import java.util.List; | 19 | import java.util.List; |
| 16 | 20 | ||
| 17 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 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 | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_PRODUCTION_ISSUE_LINE_NOT_EXISTS; | 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,11 +37,13 @@ public class MesWmProductionIssueLineServiceImpl implements MesWmProductionIssue | ||
| 32 | private MesWmProductionIssueService issueService; | 37 | private MesWmProductionIssueService issueService; |
| 33 | @Resource | 38 | @Resource |
| 34 | private MesMdItemService itemService; | 39 | private MesMdItemService itemService; |
| 40 | + @Resource | ||
| 41 | + private MesProWorkOrderBomService workOrderBomService; | ||
| 35 | 42 | ||
| 36 | @Override | 43 | @Override |
| 37 | public Long createProductionIssueLine(MesWmProductionIssueLineSaveReqVO createReqVO) { | 44 | public Long createProductionIssueLine(MesWmProductionIssueLineSaveReqVO createReqVO) { |
| 38 | - // 校验父数据存在 | ||
| 39 | - issueService.validateProductionIssueExists(createReqVO.getIssueId()); | 45 | + // 校验父数据存在 + 校验物料在工单 BOM 中 |
| 46 | + validateItemInWorkOrderBom(createReqVO.getIssueId(), createReqVO.getItemId()); | ||
| 40 | // 校验物料存在 | 47 | // 校验物料存在 |
| 41 | itemService.validateItemExists(createReqVO.getItemId()); | 48 | itemService.validateItemExists(createReqVO.getItemId()); |
| 42 | 49 | ||
| @@ -50,8 +57,8 @@ public class MesWmProductionIssueLineServiceImpl implements MesWmProductionIssue | @@ -50,8 +57,8 @@ public class MesWmProductionIssueLineServiceImpl implements MesWmProductionIssue | ||
| 50 | public void updateProductionIssueLine(MesWmProductionIssueLineSaveReqVO updateReqVO) { | 57 | public void updateProductionIssueLine(MesWmProductionIssueLineSaveReqVO updateReqVO) { |
| 51 | // 校验存在 | 58 | // 校验存在 |
| 52 | validateProductionIssueLineExists(updateReqVO.getId()); | 59 | validateProductionIssueLineExists(updateReqVO.getId()); |
| 53 | - // 校验父数据存在 | ||
| 54 | - issueService.validateProductionIssueExists(updateReqVO.getIssueId()); | 60 | + // 校验父数据存在 + 校验物料在工单 BOM 中 |
| 61 | + validateItemInWorkOrderBom(updateReqVO.getIssueId(), updateReqVO.getItemId()); | ||
| 55 | // 校验物料存在 | 62 | // 校验物料存在 |
| 56 | itemService.validateItemExists(updateReqVO.getItemId()); | 63 | itemService.validateItemExists(updateReqVO.getItemId()); |
| 57 | 64 | ||
| @@ -97,4 +104,19 @@ public class MesWmProductionIssueLineServiceImpl implements MesWmProductionIssue | @@ -97,4 +104,19 @@ public class MesWmProductionIssueLineServiceImpl implements MesWmProductionIssue | ||
| 97 | return line; | 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 | } |