diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/vo/MesQcOqcPageReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/vo/MesQcOqcPageReqVO.java index 001a345..63e14d1 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/vo/MesQcOqcPageReqVO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/vo/MesQcOqcPageReqVO.java @@ -5,11 +5,6 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -import org.springframework.format.annotation.DateTimeFormat; - -import java.time.LocalDateTime; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; @Schema(description = "管理后台 - MES 出货检验单分页 Request VO") @Data @@ -38,12 +33,4 @@ public class MesQcOqcPageReqVO extends PageParam { @Schema(description = "检测人员用户 ID", example = "1") private Long inspectorUserId; - @Schema(description = "出货日期") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime[] outDate; - - @Schema(description = "检测日期") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime[] inspectDate; - } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/vo/MesQcOqcSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/vo/MesQcOqcSaveReqVO.java index 19fc59c..168df21 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/vo/MesQcOqcSaveReqVO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/vo/MesQcOqcSaveReqVO.java @@ -1,8 +1,9 @@ package cn.iocoder.yudao.module.mes.controller.admin.qc.oqc.vo; +import cn.hutool.core.util.ObjUtil; +import com.fasterxml.jackson.annotation.JsonIgnore; import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.*; import lombok.Data; import java.math.BigDecimal; @@ -23,10 +24,6 @@ public class MesQcOqcSaveReqVO { @NotEmpty(message = "检验单名称不能为空") private String name; - @Schema(description = "检验模板 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") - @NotNull(message = "检验模板不能为空") - private Long templateId; - // ========== 来源单据 ========== @Schema(description = "来源单据 ID", example = "200") @@ -58,43 +55,53 @@ public class MesQcOqcSaveReqVO { // ========== 数量 ========== - // TODO @AI:这 2 个字段去掉,minCheckQuantity、maxUnqualifiedQuantity;前后端都是; - @Schema(description = "最低检测数", example = "5") - private Integer minCheckQuantity; - - @Schema(description = "最大不合格数", example = "0") - private Integer maxUnqualifiedQuantity; - @Schema(description = "本次出货数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") @NotNull(message = "本次出货数量不能为空") + @DecimalMin(value = "0", message = "本次出货数量不能小于 0") private BigDecimal outQuantity; - // TODO @AI:checkQuantity = qualifiedQuantity + unqualifiedQuantity;校验下相等;必须的;参考 iqc - - @Schema(description = "本次检测数量", example = "10") + @Schema(description = "本次检测数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") + @NotNull(message = "本次检测数量不能为空") + @Min(value = 1, message = "本次检测数量必须大于 0") private Integer checkQuantity; - @Schema(description = "合格品数量", example = "9") + @Schema(description = "合格品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "9") + @NotNull(message = "合格品数量不能为空") + @Min(value = 0, message = "合格品数量不能小于 0") private Integer qualifiedQuantity; - @Schema(description = "不合格品数量", example = "1") + @Schema(description = "不合格品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "不合格品数量不能为空") + @Min(value = 0, message = "不合格品数量不能小于 0") private Integer unqualifiedQuantity; // ========== 检验 ========== - @Schema(description = "检测结果", example = "1") - private Integer checkResult; + @Schema(description = "检测人员用户 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "检测人员不能为空") + private Long inspectorUserId; - @Schema(description = "出货日期") + @Schema(description = "出货日期", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "出货日期不能为空") private LocalDateTime outDate; - @Schema(description = "检测日期") + @Schema(description = "检测日期", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "检测日期不能为空") private LocalDateTime inspectDate; - @Schema(description = "检测人员用户 ID", example = "1") - private Long inspectorUserId; + @Schema(description = "检测结果", example = "1") + private Integer checkResult; @Schema(description = "备注", example = "备注") private String remark; + @AssertTrue(message = "检测数量必须等于合格品数量与不合格品数量之和") + @JsonIgnore + public boolean isQuantityValid() { + if (ObjUtil.hasNull(checkQuantity, qualifiedQuantity, unqualifiedQuantity)) { + return true; // @NotNull 会处理 null + } + return checkQuantity.equals(qualifiedQuantity + unqualifiedQuantity); + } + } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/indicatorresult/MesQcIndicatorResultDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/indicatorresult/MesQcIndicatorResultDO.java index 7feb5a6..e6e376d 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/indicatorresult/MesQcIndicatorResultDO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/indicatorresult/MesQcIndicatorResultDO.java @@ -2,7 +2,10 @@ package cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicatorresult; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.ipqc.MesQcIpqcDO; import cn.iocoder.yudao.module.mes.dal.dataobject.qc.iqc.MesQcIqcDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.oqc.MesQcOqcDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.rqc.MesQcRqcDO; import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; @@ -37,7 +40,9 @@ public class MesQcIndicatorResultDO extends BaseDO { * 关联质检单 ID(IQC/IPQC/OQC/RQC 的 id) * * 关联 IQC {@link MesQcIqcDO#getId()} - * TODO @芋艿:IPQC/OQC/RQC 关联补充 + * 关联 IPQC {@link MesQcIpqcDO#getId()} + * 关联 OQC {@link MesQcOqcDO#getId()} + * 关联 RQC {@link MesQcRqcDO#getId()} */ private Long qcId; /** diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/oqc/MesQcOqcDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/oqc/MesQcOqcDO.java index 766bf64..b1f8253 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/oqc/MesQcOqcDO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/oqc/MesQcOqcDO.java @@ -91,14 +91,6 @@ public class MesQcOqcDO extends BaseDO { // ========== 数量 ========== /** - * 最低检测数 - */ - private Integer minCheckQuantity; - /** - * 最大不合格数 - */ - private Integer maxUnqualifiedQuantity; - /** * 本次出货数量 */ private BigDecimal outQuantity; diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/oqc/MesQcOqcLineDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/oqc/MesQcOqcLineDO.java index 1c23d12..f621dc0 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/oqc/MesQcOqcLineDO.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/oqc/MesQcOqcLineDO.java @@ -43,6 +43,12 @@ public class MesQcOqcLineDO extends BaseDO { */ private Long indicatorId; /** + * 检测工具 + * + * 冗余 {@link MesQcIndicatorDO#getTool()} + */ + private String tool; + /** * 检测方法 */ private String checkMethod; diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/client/MesMdClientService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/client/MesMdClientService.java index 1b0aae6..2038ce4 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/client/MesMdClientService.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/client/MesMdClientService.java @@ -86,6 +86,13 @@ public interface MesMdClientService { } /** + * 校验客户是否存在 + * + * @param id 编号 + */ + void validateClientExists(Long id); + + /** * 批量导入客户 * * @param importClients 导入客户列表 diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/client/MesMdClientServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/client/MesMdClientServiceImpl.java index 63dfb28..ab07dab 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/client/MesMdClientServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/client/MesMdClientServiceImpl.java @@ -79,7 +79,8 @@ public class MesMdClientServiceImpl implements MesMdClientService { clientMapper.deleteById(id); } - private void validateClientExists(Long id) { + @Override + public void validateClientExists(Long id) { if (clientMapper.selectById(id) == null) { throw exception(MD_CLIENT_NOT_EXISTS); } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImpl.java index 6ab589c..04316fc 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImpl.java @@ -70,15 +70,12 @@ public class MesQcIpqcServiceImpl implements MesQcIpqcService { public Long createIpqc(MesQcIpqcSaveReqVO createReqVO) { // 1.1 校验编号唯一 validateIpqcCodeUnique(null, createReqVO.getCode()); - // 1.2 校验工单存在 + // 1.2 校验工单、工位、检测人员、物料存在 MesProWorkOrderDO workOrder = workOrderService.validateWorkOrderExists(createReqVO.getWorkOrderId()); - // 1.3 校验工位存在 workstationService.validateWorkstationExists(createReqVO.getWorkstationId()); - // 1.4 校验检测人员存在 adminUserApi.validateUser(createReqVO.getInspectorUserId()); - // 1.5 校验物料存在 itemService.validateItemExists(createReqVO.getItemId()); - // 1.6 根据产品 + 检验类型自动匹配模板 + // 1.3 根据产品 + 检验类型自动匹配模板 MesQcTemplateItemDO templateItem = templateDetailService.getRequiredTemplateByItemIdAndType( workOrder.getProductId(), MesQcTypeEnum.IPQC.getType()); Long templateId = templateItem.getTemplateId(); @@ -101,13 +98,10 @@ public class MesQcIpqcServiceImpl implements MesQcIpqcService { validateIpqcStatusPrepare(updateReqVO.getId()); // 1.2 校验编号唯一 validateIpqcCodeUnique(updateReqVO.getId(), updateReqVO.getCode()); - // 1.3 校验工单存在 + // 1.3 校验工单、工位、检测人员、物料存在 workOrderService.validateWorkOrderExists(updateReqVO.getWorkOrderId()); - // 1.4 校验工位存在 workstationService.validateWorkstationExists(updateReqVO.getWorkstationId()); - // 1.5 校验检测人员存在 adminUserApi.validateUser(updateReqVO.getInspectorUserId()); - // 1.6 校验物料存在 itemService.validateItemExists(updateReqVO.getItemId()); // 2. 更新 @@ -225,8 +219,7 @@ public class MesQcIpqcServiceImpl implements MesQcIpqcService { minorRate = BigDecimal.valueOf(totalMinor).multiply(BigDecimal.valueOf(100)) .divide(checkQty, 2, RoundingMode.HALF_UP); } - - // 3. 更新主表 + // 2.3 更新主表 MesQcIpqcDO updateIpqc = new MesQcIpqcDO().setId(ipqcId) .setCriticalQuantity(totalCritical).setMajorQuantity(totalMajor).setMinorQuantity(totalMinor) .setCriticalRate(criticalRate).setMajorRate(majorRate).setMinorRate(minorRate); diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/iqc/MesQcIqcServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/iqc/MesQcIqcServiceImpl.java index 0537d22..52e2b30 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/iqc/MesQcIqcServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/iqc/MesQcIqcServiceImpl.java @@ -68,14 +68,13 @@ public class MesQcIqcServiceImpl implements MesQcIqcService { public Long createIqc(MesQcIqcSaveReqVO createReqVO) { // 1.1 校验编号唯一 validateIqcCodeUnique(null, createReqVO.getCode()); - // 1.2 校验供应商、物料存在 + // 1.2 校验供应商、物料、检测人员存在 vendorService.validateVendorExists(createReqVO.getVendorId()); itemService.validateItemExists(createReqVO.getItemId()); - // 1.3 校验检测人员存在 adminUserApi.validateUser(createReqVO.getInspectorUserId()); - // 1.4 校验来源单据参数,并验证数据存在 + // 1.3 校验来源单据参数,并验证数据存在 validateSourceDoc(createReqVO.getSourceDocType(), createReqVO.getSourceDocId(), createReqVO.getSourceLineId()); - // 1.5 通过 itemId + IQC 类型自动查找模板 + // 1.4 通过 itemId + IQC 类型自动查找模板 MesQcTemplateItemDO templateItem = templateDetailService.getRequiredTemplateByItemIdAndType( createReqVO.getItemId(), MesQcTypeEnum.IQC.getType()); Long templateId = templateItem.getTemplateId(); @@ -98,10 +97,9 @@ public class MesQcIqcServiceImpl implements MesQcIqcService { validateIqcStatusPrepare(updateReqVO.getId()); // 1.2 校验编号唯一 validateIqcCodeUnique(updateReqVO.getId(), updateReqVO.getCode()); - // 1.3 校验供应商、物料存在 + // 1.3 校验供应商、物料、检测人员存在 vendorService.validateVendorExists(updateReqVO.getVendorId()); itemService.validateItemExists(updateReqVO.getItemId()); - // 1.4 校验检测人员存在 adminUserApi.validateUser(updateReqVO.getInspectorUserId()); // 2. 更新主表 @@ -264,8 +262,7 @@ public class MesQcIqcServiceImpl implements MesQcIqcService { minorRate = BigDecimal.valueOf(totalMinor).multiply(BigDecimal.valueOf(100)) .divide(checkQty, 2, RoundingMode.HALF_UP); } - - // 3. 更新主表 + // 2.3 更新主表 MesQcIqcDO updateIqc = new MesQcIqcDO().setId(iqcId) .setCriticalQuantity(totalCritical).setMajorQuantity(totalMajor).setMinorQuantity(totalMinor) .setCriticalRate(criticalRate).setMajorRate(majorRate).setMinorRate(minorRate); diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/oqc/MesQcOqcLineServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/oqc/MesQcOqcLineServiceImpl.java index 34566e4..e4f02ff 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/oqc/MesQcOqcLineServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/oqc/MesQcOqcLineServiceImpl.java @@ -5,21 +5,25 @@ import cn.hutool.core.util.ObjUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.mes.controller.admin.qc.oqc.vo.line.MesQcOqcLinePageReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.qc.defectrecord.MesQcDefectRecordDO; +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicator.MesQcIndicatorDO; import cn.iocoder.yudao.module.mes.dal.dataobject.qc.oqc.MesQcOqcLineDO; import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateIndicatorDO; import cn.iocoder.yudao.module.mes.dal.mysql.qc.oqc.MesQcOqcLineMapper; import cn.iocoder.yudao.module.mes.dal.mysql.qc.template.MesQcTemplateIndicatorMapper; import cn.iocoder.yudao.module.mes.enums.qc.MesQcDefectLevelEnum; +import cn.iocoder.yudao.module.mes.service.qc.indicator.MesQcIndicatorService; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; /** @@ -35,6 +39,8 @@ public class MesQcOqcLineServiceImpl implements MesQcOqcLineService { private MesQcOqcLineMapper oqcLineMapper; @Resource private MesQcTemplateIndicatorMapper templateIndicatorMapper; + @Resource + private MesQcIndicatorService indicatorService; @Override public MesQcOqcLineDO validateOqcLineExists(Long id) { @@ -57,14 +63,22 @@ public class MesQcOqcLineServiceImpl implements MesQcOqcLineService { @Override public void createLinesFromTemplate(Long oqcId, Long templateId) { - // TODO @AI:tool 存储 - List indicators = templateIndicatorMapper.selectListByTemplateId(templateId); - List lines = convertList(indicators, indicator -> new MesQcOqcLineDO() - .setOqcId(oqcId).setIndicatorId(indicator.getIndicatorId()) - .setCheckMethod(indicator.getCheckMethod()) - .setStandardValue(indicator.getStandardValue()).setUnitMeasureId(indicator.getUnitMeasureId()) - .setMaxThreshold(indicator.getThresholdMax()).setMinThreshold(indicator.getThresholdMin()) - .setCriticalQuantity(0).setMajorQuantity(0).setMinorQuantity(0)); + List templateIndicators = templateIndicatorMapper.selectListByTemplateId(templateId); + if (CollUtil.isEmpty(templateIndicators)) { + return; + } + Map indicatorMap = indicatorService.getIndicatorMap( + convertSet(templateIndicators, MesQcTemplateIndicatorDO::getIndicatorId)); + List lines = convertList(templateIndicators, templateIndicator -> { + MesQcIndicatorDO indicator = indicatorMap.get(templateIndicator.getIndicatorId()); + return new MesQcOqcLineDO() + .setOqcId(oqcId).setIndicatorId(templateIndicator.getIndicatorId()) + .setTool(indicator != null ? indicator.getTool() : null) + .setCheckMethod(templateIndicator.getCheckMethod()) + .setStandardValue(templateIndicator.getStandardValue()).setUnitMeasureId(templateIndicator.getUnitMeasureId()) + .setMaxThreshold(templateIndicator.getThresholdMax()).setMinThreshold(templateIndicator.getThresholdMin()) + .setCriticalQuantity(0).setMajorQuantity(0).setMinorQuantity(0); + }); oqcLineMapper.insertBatch(lines); } diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/oqc/MesQcOqcServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/oqc/MesQcOqcServiceImpl.java index 6138796..6991088 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/oqc/MesQcOqcServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/oqc/MesQcOqcServiceImpl.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.mes.service.qc.oqc; -import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; @@ -8,15 +7,16 @@ import cn.iocoder.yudao.module.mes.controller.admin.qc.oqc.vo.MesQcOqcPageReqVO; import cn.iocoder.yudao.module.mes.controller.admin.qc.oqc.vo.MesQcOqcSaveReqVO; import cn.iocoder.yudao.module.mes.dal.dataobject.qc.defectrecord.MesQcDefectRecordDO; import cn.iocoder.yudao.module.mes.dal.dataobject.qc.oqc.MesQcOqcDO; -import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateDO; import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateItemDO; import cn.iocoder.yudao.module.mes.dal.mysql.qc.oqc.MesQcOqcMapper; import cn.iocoder.yudao.module.mes.enums.qc.MesQcDefectLevelEnum; import cn.iocoder.yudao.module.mes.enums.qc.MesQcOqcStatusEnum; import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum; +import cn.iocoder.yudao.module.mes.service.md.client.MesMdClientService; +import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; import cn.iocoder.yudao.module.mes.service.qc.defectrecord.MesQcDefectRecordService; import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateDetailService; -import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateService; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import jakarta.annotation.Resource; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; @@ -43,45 +43,38 @@ public class MesQcOqcServiceImpl implements MesQcOqcService { @Resource private MesQcOqcMapper oqcMapper; @Resource - private MesQcTemplateService templateService; - @Resource private MesQcTemplateDetailService templateDetailService; @Resource private MesQcOqcLineService oqcLineService; @Resource @Lazy private MesQcDefectRecordService defectRecordService; + @Resource + @Lazy + private MesMdClientService clientService; + @Resource + @Lazy + private MesMdItemService itemService; + @Resource + private AdminUserApi adminUserApi; @Override @Transactional(rollbackFor = Exception.class) public Long createOqc(MesQcOqcSaveReqVO createReqVO) { // 1.1 校验编号唯一 validateOqcCodeUnique(null, createReqVO.getCode()); - // TODO @AI:关联字段的校验! - // 1.2 校验模板存在且包含 OQC 类型 - // TODO @AI:不用前端传递,而是类似 iqc 后端计算 - Long templateId = createReqVO.getTemplateId(); - MesQcTemplateDO template = templateService.validateTemplateExists(templateId); - if (!CollUtil.contains(template.getTypes(), MesQcTypeEnum.OQC.getType())) { - throw exception(QC_OQC_NO_TEMPLATE); - } - - // 1.3 从模板的产品关联中获取检测参数 - // TODO @芋艿:【暂时不用删除】到底 miniCheckQuantity 和 maxUnqualifiedQuantity 是否有必要存储? - // TODO @AI:去掉这 2 个字段的设置,包括数据的存储,也去掉! - MesQcTemplateItemDO templateItem = templateDetailService.getTemplateItemByTemplateIdAndItemId( - templateId, createReqVO.getItemId()); - if (templateItem != null) { - if (createReqVO.getMinCheckQuantity() == null) { - createReqVO.setMinCheckQuantity(templateItem.getQuantityCheck()); - } - if (createReqVO.getMaxUnqualifiedQuantity() == null) { - createReqVO.setMaxUnqualifiedQuantity(templateItem.getQuantityUnqualified()); - } - } + // 1.2 校验客户、物料、检测人员存在 + clientService.validateClientExists(createReqVO.getClientId()); + itemService.validateItemExists(createReqVO.getItemId()); + adminUserApi.validateUser(createReqVO.getInspectorUserId()); + // 1.3 根据产品 + 检验类型自动匹配模板 + MesQcTemplateItemDO templateItem = templateDetailService.getRequiredTemplateByItemIdAndType( + createReqVO.getItemId(), MesQcTypeEnum.OQC.getType()); + Long templateId = templateItem.getTemplateId(); // 2. 插入主表 MesQcOqcDO oqc = BeanUtils.toBean(createReqVO, MesQcOqcDO.class); + oqc.setTemplateId(templateId); oqc.setStatus(MesQcOqcStatusEnum.PREPARE.getType()); oqcMapper.insert(oqc); @@ -96,6 +89,10 @@ public class MesQcOqcServiceImpl implements MesQcOqcService { validateOqcStatusPrepare(updateReqVO.getId()); // 1.2 校验编号唯一 validateOqcCodeUnique(updateReqVO.getId(), updateReqVO.getCode()); + // 1.3 校验客户、物料、检测人员存在 + clientService.validateClientExists(updateReqVO.getClientId()); + itemService.validateItemExists(updateReqVO.getItemId()); + adminUserApi.validateUser(updateReqVO.getInspectorUserId()); // 2. 更新 MesQcOqcDO updateObj = BeanUtils.toBean(updateReqVO, MesQcOqcDO.class); @@ -104,16 +101,8 @@ public class MesQcOqcServiceImpl implements MesQcOqcService { @Override public void completeOqc(Long id) { - // 1.1 校验存在 + 草稿状态 - MesQcOqcDO oqc = validateOqcStatusPrepare(id); - // 1.2 校验合格品 + 不合格品 = 检测数量 - if (oqc.getCheckQuantity() != null && oqc.getCheckQuantity() > 0) { - int total = (oqc.getQualifiedQuantity() != null ? oqc.getQualifiedQuantity() : 0) - + (oqc.getUnqualifiedQuantity() != null ? oqc.getUnqualifiedQuantity() : 0); - if (total != oqc.getCheckQuantity()) { - throw exception(QC_OQC_QUANTITY_MISMATCH); - } - } + // 1. 校验存在 + 草稿状态 + validateOqcStatusPrepare(id); // 2. 更新状态为已完成 MesQcOqcDO updateObj = new MesQcOqcDO() @@ -210,8 +199,7 @@ public class MesQcOqcServiceImpl implements MesQcOqcService { minorRate = BigDecimal.valueOf(totalMinor).multiply(BigDecimal.valueOf(100)) .divide(checkQty, 2, RoundingMode.HALF_UP); } - - // 3. 更新主表 + // 2.3 更新主表 MesQcOqcDO updateOqc = new MesQcOqcDO().setId(oqcId) .setCriticalQuantity(totalCritical).setMajorQuantity(totalMajor).setMinorQuantity(totalMinor) .setCriticalRate(criticalRate).setMajorRate(majorRate).setMinorRate(minorRate); diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/rqc/MesQcRqcServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/rqc/MesQcRqcServiceImpl.java index 2d1d27c..ce20f02 100644 --- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/rqc/MesQcRqcServiceImpl.java +++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/rqc/MesQcRqcServiceImpl.java @@ -162,6 +162,8 @@ public class MesQcRqcServiceImpl implements MesQcRqcService { public void recalculateDefectStats(Long rqcId, List records) { // RQC 只更新行级缺陷统计,主表不存储缺陷统计字段 rqcLineService.recalculateLineDefectStats(rqcId, records); + + // TODO @AI:还是对齐其他的 } }