|
|
|
|
@ -20,6 +20,9 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|
|
|
|
import org.dromara.common.tenant.helper.TenantHelper;
|
|
|
|
|
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.service.IBaseRelationMaterialService;
|
|
|
|
|
import org.dromara.oa.crm.domain.*;
|
|
|
|
|
import org.dromara.oa.crm.domain.bo.CrmQuoteInfoBo;
|
|
|
|
|
import org.dromara.oa.crm.domain.bo.CrmQuoteMaterialBo;
|
|
|
|
|
@ -59,6 +62,7 @@ public class CrmQuoteInfoServiceImpl implements ICrmQuoteInfoService {
|
|
|
|
|
private final CrmQuoteMaterialMapper quoteMaterialMapper;
|
|
|
|
|
//客户联系人
|
|
|
|
|
private final ICrmCustomerContactService customerContactService;
|
|
|
|
|
private final IBaseRelationMaterialService baseRelationMaterialService;
|
|
|
|
|
|
|
|
|
|
@DubboReference(timeout = 30000)
|
|
|
|
|
private RemoteWorkflowService remoteWorkflowService;
|
|
|
|
|
@ -198,6 +202,7 @@ public class CrmQuoteInfoServiceImpl implements ICrmQuoteInfoService {
|
|
|
|
|
public Boolean insertByBo(CrmQuoteInfoBo bo) {
|
|
|
|
|
CrmQuoteInfo add = MapstructUtils.convert(bo, CrmQuoteInfo.class);
|
|
|
|
|
validEntityBeforeSave(add);
|
|
|
|
|
Long customerId = resolveCustomerId(bo.getCustomerContactId());
|
|
|
|
|
|
|
|
|
|
String quoteCode = remoteCodeRuleService.selectCodeRuleCode("1004");
|
|
|
|
|
add.setQuoteCode(quoteCode);
|
|
|
|
|
@ -218,6 +223,7 @@ public class CrmQuoteInfoServiceImpl implements ICrmQuoteInfoService {
|
|
|
|
|
if (entity.getItemNo() == null) {
|
|
|
|
|
entity.setItemNo((long) (i + 1));
|
|
|
|
|
}
|
|
|
|
|
processRelationMaterial(entity, customerId);
|
|
|
|
|
quoteMaterialMapper.insert(entity);
|
|
|
|
|
}
|
|
|
|
|
// 回写主表金额汇总
|
|
|
|
|
@ -242,6 +248,7 @@ public class CrmQuoteInfoServiceImpl implements ICrmQuoteInfoService {
|
|
|
|
|
if (!ok) return false;
|
|
|
|
|
// 差异更新子表:存在则更新,不存在则插入;并删除前端未提交的旧记录
|
|
|
|
|
Long qid = bo.getQuoteId();
|
|
|
|
|
Long customerId = resolveCustomerId(bo.getCustomerContactId());
|
|
|
|
|
List<CrmQuoteMaterial> oldItems = quoteMaterialMapper.selectList(
|
|
|
|
|
Wrappers.<CrmQuoteMaterial>lambdaQuery().eq(CrmQuoteMaterial::getQuoteId, qid)
|
|
|
|
|
);
|
|
|
|
|
@ -257,6 +264,7 @@ public class CrmQuoteInfoServiceImpl implements ICrmQuoteInfoService {
|
|
|
|
|
if (entity.getItemNo() == null) {
|
|
|
|
|
entity.setItemNo((long) (i + 1));
|
|
|
|
|
}
|
|
|
|
|
processRelationMaterial(entity, customerId);
|
|
|
|
|
// 使用 insertOrUpdate 简化增改逻辑,参考合同物料实现
|
|
|
|
|
quoteMaterialMapper.insertOrUpdate(entity);
|
|
|
|
|
}
|
|
|
|
|
@ -288,6 +296,72 @@ public class CrmQuoteInfoServiceImpl implements ICrmQuoteInfoService {
|
|
|
|
|
//TODO 做一些数据校验,如唯一约束
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Long resolveCustomerId(Long customerContactId) {
|
|
|
|
|
// 联系人ID允许为空,因为报价单在草稿或临时保存阶段可能还未选择客户联系人,此时不应抛异常阻断主流程。
|
|
|
|
|
if (customerContactId == null) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
// 报价单主表当前只直接保存客户联系人ID,这里统一通过联系人反查所属客户ID,
|
|
|
|
|
// 这样后续物料关联、同轮报价聚合等逻辑都能基于“客户”这一稳定业务主键处理,避免各处重复查询。
|
|
|
|
|
CrmCustomerContactVo customerContactVo = customerContactService.queryById(customerContactId);
|
|
|
|
|
// 联系人被删除、数据不完整或跨模块查询未命中时,返回 null 而不是强行报错,
|
|
|
|
|
// 目的是让调用方按“未识别到客户”分支继续兜底处理,减少非核心数据缺失对报价保存流程的影响。
|
|
|
|
|
return customerContactVo == null ? null : customerContactVo.getCustomerId();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void processRelationMaterial(CrmQuoteMaterial quoteMaterial, Long customerId) {
|
|
|
|
|
String materialFlag = StringUtils.isNotBlank(quoteMaterial.getMaterialFlag())
|
|
|
|
|
? quoteMaterial.getMaterialFlag()
|
|
|
|
|
: (quoteMaterial.getMaterialId() != null ? "1" : "2");
|
|
|
|
|
quoteMaterial.setMaterialFlag(materialFlag);
|
|
|
|
|
if (!Objects.equals(materialFlag, "1")
|
|
|
|
|
|| quoteMaterial.getMaterialId() == null
|
|
|
|
|
|| customerId == null
|
|
|
|
|
|| StringUtils.isBlank(quoteMaterial.getProductName())) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 标准物料允许业务人员修改“产品名称”,因此旧的销售物料关联不一定还能代表当前录入值,
|
|
|
|
|
// 这里先校验已带回的 relationMaterialId 是否仍与“物料 + 客户 + 产品名称”一致,不一致就重新匹配/补建。
|
|
|
|
|
BaseRelationMaterialVo currentRelationMaterial = queryRelationMaterial(quoteMaterial.getRelationMaterialId());
|
|
|
|
|
if (currentRelationMaterial != null
|
|
|
|
|
&& Objects.equals(currentRelationMaterial.getMaterialId(), quoteMaterial.getMaterialId())
|
|
|
|
|
&& Objects.equals(currentRelationMaterial.getCustomerId(), customerId)
|
|
|
|
|
&& StringUtils.equals(currentRelationMaterial.getSaleMaterialName(), quoteMaterial.getProductName())) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
quoteMaterial.setRelationMaterialId(null);
|
|
|
|
|
|
|
|
|
|
BaseRelationMaterialBo queryBo = new BaseRelationMaterialBo();
|
|
|
|
|
queryBo.setMaterialId(quoteMaterial.getMaterialId());
|
|
|
|
|
queryBo.setCustomerId(customerId);
|
|
|
|
|
queryBo.setSaleMaterialName(quoteMaterial.getProductName());
|
|
|
|
|
List<BaseRelationMaterialVo> relationMaterials = baseRelationMaterialService.queryList(queryBo);
|
|
|
|
|
if (relationMaterials != null && !relationMaterials.isEmpty()) {
|
|
|
|
|
quoteMaterial.setRelationMaterialId(relationMaterials.get(0).getRelationMaterialId());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BaseRelationMaterialBo relationMaterialBo = new BaseRelationMaterialBo();
|
|
|
|
|
relationMaterialBo.setMaterialId(quoteMaterial.getMaterialId());
|
|
|
|
|
relationMaterialBo.setCustomerId(customerId);
|
|
|
|
|
relationMaterialBo.setSaleMaterialName(quoteMaterial.getProductName());
|
|
|
|
|
relationMaterialBo.setActiveFlag("1");
|
|
|
|
|
// 这里按“物料 + 客户 + 报价产品名称”补建销售物料关联,避免标准物料改名后仍然丢失客户侧展示名称。
|
|
|
|
|
baseRelationMaterialService.insertByBo(relationMaterialBo);
|
|
|
|
|
quoteMaterial.setRelationMaterialId(relationMaterialBo.getRelationMaterialId());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private BaseRelationMaterialVo queryRelationMaterial(Long relationMaterialId) {
|
|
|
|
|
if (relationMaterialId == null) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
BaseRelationMaterialBo queryBo = new BaseRelationMaterialBo();
|
|
|
|
|
queryBo.setRelationMaterialId(relationMaterialId);
|
|
|
|
|
List<BaseRelationMaterialVo> relationMaterials = baseRelationMaterialService.queryList(queryBo);
|
|
|
|
|
return relationMaterials == null || relationMaterials.isEmpty() ? null : relationMaterials.get(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 校验并批量删除报价单信息信息
|
|
|
|
|
*
|
|
|
|
|
|