diff --git a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/service/impl/CrmQuoteInfoServiceImpl.java b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/service/impl/CrmQuoteInfoServiceImpl.java index 5c277aa3..9e6410c7 100644 --- a/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/service/impl/CrmQuoteInfoServiceImpl.java +++ b/ruoyi-modules/ruoyi-oa/src/main/java/org/dromara/oa/crm/service/impl/CrmQuoteInfoServiceImpl.java @@ -22,6 +22,7 @@ import org.dromara.oa.base.domain.BaseMaterialInfo; import org.dromara.oa.base.domain.BaseRelationMaterial; import org.dromara.oa.base.domain.bo.BaseRelationMaterialBo; import org.dromara.oa.base.domain.vo.BaseRelationMaterialVo; +import org.dromara.oa.base.mapper.BaseMaterialInfoMapper; import org.dromara.oa.base.service.IBaseRelationMaterialService; import org.dromara.oa.crm.domain.*; import org.dromara.oa.crm.domain.bo.CrmQuoteInfoBo; @@ -63,6 +64,7 @@ public class CrmQuoteInfoServiceImpl implements ICrmQuoteInfoService { //客户联系人 private final ICrmCustomerContactService customerContactService; private final IBaseRelationMaterialService baseRelationMaterialService; + private final BaseMaterialInfoMapper baseMaterialInfoMapper; @DubboReference(timeout = 30000) private RemoteWorkflowService remoteWorkflowService; @@ -309,49 +311,110 @@ public class CrmQuoteInfoServiceImpl implements ICrmQuoteInfoService { return customerContactVo == null ? null : customerContactVo.getCustomerId(); } + /** + * 处理关联物料信息:查询是否存在,不存在则创建 + *
+ * 业务逻辑说明: + * 1. 当报价物料是标准物料(materialFlag="1")且已选择SAP物料(materialId不为空)时触发 + * 2. 智能解析产品名称:优先使用用户输入,其次使用已有销售物料名,最后回退到SAP物料名 + * 3. 校验现有关联是否仍有效(物料ID+客户ID+产品名称是否一致),不一致则重新匹配或创建 + * 4. 若不存在匹配记录,则自动创建新的关联销售物料信息 + * 5. 将关联物料ID回写到报价物料对象,建立物料与客户之间的映射关系 + *
+ * + * @param quoteMaterial 报价物料对象,包含物料ID、物料类型、产品名称等信息 + * @param customerId 客户ID,用于建立物料与客户的关联关系 + */ private void processRelationMaterial(CrmQuoteMaterial quoteMaterial, Long customerId) { + // 自动推断物料类型标志:如果前端已传入则使用传入值,否则根据materialId判断 + // 有materialId表示选择了SAP标准物料,标志为"1";无materialId表示手工物料,标志为"2" String materialFlag = StringUtils.isNotBlank(quoteMaterial.getMaterialFlag()) ? quoteMaterial.getMaterialFlag() : (quoteMaterial.getMaterialId() != null ? "1" : "2"); quoteMaterial.setMaterialFlag(materialFlag); + // 校验触发条件:必须同时满足以下三个条件才处理关联物料 + // 1. 物料类型为标准物料(materialFlag="1") + // 2. 已选择SAP标准物料(materialId不为空) + // 3. 已确定客户(customerId不为空) if (!Objects.equals(materialFlag, "1") || quoteMaterial.getMaterialId() == null - || customerId == null - || StringUtils.isBlank(quoteMaterial.getProductName())) { + || customerId == null) { return; } + // 根据当前关联物料ID查询关联销售物料信息,用于后续校验关联是否仍有效 + BaseRelationMaterialVo currentRelationMaterial = queryRelationMaterial(quoteMaterial.getRelationMaterialId()); + // 智能解析产品名称,按优先级回退:用户输入 > 已有销售物料名 > SAP物料名 + String resolvedProductName = resolveStandardMaterialProductName(quoteMaterial, currentRelationMaterial); + // 如果无法解析出有效的产品名称,则终止处理 + if (StringUtils.isBlank(resolvedProductName)) { + return; + } + // 标准物料新增时,业务人员经常先选 SAP 物料再补客户侧名称; + // 若本次未填写产品名称,则这里回退销售物料名/SAP物料名,确保仍能自动补建客户侧关联名称。 + // 将解析后的产品名称回填到报价物料对象,保证数据完整性 + quoteMaterial.setProductName(resolvedProductName); + // 标准物料允许业务人员修改“产品名称”,因此旧的销售物料关联不一定还能代表当前录入值, // 这里先校验已带回的 relationMaterialId 是否仍与“物料 + 客户 + 产品名称”一致,不一致就重新匹配/补建。 - BaseRelationMaterialVo currentRelationMaterial = queryRelationMaterial(quoteMaterial.getRelationMaterialId()); + // 校验关联有效性:物料ID、客户ID、产品名称三者必须完全匹配 if (currentRelationMaterial != null && Objects.equals(currentRelationMaterial.getMaterialId(), quoteMaterial.getMaterialId()) && Objects.equals(currentRelationMaterial.getCustomerId(), customerId) - && StringUtils.equals(currentRelationMaterial.getSaleMaterialName(), quoteMaterial.getProductName())) { + && StringUtils.equals(currentRelationMaterial.getSaleMaterialName(), resolvedProductName)) { + // 关联仍有效,无需重新匹配,直接返回 return; } + // 关联无效或不存在,清空关联物料ID,准备重新匹配或创建 quoteMaterial.setRelationMaterialId(null); + // 构建查询条件对象,根据物料ID+客户ID+产品名称查询是否已存在关联记录 BaseRelationMaterialBo queryBo = new BaseRelationMaterialBo(); + // 设置SAP物料ID,关联销售物料必须对应同一个SAP物料 queryBo.setMaterialId(quoteMaterial.getMaterialId()); + // 设置客户ID,关联销售物料是按客户维度隔离的 queryBo.setCustomerId(customerId); - queryBo.setSaleMaterialName(quoteMaterial.getProductName()); + // 设置销售物料名称(即解析后的产品名称),支持同一SAP物料对不同客户有不同销售名称 + queryBo.setSaleMaterialName(resolvedProductName); + // 执行查询 List