Commit 9c94c1f58940f0e3aeb90aa4c449ff88dc584e20

Authored by YunaiV
1 parent 0d27932d

feat(mes): 修复 IQC 模块 TODO @AI(第二轮)

1. MesQcIqcSaveReqVO: 新增 @AssertTrue 校验 qualifiedQuantity + unqualifiedQuantity == receivedQuantity
2. MesQcIqcLineDO/ServiceImpl/RespVO/Controller: toolId(Long) 改为 tool(String),从 MesQcIndicatorDO 冗余读取,移除 MesTmToolService 依赖
3. MesWmArrivalNoticeService/Impl: 新增 validateArrivalNoticeAndLineExists 方法,校验通知单+行存在且匹配
4. MesQcIqcServiceImpl: 抽取 validateSourceDoc 私有方法校验来源单据;completeIqc 增加 checkResult 必填校验并移除重复数量校验;writeBackSourceDoc 使用 ObjectUtil.hasNull 简化判断
5. ErrorCodeConstants: 新增 QC_IQC_SOURCE_DOC_PARAMS_MISSING、QC_IQC_CHECK_RESULT_EMPTY
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcLineController.java
... ... @@ -9,11 +9,9 @@ import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.line.MesQcIqcLineR
9 9 import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
10 10 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.iqc.MesQcIqcLineDO;
11 11 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicator.MesQcIndicatorDO;
12   -import cn.iocoder.yudao.module.mes.dal.dataobject.tm.tool.MesTmToolDO;
13 12 import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
14 13 import cn.iocoder.yudao.module.mes.service.qc.iqc.MesQcIqcLineService;
15 14 import cn.iocoder.yudao.module.mes.service.qc.indicator.MesQcIndicatorService;
16   -import cn.iocoder.yudao.module.mes.service.tm.tool.MesTmToolService;
17 15 import io.swagger.v3.oas.annotations.Operation;
18 16 import io.swagger.v3.oas.annotations.Parameter;
19 17 import io.swagger.v3.oas.annotations.tags.Tag;
... ... @@ -46,8 +44,6 @@ public class MesQcIqcLineController {
46 44 private MesQcIndicatorService indicatorService;
47 45 @Resource
48 46 private MesMdUnitMeasureService unitMeasureService;
49   - @Resource
50   - private MesTmToolService toolService;
51 47  
52 48 @GetMapping("/get")
53 49 @Operation(summary = "获得来料检验单行")
... ... @@ -85,13 +81,6 @@ public class MesQcIqcLineController {
85 81 .setIndicatorType(indicator.getType()));
86 82 findAndThen(unitMeasureMap, vo.getUnitMeasureId(),
87 83 unit -> vo.setUnitMeasureName(unit.getName()));
88   - // 逐个查询工具名称(工具数量通常较少)
89   - if (vo.getToolId() != null) {
90   - MesTmToolDO tool = toolService.getTool(vo.getToolId());
91   - if (tool != null) {
92   - vo.setToolName(tool.getName());
93   - }
94   - }
95 84 });
96 85 }
97 86  
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/MesQcIqcSaveReqVO.java
1 1 package cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo;
2 2  
  3 +import cn.hutool.core.util.ObjUtil;
3 4 import io.swagger.v3.oas.annotations.media.Schema;
  5 +import jakarta.validation.constraints.AssertTrue;
