ソースを参照

✨ feat(mes): 增加 IPQC 相关错误码和校验逻辑

新增 IPQC 相关的错误码,增强了对来源报工单的校验逻辑,确保在创建 IPQC 时,来源报工单存在待检产出行,并且来源单据行属于该报工单。
YunaiV 3 ヶ月 前
コミット
5b61d1be88

+ 2 - 0
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java

@@ -347,6 +347,8 @@ public interface ErrorCodeConstants {
     ErrorCode QC_IPQC_NO_TEMPLATE = new ErrorCode(1_040_604_005, "当前产品未配置 IPQC 检测模板");
     ErrorCode QC_IPQC_CHECK_RESULT_EMPTY = new ErrorCode(1_040_604_006, "完成检验单前,检测结果必须填写");
     ErrorCode QC_IPQC_SOURCE_DOC_TYPE_UNKNOWN = new ErrorCode(1_040_604_007, "未知的 IPQC 来源单据类型");
+    ErrorCode QC_IPQC_SOURCE_DOC_NO_PENDING_LINE = new ErrorCode(1_040_604_008, "来源报工单不存在待检产出行,无法创建 IPQC");
+    ErrorCode QC_IPQC_SOURCE_LINE_NOT_BELONG = new ErrorCode(1_040_604_009, "来源单据行不属于该报工单");
     // ========== MES 质量管理-过程检验行(1-040-604-100) ==========
     ErrorCode QC_IPQC_LINE_NOT_EXISTS = new ErrorCode(1_040_604_100, "过程检验行不存在");
 

+ 12 - 1
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/indicatorresult/MesQcIndicatorResultServiceImpl.java

@@ -21,6 +21,7 @@ import cn.iocoder.yudao.module.mes.service.qc.ipqc.MesQcIpqcService;
 import cn.iocoder.yudao.module.mes.service.qc.iqc.MesQcIqcService;
 import cn.iocoder.yudao.module.mes.service.qc.oqc.MesQcOqcService;
 import cn.iocoder.yudao.module.mes.service.qc.rqc.MesQcRqcService;
+import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
 import jakarta.annotation.Resource;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
@@ -62,6 +63,9 @@ public class MesQcIndicatorResultServiceImpl implements MesQcIndicatorResultServ
     @Lazy
     private MesQcRqcService rqcService;
 
+    @Resource
+    private DictDataApi dictDataApi;
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Long createIndicatorResult(MesQcIndicatorResultSaveReqVO createReqVO) {
@@ -208,7 +212,14 @@ public class MesQcIndicatorResultServiceImpl implements MesQcIndicatorResultServ
                             "检测项[" + indicator.getName() + "]要求整数,实际值=" + item.getValue());
                 }
             }
-            // TEXT / DICT / FILE 不做格式校验
+            // DICT:校验值属于对应字典类型
+            if (Objects.equals(resultType, MesQcResultValueTypeEnum.DICT.getType())) {
+                String dictType = indicator.getResultSpecification();
+                if (StrUtil.isNotBlank(dictType)) {
+                    dictDataApi.validateDictDataList(dictType, Collections.singleton(item.getValue()));
+                }
+            }
+            // FILE / TEXT 不做格式校验
         }
     }
 

+ 23 - 2
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImpl.java

@@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.mes.service.qc.ipqc;
 import cn.hutool.core.util.ObjUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productproduce.MesWmProductProduceLineDO;
+import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcPageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcSaveReqVO;
@@ -29,6 +31,7 @@ import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
 import cn.iocoder.yudao.module.mes.service.qc.defectrecord.MesQcDefectRecordService;
 import cn.iocoder.yudao.module.mes.service.qc.indicatorresult.MesQcIndicatorResultService;
 import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateItemService;
+import cn.iocoder.yudao.module.mes.service.wm.productproduce.MesWmProductProduceLineService;
 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
 import jakarta.annotation.Resource;
 import org.springframework.context.annotation.Lazy;
@@ -88,6 +91,9 @@ public class MesQcIpqcServiceImpl implements MesQcIpqcService {
     @Resource
     @Lazy
     private MesQcIndicatorResultService indicatorResultService;
+    @Resource
+    @Lazy
+    private MesWmProductProduceLineService productProduceLineService;
 
     @Resource
     private AdminUserApi adminUserApi;
@@ -105,7 +111,7 @@ public class MesQcIpqcServiceImpl implements MesQcIpqcService {
         Long templateId = templateItem.getTemplateId();
         // 1.4 获取来源单据编号
         String sourceDocCode = validateAndGetSourceDocCode(
-                createReqVO.getSourceDocType(), createReqVO.getSourceDocId());
+                createReqVO.getSourceDocType(), createReqVO.getSourceDocId(), createReqVO.getSourceLineId());
 
         // 2. 插入主表
         MesQcIpqcDO ipqc = BeanUtils.toBean(createReqVO, MesQcIpqcDO.class)
@@ -274,12 +280,27 @@ public class MesQcIpqcServiceImpl implements MesQcIpqcService {
         }
     }
 
-    private String validateAndGetSourceDocCode(Integer sourceDocType, Long sourceDocId) {
+    private String validateAndGetSourceDocCode(Integer sourceDocType, Long sourceDocId, Long sourceLineId) {
         if (sourceDocType == null || sourceDocId == null) {
             return null;
         }
         if (Objects.equals(sourceDocType, MesBizTypeConstants.PRO_FEEDBACK)) {
             MesProFeedbackDO feedback = feedbackService.validateFeedbackExists(sourceDocId);
+            // 校验该报工存在待检产出行
+            List<MesWmProductProduceLineDO> lines = productProduceLineService
+                    .getProductProduceLineListByFeedbackId(sourceDocId);
+            boolean hasPending = lines.stream().anyMatch(
+                    l -> Objects.equals(l.getQualityStatus(), MesWmQualityStatusEnum.PENDING.getStatus()));
+            if (!hasPending) {
+                throw exception(QC_IPQC_SOURCE_DOC_NO_PENDING_LINE);
+            }
+            // 校验 sourceLineId 属于该报工的产出行
+            if (sourceLineId != null) {
+                boolean belongs = lines.stream().anyMatch(l -> Objects.equals(l.getId(), sourceLineId));
+                if (!belongs) {
+                    throw exception(QC_IPQC_SOURCE_LINE_NOT_BELONG);
+                }
+            }
             return feedback.getCode();
         }
         // 未知来源类型应报错,而不是静默忽略