| | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| | | import cn.iocoder.yudao.framework.common.exception.ServiceException; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | |
| | | import cn.iocoder.yudao.module.mes.service.qc.imports.MesQcImportHelper; |
| | | 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.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.qc.template.MesQcTemplateService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.productsales.MesWmProductSalesLineService; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.ncr.vo.MesQcNcrSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.service.qc.ncr.MesQcNcrService; |
| | |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesLineDO; |
| | | import cn.iocoder.yudao.module.crm.api.customer.CrmCustomerApi; |
| | | import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; |
| | | import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; |
| | | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.context.annotation.Lazy; |
| | |
| | | |
| | | @Resource |
| | | private MesQcTemplateItemService templateItemService; |
| | | @Resource |
| | | private MesQcTemplateService templateService; |
| | | @Resource |
| | | private MesQcOqcLineService oqcLineService; |
| | | @Resource |
| | |
| | | // 1.3 根据产品 + OQC 类型查找可用质检方案(支持前端显式指定) |
| | | List<MesQcTemplateItemDO> templateItems = templateItemService.getTemplateItemList( |
| | | createReqVO.getItemId(), MesQcTypeEnum.OQC.getType(), null, null); |
| | | Long templateId; |
| | | if (CollUtil.isEmpty(templateItems)) { |
| | | throw exception(QC_NO_TEMPLATE); |
| | | } |
| | | MesQcTemplateItemDO templateItem = templateItems.get(0); |
| | | if (createReqVO.getTemplateId() != null) { |
| | | templateItem = templateItems.stream() |
| | | .filter(available -> Objects.equals(available.getTemplateId(), createReqVO.getTemplateId())) |
| | | .findFirst().orElse(null); |
| | | if (templateItem == null) { |
| | | throw exception(QC_NO_TEMPLATE); // 指定了方案但不在匹配列表中,拒绝 |
| | | // 产品物料未绑定出货检验方案:显式指定的方案改为校验方案本身(存在、已启用、检测种类含出货检验) |
| | | if (createReqVO.getTemplateId() == null) { |
| | | throw new ServiceException(QC_NO_TEMPLATE.getCode(), buildNoTemplateMessage(createReqVO.getItemId())); |
| | | } |
| | | templateId = validateTemplateUsable(createReqVO.getTemplateId()); |
| | | } else { |
| | | MesQcTemplateItemDO templateItem = templateItems.get(0); |
| | | if (createReqVO.getTemplateId() != null) { |
| | | templateItem = templateItems.stream() |
| | | .filter(available -> Objects.equals(available.getTemplateId(), createReqVO.getTemplateId())) |
| | | .findFirst().orElse(null); |
| | | if (templateItem == null) { // 指定了方案但不在该物料已绑定的匹配列表中,拒绝 |
| | | throw new ServiceException(QC_NO_TEMPLATE.getCode(), StrUtil.format( |
| | | "所选质检方案不在产品物料[{}]已绑定的出货检验方案范围内:请重新选择质检方案," |
| | | + "或先在【质量管理-质检方案】中为该物料绑定所选方案后重试。", |
| | | describeItem(createReqVO.getItemId()))); |
| | | } |
| | | } |
| | | templateId = templateItem.getTemplateId(); |
| | | } |
| | | Long templateId = templateItem.getTemplateId(); |
| | | |
| | | // 2. 插入主表 |
| | | MesQcOqcDO oqc = BeanUtils.toBean(createReqVO, MesQcOqcDO.class) |
| | |
| | | oqcMapper.updateById(updateObj); |
| | | } |
| | | |
| | | /** |
| | | * 校验质检方案本身可用:存在、已启用、检测种类包含出货检验,返回方案编号 |
| | | */ |
| | | private Long validateTemplateUsable(Long templateId) { |
| | | MesQcTemplateDO template = templateService.getTemplate(templateId); |
| | | if (template == null) { |
| | | throw new ServiceException(QC_TEMPLATE_NOT_EXISTS.getCode(), StrUtil.format( |
| | | "所选质检方案不存在(ID={}),可能已被删除,请刷新后重新选择质检方案", templateId)); |
| | | } |
| | | if (!CommonStatusEnum.isEnable(template.getStatus())) { |
| | | throw exception(QC_OQC_TEMPLATE_IS_DISABLE, template.getName()); |
| | | } |
| | | if (!CollUtil.contains(template.getTypes(), MesQcTypeEnum.OQC.getType())) { |
| | | throw exception(QC_OQC_TEMPLATE_TYPE_NOT_MATCH, template.getName()); |
| | | } |
| | | return template.getId(); |
| | | } |
| | | |
| | | /** |
| | | * 构建「无可用质检方案」的提示:给出物料名称与下一步动作 |
| | | */ |
| | | private String buildNoTemplateMessage(Long itemId) { |
| | | return StrUtil.format("产品物料[{}]未绑定「出货检验」质检方案,且未选择质检方案:请先选择质检方案后重试," |
| | | + "或在【质量管理-质检方案】中为该物料绑定检测种类包含出货检验的方案。", describeItem(itemId)); |
| | | } |
| | | |
| | | /** |
| | | * 描述物料,用于异常提示:优先给出「编码 名称」,查不到时回退为物料编号 |
| | | */ |
| | | private String describeItem(Long itemId) { |
| | | if (itemId == null) { |
| | | return "未选择"; |
| | | } |
| | | MdmItemRespDTO item = mdmItemApi.getItem(itemId).getCheckedData(); |
| | | return item != null ? item.getCode() + " " + item.getName() : "物料编号 ID=" + itemId; |
| | | } |
| | | |
| | | private void validateOqcSaveData(MesQcOqcSaveReqVO reqVO) { |
| | | // 校验编号唯一 |
| | | validateOqcCodeUnique(reqVO.getId(), reqVO.getCode()); |