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