CRM-合同:完善新增合同插入关联的商品

This commit is contained in:
puhui999 2024-01-28 20:15:11 +08:00
parent ea6752f15e
commit 4418a7bebc
4 changed files with 94 additions and 6 deletions

View File

@ -11,6 +11,7 @@ public interface ErrorCodeConstants {
// ========== 合同管理 1-020-000-000 ========== // ========== 合同管理 1-020-000-000 ==========
ErrorCode CONTRACT_NOT_EXISTS = new ErrorCode(1_020_000_000, "合同不存在"); ErrorCode CONTRACT_NOT_EXISTS = new ErrorCode(1_020_000_000, "合同不存在");
ErrorCode CONTRACT_UPDATE_FAIL_EDITING_PROHIBITED = new ErrorCode(1_020_000_001, "更新合同失败,原因:禁止编辑");
// ========== 线索管理 1-020-001-000 ========== // ========== 线索管理 1-020-001-000 ==========
ErrorCode CLUE_NOT_EXISTS = new ErrorCode(1_020_001_000, "线索不存在"); ErrorCode CLUE_NOT_EXISTS = new ErrorCode(1_020_001_000, "线索不存在");

View File

@ -89,6 +89,9 @@ public class CrmContractSaveReqVO {
@DiffLogField(name = "备注") @DiffLogField(name = "备注")
private String remark; private String remark;
@Schema(description = "审批状态", example = "1")
private Integer auditStatus;
@Schema(description = "产品列表") @Schema(description = "产品列表")
private List<CrmContractProductItem> productItems; private List<CrmContractProductItem> productItems;
@ -104,7 +107,7 @@ public class CrmContractSaveReqVO {
@Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911")
@NotNull(message = "产品数量不能为空") @NotNull(message = "产品数量不能为空")
private Long count; private Integer count;
@Schema(description = "产品折扣") @Schema(description = "产品折扣")
private Integer discountPercent; private Integer discountPercent;

View File

@ -2,7 +2,9 @@ package cn.iocoder.yudao.module.crm.service.contract;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil; import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
@ -10,16 +12,23 @@ import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageR
import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractSaveReqVO; import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractSaveReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO;
import cn.iocoder.yudao.module.crm.convert.contract.CrmContractConvert; import cn.iocoder.yudao.module.crm.convert.contract.CrmContractConvert;
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO;
import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper; import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper;
import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum; import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum;
import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission; import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission;
import cn.iocoder.yudao.module.crm.service.business.CrmBusinessProductService; import cn.iocoder.yudao.module.crm.service.business.CrmBusinessProductService;
import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService;
import cn.iocoder.yudao.module.crm.service.contact.CrmContactService;
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO; import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO;
import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
import cn.iocoder.yudao.module.crm.service.product.CrmProductService;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import com.mzt.logapi.context.LogRecordContext; import com.mzt.logapi.context.LogRecordContext;
import com.mzt.logapi.service.impl.DiffParseFunction; import com.mzt.logapi.service.impl.DiffParseFunction;
import com.mzt.logapi.starter.annotation.LogRecord; import com.mzt.logapi.starter.annotation.LogRecord;
@ -30,10 +39,14 @@ import org.springframework.validation.annotation.Validated;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CONTRACT_NOT_EXISTS; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*; import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS;
/** /**
* CRM 合同 Service 实现类 * CRM 合同 Service 实现类
@ -53,16 +66,25 @@ public class CrmContractServiceImpl implements CrmContractService {
private CrmPermissionService crmPermissionService; private CrmPermissionService crmPermissionService;
@Resource @Resource
private CrmBusinessProductService businessProductService; private CrmBusinessProductService businessProductService;
@Resource
private CrmProductService productService;
@Resource @Resource
private BpmProcessInstanceApi bpmProcessInstanceApi; private BpmProcessInstanceApi bpmProcessInstanceApi;
@Resource
private CrmCustomerService customerService;
@Resource
private CrmContactService contactService;
@Resource
private CrmBusinessService businessService;
@Resource
private AdminUserApi adminUserApi;
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_CREATE_SUB_TYPE, bizNo = "{{#contract.id}}", @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_CREATE_SUB_TYPE, bizNo = "{{#contract.id}}",
success = CRM_CONTRACT_CREATE_SUCCESS) success = CRM_CONTRACT_CREATE_SUCCESS)
public Long createContract(CrmContractSaveReqVO createReqVO, Long userId) { public Long createContract(CrmContractSaveReqVO createReqVO, Long userId) {
// TODO @合同待定插入合同商品需要搞个 BusinessProductDO validateRelationDataExists(createReqVO);
// 插入合同 // 插入合同
CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class).setId(null); CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class).setId(null);
contractMapper.insert(contract); contractMapper.insert(contract);
@ -71,6 +93,10 @@ public class CrmContractServiceImpl implements CrmContractService {
crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId) crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId)
.setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()).setBizId(contract.getId()) .setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()).setBizId(contract.getId())
.setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); .setLevel(CrmPermissionLevelEnum.OWNER.getLevel()));
// 插入商机关联商品
List<CrmBusinessProductDO> businessProduct = convertBusinessProductList(createReqVO);
businessProductService.insertBatch(businessProduct);
// 4. 记录操作日志上下文 // 4. 记录操作日志上下文
LogRecordContext.putVariable("contract", contract); LogRecordContext.putVariable("contract", contract);
return contract.getId(); return contract.getId();
@ -83,12 +109,21 @@ public class CrmContractServiceImpl implements CrmContractService {
@CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
public void updateContract(CrmContractSaveReqVO updateReqVO) { public void updateContract(CrmContractSaveReqVO updateReqVO) {
// TODO @合同待定只有草稿审批中可以编辑 // TODO @合同待定只有草稿审批中可以编辑
if (ObjUtil.notEqual(updateReqVO.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus()) ||
ObjUtil.notEqual(updateReqVO.getAuditStatus(), CrmAuditStatusEnum.PROCESS.getStatus())) {
throw exception(CONTRACT_UPDATE_FAIL_EDITING_PROHIBITED);
}
validateRelationDataExists(updateReqVO);
// 校验存在 // 校验存在
CrmContractDO oldContract = validateContractExists(updateReqVO.getId()); CrmContractDO oldContract = validateContractExists(updateReqVO.getId());
// 更新合同 // 更新合同
CrmContractDO updateObj = BeanUtils.toBean(updateReqVO, CrmContractDO.class); CrmContractDO updateObj = BeanUtils.toBean(updateReqVO, CrmContractDO.class);
contractMapper.updateById(updateObj); contractMapper.updateById(updateObj);
// TODO @合同待定插入合同商品需要搞个 BusinessProductDO
// TODO puhui999: @芋艿合同变更关联的商机后商品怎么处理
//List<CrmBusinessProductDO> businessProduct = convertBusinessProductList(updateReqVO);
//businessProductService.selectListByBusinessId()
//diffList()
// 3. 记录操作日志上下文 // 3. 记录操作日志上下文
LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldContract, CrmContractSaveReqVO.class)); LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldContract, CrmContractSaveReqVO.class));
@ -97,8 +132,55 @@ public class CrmContractServiceImpl implements CrmContractService {
// TODO @合同待定缺一个取消合同的接口只有草稿审批中可以取消CrmAuditStatusEnum // TODO @合同待定缺一个取消合同的接口只有草稿审批中可以取消CrmAuditStatusEnum
// TODO @合同待定缺一个发起审批的接口只有草稿可以发起审批CrmAuditStatusEnum private List<CrmBusinessProductDO> convertBusinessProductList(CrmContractSaveReqVO reqVO) {
// 校验商品存在
Set<Long> productIds = convertSet(reqVO.getProductItems(), CrmContractSaveReqVO.CrmContractProductItem::getId);
List<CrmProductDO> productList = productService.getProductList(productIds);
if (CollUtil.isEmpty(productIds) || productList.size() != productIds.size()) {
throw exception(PRODUCT_NOT_EXISTS);
}
Map<Long, CrmProductDO> productMap = convertMap(productList, CrmProductDO::getId);
return convertList(reqVO.getProductItems(), productItem -> {
CrmBusinessProductDO businessProduct = BeanUtils.toBean(productMap.get(productItem.getId()), CrmBusinessProductDO.class);
businessProduct.setId(null).setBusinessId(reqVO.getBusinessId()).setProductId(productItem.getId())
.setCount(productItem.getCount()).setDiscountPercent(productItem.getDiscountPercent()).setTotalPrice(calculator(businessProduct));
return businessProduct;
});
}
/**
* 计算商品总价
*
* @param businessProduct 关联商品
* @return 商品总价
*/
private Integer calculator(CrmBusinessProductDO businessProduct) {
int price = businessProduct.getPrice() * businessProduct.getCount();
if (businessProduct.getDiscountPercent() == null) {
return price;
}
return MoneyUtils.calculateRatePriceFloor(price, (double) (businessProduct.getDiscountPercent() / 100));
}
/**
* 校验关联数据是否存在
*
* @param reqVO 请求
*/
private void validateRelationDataExists(CrmContractSaveReqVO reqVO) {
// 1. 校验客户
if (reqVO.getCustomerId() != null && customerService.getCustomer(reqVO.getCustomerId()) == null) {
throw exception(CUSTOMER_NOT_EXISTS);
}
// 2. 校验负责人
if (reqVO.getOwnerUserId() != null && adminUserApi.getUser(reqVO.getOwnerUserId()) == null) {
throw exception(USER_NOT_EXISTS);
}
// 4. 如果有关联商机则需要校验存在
if (reqVO.getBusinessId() != null && businessService.getBusiness(reqVO.getBusinessId()) == null) {
throw exception(BUSINESS_NOT_EXISTS);
}
}
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@ -151,6 +233,7 @@ public class CrmContractServiceImpl implements CrmContractService {
} }
@Override @Override
@Transactional(rollbackFor = Exception.class)
public void handleApprove(Long id, Long userId) { public void handleApprove(Long id, Long userId) {
// 创建合同审批流程实例 // 创建合同审批流程实例
String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO() String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO()

View File

@ -1,4 +1,5 @@
package cn.iocoder.yudao.module.crm.service.contract.listener; package cn.iocoder.yudao.module.crm.service.contract.listener;
public class CrmContractResultListener { public class CrmContractResultListener {
// TODO puhui999: @芋艿 艿艿写一下这个没研究明白哈哈
} }