4 6 import jakarta.validation.constraints.DecimalMin;
5 7 import jakarta.validation.constraints.NotEmpty;
6 8 import jakarta.validation.constraints.NotNull;
... ... @@ -82,4 +84,13 @@ public class MesQcIqcSaveReqVO {
82 84 @Schema(description = "备注", example = "备注")
83 85 private String remark;
84 86  
  87 + @AssertTrue(message = "合格品数量与不合格品数量之和必须等于本次接收数量")
  88 + @Schema(hidden = true)
  89 + public boolean isQuantityValid() {
  90 + if (ObjUtil.hasNull(qualifiedQuantity, unqualifiedQuantity, receivedQuantity)) {
  91 + return true; // @NotNull 会处理 null
  92 + }
  93 + return qualifiedQuantity.add(unqualifiedQuantity).compareTo(receivedQuantity) == 0;
  94 + }
  95 +
85 96 }
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/vo/line/MesQcIqcLineRespVO.java
... ... @@ -30,11 +30,8 @@ public class MesQcIqcLineRespVO {
30 30 @Schema(description = "检测指标类型", example = "QUANTITATIVE")
31 31 private String indicatorType;
32 32  
33   - @Schema(description = "检测工具 ID", example = "5")
34   - private Long toolId;
35   -
36   - @Schema(description = "检测工具名称", example = "卡尺")
37   - private String toolName;
  33 + @Schema(description = "检测工具", example = "卡尺")
  34 + private String tool;
38 35  
39 36 @Schema(description = "检测方法", example = "目测")
40 37 private String checkMethod;
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/iqc/MesQcIqcLineDO.java
... ... @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.mes.dal.dataobject.qc.iqc;
3 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 4 import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
5 5 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicator.MesQcIndicatorDO;
6   -import cn.iocoder.yudao.module.mes.dal.dataobject.tm.tool.MesTmToolDO;
7 6 import com.baomidou.mybatisplus.annotation.KeySequence;
8 7 import com.baomidou.mybatisplus.annotation.TableId;
9 8 import com.baomidou.mybatisplus.annotation.TableName;
... ... @@ -44,11 +43,11 @@ public class MesQcIqcLineDO extends BaseDO {
44 43 */
45 44 private Long indicatorId;
46 45 /**
47   - * 检测工具 ID
  46 + * 检测工具
48 47 *
49   - * 关联 {@link MesTmToolDO#getId()}
  48 + * 冗余 {@link MesQcIndicatorDO#getTool()}
50 49 */
51   - private Long toolId;
  50 + private String tool;
52 51 /**
53 52 * 检测方法
54 53 */
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/template/MesQcTemplateIndicatorMapper.java
... ... @@ -9,6 +9,7 @@ import org.apache.ibatis.annotations.Mapper;
9 9  
10 10 import java.util.List;
11 11  
  12 +// TODO @AI:MesQcTemplateIndicatorService 独立一个;然后非 MesQcTemplateIndicatorService 调用 mapper 的地方,都替换下;
12 13 /**
13 14 * MES 质检方案-检测指标项 Mapper
14 15 *
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
... ... @@ -250,6 +250,8 @@ public interface ErrorCodeConstants {
250 250 ErrorCode QC_IQC_NOT_PREPARE = new ErrorCode(1_040_603_002, "只有草稿状态的检验单才可操作");
251 251 ErrorCode QC_IQC_QUANTITY_MISMATCH = new ErrorCode(1_040_603_004, "合格品与不合格品数量之和须等于检测数量");
252 252 ErrorCode QC_IQC_NO_TEMPLATE = new ErrorCode(1_040_603_005, "当前产品未配置 IQC 检测模板");
  253 + ErrorCode QC_IQC_SOURCE_DOC_PARAMS_MISSING = new ErrorCode(1_040_603_006, "来源单据类型非空时,来源单据 ID 和来源单据行 ID 不能为空");
  254 + ErrorCode QC_IQC_CHECK_RESULT_EMPTY = new ErrorCode(1_040_603_007, "完成检验单前,检测结果必须填写");
253 255 // ========== MES 质量管理-来料检验行(1-040-603-100) ==========
254 256 ErrorCode QC_IQC_LINE_NOT_EXISTS = new ErrorCode(1_040_603_100, "来料检验行不存在");
255 257  
... ... @@ -344,4 +346,10 @@ public interface ErrorCodeConstants {
344 346 ErrorCode WM_MATERIAL_REQUEST_STATUS_INVALID = new ErrorCode(1_040_706_001, "领料申请单状态不正确,无法执行该操作");
345 347 ErrorCode WM_MATERIAL_REQUEST_LINE_NOT_EXISTS = new ErrorCode(1_040_706_100, "领料申请单行不存在");
346 348  
  349 + // ========== MES 仓库管理-外协出库单(1-040-707-000) ==========
  350 + ErrorCode WM_OUTSOURCE_ISSUE_NOT_EXISTS = new ErrorCode(1_040_707_000, "外协出库单不存在");
  351 + ErrorCode WM_OUTSOURCE_ISSUE_STATUS_INVALID = new ErrorCode(1_040_707_001, "外协出库单状态不正确,无法执行该操作");
  352 + ErrorCode WM_OUTSOURCE_ISSUE_QUANTITY_MISMATCH = new ErrorCode(1_040_707_002, "出库单行数量与明细数量不一致");
  353 + ErrorCode WM_OUTSOURCE_ISSUE_LINE_NOT_EXISTS = new ErrorCode(1_040_707_100, "外协出库单行不存在");
  354 +
347 355 }
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/iqc/MesQcIqcLineServiceImpl.java
... ... @@ -6,20 +6,24 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 6 import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.line.MesQcIqcLinePageReqVO;
7 7 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.defectrecord.MesQcDefectRecordDO;
8 8 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.iqc.MesQcIqcLineDO;
  9 +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicator.MesQcIndicatorDO;
9 10 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateIndicatorDO;
10 11 import cn.iocoder.yudao.module.mes.dal.mysql.qc.iqc.MesQcIqcLineMapper;
11 12 import cn.iocoder.yudao.module.mes.dal.mysql.qc.template.MesQcTemplateIndicatorMapper;
12 13 import cn.iocoder.yudao.module.mes.enums.qc.MesQcDefectLevelEnum;
  14 +import cn.iocoder.yudao.module.mes.service.qc.indicator.MesQcIndicatorService;
13 15 import jakarta.annotation.Resource;
14 16 import org.springframework.stereotype.Service;
15 17 import org.springframework.validation.annotation.Validated;
16 18  
17 19 import java.util.ArrayList;
18 20 import java.util.List;
  21 +import java.util.Map;
19 22 import java.util.Objects;
20 23  
21 24 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
22 25 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  26 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
23 27 import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
24 28  
25 29 /**
... ... @@ -36,6 +40,9 @@ public class MesQcIqcLineServiceImpl implements MesQcIqcLineService {
36 40 @Resource
37 41 private MesQcTemplateIndicatorMapper templateIndicatorMapper;
38 42  
  43 + @Resource
  44 + private MesQcIndicatorService indicatorService;
  45 +
39 46 @Override
40 47 public MesQcIqcLineDO validateIqcLineExists(Long id) {
41 48 MesQcIqcLineDO line = iqcLineMapper.selectById(id);
... ... @@ -57,14 +64,22 @@ public class MesQcIqcLineServiceImpl implements MesQcIqcLineService {
57 64  
58 65 @Override
59 66 public void createLinesFromTemplate(Long iqcId, Long templateId) {
60   - List<MesQcTemplateIndicatorDO> indicators = templateIndicatorMapper.selectListByTemplateId(templateId);
61   - List<MesQcIqcLineDO> lines = convertList(indicators, indicator -> new MesQcIqcLineDO()
62   - .setIqcId(iqcId).setIndicatorId(indicator.getIndicatorId())
63   - .setToolId(null) // TODO @芋艿:模板指标暂无 toolId,后续可扩展
64   - .setCheckMethod(indicator.getCheckMethod())
65   - .setStandardValue(indicator.getStandardValue()).setUnitMeasureId(indicator.getUnitMeasureId())
66   - .setMaxThreshold(indicator.getThresholdMax()).setMinThreshold(indicator.getThresholdMin())
67   - .setCriticalQuantity(0).setMajorQuantity(0).setMinorQuantity(0));
  67 + List<MesQcTemplateIndicatorDO> templateIndicators = templateIndicatorMapper.selectListByTemplateId(templateId);
  68 + if (CollUtil.isEmpty(templateIndicators)) {
  69 + return;
  70 + }
  71 + Map<Long, MesQcIndicatorDO> indicatorMap = indicatorService.getIndicatorMap(
  72 + convertSet(templateIndicators, MesQcTemplateIndicatorDO::getIndicatorId));
  73 + List<MesQcIqcLineDO> lines = convertList(templateIndicators, templateIndicator -> {
  74 + MesQcIndicatorDO indicator = indicatorMap.get(templateIndicator.getIndicatorId());
  75 + return new MesQcIqcLineDO()
  76 + .setIqcId(iqcId).setIndicatorId(templateIndicator.getIndicatorId())
  77 + .setTool(indicator != null ? indicator.getTool() : null)
  78 + .setCheckMethod(templateIndicator.getCheckMethod())
  79 + .setStandardValue(templateIndicator.getStandardValue()).setUnitMeasureId(templateIndicator.getUnitMeasureId())
  80 + .setMaxThreshold(templateIndicator.getThresholdMax()).setMinThreshold(templateIndicator.getThresholdMin())
  81 + .setCriticalQuantity(0).setMajorQuantity(0).setMinorQuantity(0);
  82 + });
68 83 iqcLineMapper.insertBatch(lines);
69 84 }
70 85  
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/iqc/MesQcIqcService.java
... ... @@ -22,16 +22,18 @@ public interface MesQcIqcService {
22 22 * 创建来料检验单
23 23 *
24 24 * @param createReqVO 创建信息
  25 + * @param inspectorUserId 检测人员用户 ID
25 26 * @return 编号
26 27 */
27   - Long createIqc(@Valid MesQcIqcSaveReqVO createReqVO);
  28 + Long createIqc(@Valid MesQcIqcSaveReqVO createReqVO, Long inspectorUserId);
28 29  
29 30 /**
30 31 * 更新来料检验单
31 32 *
32 33 * @param updateReqVO 更新信息
  34 + * @param inspectorUserId 检测人员用户 ID
33 35 */
34   - void updateIqc(@Valid MesQcIqcSaveReqVO updateReqVO);
  36 + void updateIqc(@Valid MesQcIqcSaveReqVO updateReqVO, Long inspectorUserId);
35 37  
36 38 /**
37 39 * 完成来料检验单
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/iqc/MesQcIqcServiceImpl.java
... ... @@ -4,11 +4,11 @@ import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.util.ObjUtil;
5 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  7 +import cn.hutool.core.util.ObjectUtil;
7 8 import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcPageReqVO;
8 9 import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcSaveReqVO;
9 10 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.defectrecord.MesQcDefectRecordDO;
10 11 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.iqc.MesQcIqcDO;
11   -import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateDO;
12 12 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateItemDO;
13 13 import cn.iocoder.yudao.module.mes.dal.mysql.qc.iqc.MesQcIqcMapper;
14 14 import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
... ... @@ -16,7 +16,7 @@ import cn.iocoder.yudao.module.mes.enums.qc.MesQcDefectLevelEnum;
16 16 import cn.iocoder.yudao.module.mes.enums.qc.MesQcIqcStatusEnum;
17 17 import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum;
18 18 import cn.iocoder.yudao.module.mes.service.qc.defectrecord.MesQcDefectRecordService;
19   -import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateService;
  19 +import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateDetailService;
20 20 import cn.iocoder.yudao.module.mes.service.wm.arrivalnotice.MesWmArrivalNoticeService;
21 21 import jakarta.annotation.Resource;
22 22 import org.springframework.stereotype.Service;
... ... @@ -44,7 +44,7 @@ public class MesQcIqcServiceImpl implements MesQcIqcService {
44 44 @Resource
45 45 private MesQcIqcMapper iqcMapper;
46 46 @Resource
47   - private MesQcTemplateService templateService;
  47 + private MesQcTemplateDetailService templateDetailService;
48 48  
49 49 @Resource
50 50 private MesQcIqcLineService iqcLineService;
... ... @@ -55,46 +55,42 @@ public class MesQcIqcServiceImpl implements MesQcIqcService {
55 55  
56 56 @Override
57 57 @Transactional(rollbackFor = Exception.class)
58   - public Long createIqc(MesQcIqcSaveReqVO createReqVO) {
  58 + public Long createIqc(MesQcIqcSaveReqVO createReqVO, Long inspectorUserId) {
59 59 // 1.1 校验编号唯一
60 60 validateIqcCodeUnique(null, createReqVO.getCode());
61   - // 1.2 查找物料关联的 IQC 检测模板
62   - Long templateId = createReqVO.getTemplateId();
63   - MesQcTemplateDO template = templateService.validateTemplateExists(templateId);
64   - if (!CollUtil.contains(template.getTypes(), MesQcTypeEnum.IQC.getType())) {
65   - throw exception(QC_IQC_NO_TEMPLATE);
66   - }
  61 + // 1.2 校验来源单据参数,并验证数据存在
  62 + validateSourceDoc(createReqVO.getSourceDocType(), createReqVO.getSourceDocId(), createReqVO.getSourceLineId());
  63 + // 1.3 通过 itemId + IQC 类型自动查找模板
  64 + MesQcTemplateItemDO templateItem = templateDetailService.getRequiredTemplateByItemIdAndType(
  65 + createReqVO.getItemId(), MesQcTypeEnum.IQC.getType());
  66 + Long templateId = templateItem.getTemplateId();
67 67  
68   - // 3.1 从模板的产品关联中获取检测参数(min_check_quantity、max_unqualified_quantity)
69   - MesQcTemplateItemDO templateItem = templateService.getTemplateItemByTemplateIdAndItemId(
70   - templateId, createReqVO.getItemId());
71   - if (templateItem != null) {
72   - if (createReqVO.getMinCheckQuantity() == null) {
73   - createReqVO.setMinCheckQuantity(templateItem.getQuantityCheck());
74   - }
75   - if (createReqVO.getMaxUnqualifiedQuantity() == null) {
76   - createReqVO.setMaxUnqualifiedQuantity(templateItem.getQuantityUnqualified());
77   - }
78   - }
79   - // 3.2 插入主表
  68 + // 2. 插入主表
80 69 MesQcIqcDO iqc = BeanUtils.toBean(createReqVO, MesQcIqcDO.class);
  70 + iqc.setTemplateId(templateId);
  71 + iqc.setCheckQuantity(createReqVO.getQualifiedQuantity().add(createReqVO.getUnqualifiedQuantity()));
  72 + iqc.setInspectorUserId(inspectorUserId);
81 73 iqc.setStatus(MesQcIqcStatusEnum.PREPARE.getType());
82 74 iqcMapper.insert(iqc);
83 75  
84   - // 4. 从模板指标自动生成检验行
  76 + // 3. 从模板指标自动生成检验行
85 77 iqcLineService.createLinesFromTemplate(iqc.getId(), templateId);
86 78 return iqc.getId();
87 79 }
88 80  
89 81 @Override
90   - public void updateIqc(MesQcIqcSaveReqVO updateReqVO) {
  82 + public void updateIqc(MesQcIqcSaveReqVO updateReqVO, Long inspectorUserId) {
91 83 // 1.1 校验存在 + 草稿状态
92 84 validateIqcStatusPrepare(updateReqVO.getId());
93 85 // 1.2 校验编号唯一
94 86 validateIqcCodeUnique(updateReqVO.getId(), updateReqVO.getCode());
95 87  
96   - // 2. 更新
  88 + // 2. 更新主表
97 89 MesQcIqcDO updateObj = BeanUtils.toBean(updateReqVO, MesQcIqcDO.class);
  90 + updateObj.setSourceDocType(null).setSourceDocId(null).setSourceLineId(null); // 不允许修改来源单据
  91 + updateObj.setTemplateId(null); // 不允许修改模板
  92 + updateObj.setCheckQuantity(updateReqVO.getQualifiedQuantity().add(updateReqVO.getUnqualifiedQuantity()));
  93 + updateObj.setInspectorUserId(inspectorUserId);
98 94 iqcMapper.updateById(updateObj);
99 95 }
100 96  
... ... @@ -102,14 +98,11 @@ public class MesQcIqcServiceImpl implements MesQcIqcService {
102 98 public void completeIqc(Long id) {
103 99 // 1.1 校验存在 + 草稿状态
104 100 MesQcIqcDO iqc = validateIqcStatusPrepare(id);
105   - // 1.2 校验合格品 + 不合格品 = 检测数量
106   - if (iqc.getCheckQuantity() != null && iqc.getCheckQuantity().compareTo(BigDecimal.ZERO) > 0) {
107   - BigDecimal total = ObjUtil.defaultIfNull(iqc.getQualifiedQuantity(), BigDecimal.ZERO)
108   - .add(ObjUtil.defaultIfNull(iqc.getUnqualifiedQuantity(), BigDecimal.ZERO));
109   - if (total.compareTo(iqc.getCheckQuantity()) != 0) {
110   - throw exception(QC_IQC_QUANTITY_MISMATCH);
111   - }
  101 + // DONE @AI:已修复,增加 checkResult 必填校验
  102 + if (iqc.getCheckResult() == null) {
  103 + throw exception(QC_IQC_CHECK_RESULT_EMPTY);
112 104 }
  105 + // DONE @AI:已修复,数量校验已在 MesQcIqcSaveReqVO 的 @AssertTrue 中保证,此处移除
113 106  
114 107 // 2. 更新状态为已完成
115 108 MesQcIqcDO updateObj = new MesQcIqcDO()
... ... @@ -130,7 +123,8 @@ public class MesQcIqcServiceImpl implements MesQcIqcService {
130 123 if (iqc.getSourceDocType() == null) {
131 124 return;
132 125 }
133   - if (iqc.getSourceLineId() == null || iqc.getSourceDocId() == null) {
  126 + // DONE @AI:已修复,使用 ObjectUtil.hasNull() 简化判断
  127 + if (ObjectUtil.hasNull(iqc.getSourceLineId(), iqc.getSourceDocId())) {
134 128 throw new IllegalArgumentException(
135 129 "IQC 单[" + iqc.getId() + "] sourceDocType 非空但 sourceLineId 或 sourceDocId 为空");
136 130 }
... ... @@ -152,9 +146,9 @@ public class MesQcIqcServiceImpl implements MesQcIqcService {
152 146 // 2.1 删除主表
153 147 iqcMapper.deleteById(id);
154 148 // 2.2 级联删除行
155   - iqcLineService.deleteByIqcId(id);
  149 + iqcLineService.deleteListByIqcId(id);
156 150 // 2.3 级联删除缺陷记录
157   - defectRecordService.deleteByQcTypeAndQcId(MesQcTypeEnum.IQC.getType(), id);
  151 + defectRecordService.deleteListByQcTypeAndQcId(MesQcTypeEnum.IQC.getType(), id);
158 152 }
159 153  
160 154 @Override
... ... @@ -190,6 +184,26 @@ public class MesQcIqcServiceImpl implements MesQcIqcService {
190 184 }
191 185 }
192 186  
  187 + /**
  188 + * 校验来源单据参数,并验证数据存在
  189 + *
  190 + * @param sourceDocType 来源单据类型
  191 + * @param sourceDocId 来源单据 ID
  192 + * @param sourceLineId 来源单据行 ID
  193 + */
  194 + private void validateSourceDoc(Integer sourceDocType, Long sourceDocId, Long sourceLineId) {
  195 + if (sourceDocType == null) {
  196 + return;
  197 + }
  198 + if (ObjUtil.hasNull(sourceDocId, sourceLineId)) {
  199 + throw exception(QC_IQC_SOURCE_DOC_PARAMS_MISSING);
  200 + }
  201 + // 根据来源单据类型,校验数据存在且匹配
  202 + if (Objects.equals(sourceDocType, MesBizTypeConstants.WM_ARRIVAL_NOTICE)) {
  203 + arrivalNoticeService.validateArrivalNoticeAndLineExists(sourceDocId, sourceLineId);
  204 + }
  205 + }
  206 +
193 207 @Override
194 208 public MesQcIqcDO getIqc(Long id) {
195 209 return iqcMapper.selectById(id);
... ... @@ -246,7 +260,7 @@ public class MesQcIqcServiceImpl implements MesQcIqcService {
246 260 if (CollUtil.isEmpty(ids)) {
247 261 return Collections.emptyMap();
248 262 }
249   - List<MesQcIqcDO> list = iqcMapper.selectBatchIds(ids);
  263 + List<MesQcIqcDO> list = iqcMapper.selectByIds(ids);
250 264 return convertMap(list, MesQcIqcDO::getId);
251 265 }
252 266  
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeService.java
... ... @@ -93,6 +93,14 @@ public interface MesWmArrivalNoticeService {
93 93 }
94 94  
95 95 /**
  96 + * 校验到货通知单和行存在,且行属于该通知单
  97 + *
  98 + * @param noticeId 到货通知单 ID
  99 + * @param lineId 到货通知单行 ID
  100 + */
  101 + void validateArrivalNoticeAndLineExists(Long noticeId, Long lineId);
  102 +
  103 + /**
96 104 * 按状态获得到货通知单列表
97 105 *
98 106 * @param status 状态
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeServiceImpl.java
... ... @@ -21,6 +21,7 @@ import java.math.BigDecimal;
21 21 import java.util.Collection;
22 22 import java.util.Collections;
23 23 import java.util.List;
  24 +import java.util.Objects;
24 25  
25 26 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
26 27 import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
... ... @@ -166,6 +167,24 @@ public class MesWmArrivalNoticeServiceImpl implements MesWmArrivalNoticeService
166 167 return arrivalNoticeMapper.selectListByStatus(status);
167 168 }
168 169  
  170 + @Override
  171 + public void validateArrivalNoticeAndLineExists(Long noticeId, Long lineId) {
  172 + // 1. 校验通知单存在
  173 + MesWmArrivalNoticeDO notice = arrivalNoticeMapper.selectById(noticeId);
  174 + if (notice == null) {
  175 + throw exception(WM_ARRIVAL_NOTICE_NOT_EXISTS);
  176 + }
  177 + // 2.1 校验行存在
  178 + MesWmArrivalNoticeLineDO line = arrivalNoticeLineService.getArrivalNoticeLine(lineId);
  179 + if (line == null) {
  180 + throw exception(WM_ARRIVAL_NOTICE_LINE_NOT_EXISTS);
  181 + }
  182 + // 2.2 校验行属于该通知单
  183 + if (ObjUtil.notEqual(line.getNoticeId(), noticeId)) {
  184 + throw exception(WM_ARRIVAL_NOTICE_LINE_NOT_EXISTS);
  185 + }
  186 + }
  187 +
169 188 private MesWmArrivalNoticeDO validateArrivalNoticeExists(Long id) {
170 189 MesWmArrivalNoticeDO notice = arrivalNoticeMapper.selectById(id);
171 190 if (notice == null) {
... ...