mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-30 03:01:53 +08:00
CRM-CONTRACT: 完善 TODO
This commit is contained in:
parent
1a96fb2ffc
commit
59e6f23788
@ -35,6 +35,22 @@ public class MoneyUtils {
|
|||||||
return calculateRatePrice(price, rate, 0, RoundingMode.FLOOR).intValue();
|
return calculateRatePrice(price, rate, 0, RoundingMode.FLOOR).intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算百分比金额
|
||||||
|
*
|
||||||
|
* @param price 金额(单位分)
|
||||||
|
* @param count 数量
|
||||||
|
* @param percent 折扣(单位分),列如 60.2%,则传入 6020
|
||||||
|
* @return 商品总价
|
||||||
|
*/
|
||||||
|
public static Integer calculator(Integer price, Integer count, Integer percent) {
|
||||||
|
price = price * count;
|
||||||
|
if (percent == null) {
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
return MoneyUtils.calculateRatePriceFloor(price, (double) (percent / 100));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算百分比金额
|
* 计算百分比金额
|
||||||
*
|
*
|
||||||
|
@ -43,7 +43,7 @@ public class BpmModelController {
|
|||||||
return success(model);
|
return success(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO @puhui999:这个接口的目的是啥呀?
|
// TODO @puhui999:这个接口的目的是啥呀?业务表单预览流程🤣
|
||||||
@GetMapping("/get-by-key")
|
@GetMapping("/get-by-key")
|
||||||
@Operation(summary = "获得模型")
|
@Operation(summary = "获得模型")
|
||||||
@Parameter(name = "key", description = "流程标识", required = true, example = "oa_leave")
|
@Parameter(name = "key", description = "流程标识", required = true, example = "oa_leave")
|
||||||
|
@ -12,6 +12,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, "更新合同失败,原因:禁止编辑");
|
ErrorCode CONTRACT_UPDATE_FAIL_EDITING_PROHIBITED = new ErrorCode(1_020_000_001, "更新合同失败,原因:禁止编辑");
|
||||||
|
ErrorCode CONTRACT_SUBMIT_FAIL_NOT_DRAFT = new ErrorCode(1_020_000_002, "合同提交审核失败,原因:合同没处在未提交状态");
|
||||||
|
|
||||||
// ========== 线索管理 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, "线索不存在");
|
||||||
|
@ -39,6 +39,8 @@ public interface LogRecordConstants {
|
|||||||
String CRM_CUSTOMER_POOL_SUCCESS = "将客户【{{#customerName}}】放入了公海";
|
String CRM_CUSTOMER_POOL_SUCCESS = "将客户【{{#customerName}}】放入了公海";
|
||||||
String CRM_CUSTOMER_RECEIVE_SUB_TYPE = "{{#ownerUserName != null ? '分配客户' : '领取客户'}}";
|
String CRM_CUSTOMER_RECEIVE_SUB_TYPE = "{{#ownerUserName != null ? '分配客户' : '领取客户'}}";
|
||||||
String CRM_CUSTOMER_RECEIVE_SUCCESS = "{{#ownerUserName != null ? '将客户【' + #customer.name + '】分配给【' + #ownerUserName + '】' : '领取客户【' + #customer.name + '】'}}";
|
String CRM_CUSTOMER_RECEIVE_SUCCESS = "{{#ownerUserName != null ? '将客户【' + #customer.name + '】分配给【' + #ownerUserName + '】' : '领取客户【' + #customer.name + '】'}}";
|
||||||
|
String CRM_CUSTOMER_IMPORT_SUB_TYPE = "{{#isUpdate ? '导入并更新客户' : '导入客户'}}";
|
||||||
|
String CRM_CUSTOMER_IMPORT_SUCCESS = "{{#isUpdate ? '导入并更新了客户【'+ #customer.name +'】' : '导入了客户【'+ #customer.name +'】'}}";
|
||||||
|
|
||||||
// ======================= CRM_CUSTOMER_LIMIT_CONFIG 客户限制配置 =======================
|
// ======================= CRM_CUSTOMER_LIMIT_CONFIG 客户限制配置 =======================
|
||||||
|
|
||||||
|
@ -132,21 +132,19 @@ public class CrmContractController {
|
|||||||
return CrmContractConvert.INSTANCE.convertPage(pageResult, userMap, customerList);
|
return CrmContractConvert.INSTANCE.convertPage(pageResult, userMap, customerList);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO @puhui999:transferContract
|
@PutMapping("/transfer-contract")
|
||||||
@PutMapping("/transfer")
|
|
||||||
@Operation(summary = "合同转移")
|
@Operation(summary = "合同转移")
|
||||||
@PreAuthorize("@ss.hasPermission('crm:contract:update')")
|
@PreAuthorize("@ss.hasPermission('crm:contract:update')")
|
||||||
public CommonResult<Boolean> transfer(@Valid @RequestBody CrmContractTransferReqVO reqVO) {
|
public CommonResult<Boolean> transferContract(@Valid @RequestBody CrmContractTransferReqVO reqVO) {
|
||||||
contractService.transferContract(reqVO, getLoginUserId());
|
contractService.transferContract(reqVO, getLoginUserId());
|
||||||
return success(true);
|
return success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO @puhui999:方法名不对哈;要不改成 submit?提交审核的意思
|
@PutMapping("/submit")
|
||||||
@PutMapping("/approve")
|
@Operation(summary = "提交合同审批")
|
||||||
@Operation(summary = "发起合同审批流程")
|
|
||||||
@PreAuthorize("@ss.hasPermission('crm:contract:update')")
|
@PreAuthorize("@ss.hasPermission('crm:contract:update')")
|
||||||
public CommonResult<Boolean> transfer(@RequestParam("id") Long id) {
|
public CommonResult<Boolean> submitContract(@RequestParam("id") Long id) {
|
||||||
contractService.handleApprove(id, getLoginUserId());
|
contractService.submitContract(id, getLoginUserId());
|
||||||
return success(true);
|
return success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,9 +89,6 @@ public class CrmContractSaveReqVO {
|
|||||||
@DiffLogField(name = "备注")
|
@DiffLogField(name = "备注")
|
||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
// TODO @puhui999:这个字段,按道理不用传递?
|
|
||||||
@Schema(description = "审批状态", example = "1")
|
|
||||||
private Integer auditStatus;
|
|
||||||
|
|
||||||
@Schema(description = "产品列表")
|
@Schema(description = "产品列表")
|
||||||
private List<CrmContractProductItem> productItems;
|
private List<CrmContractProductItem> productItems;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package cn.iocoder.yudao.module.crm.dal.dataobject.business;
|
package cn.iocoder.yudao.module.crm.dal.dataobject.business;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
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.dataobject.product.CrmProductDO;
|
||||||
import cn.iocoder.yudao.module.crm.enums.DictTypeConstants;
|
import cn.iocoder.yudao.module.crm.enums.DictTypeConstants;
|
||||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||||
@ -40,6 +41,12 @@ public class CrmBusinessProductDO extends BaseDO {
|
|||||||
* 关联 {@link CrmProductDO#getId()}
|
* 关联 {@link CrmProductDO#getId()}
|
||||||
*/
|
*/
|
||||||
private Long productId;
|
private Long productId;
|
||||||
|
/**
|
||||||
|
* 合同编号
|
||||||
|
*
|
||||||
|
* 关联 {@link CrmContractDO#getId()}
|
||||||
|
*/
|
||||||
|
private Long contractId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 产品单价
|
* 产品单价
|
||||||
|
@ -45,7 +45,7 @@ public class CrmProductDO extends BaseDO {
|
|||||||
/**
|
/**
|
||||||
* 价格,单位:分
|
* 价格,单位:分
|
||||||
*/
|
*/
|
||||||
private Long price;
|
private Integer price;
|
||||||
/**
|
/**
|
||||||
* 状态
|
* 状态
|
||||||
*
|
*
|
||||||
|
@ -101,10 +101,9 @@ public interface CrmCustomerMapper extends BaseMapperX<CrmCustomerDO> {
|
|||||||
return selectJoinPage(pageReqVO, CrmCustomerDO.class, query);
|
return selectJoinPage(pageReqVO, CrmCustomerDO.class, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
default List<CrmCustomerDO> selectListByLockAndDealStatusAndNotPool(Boolean lockStatus, Boolean dealStatus) {
|
default List<CrmCustomerDO> selectListByLockAndNotPool(Boolean lockStatus) {
|
||||||
return selectList(new LambdaQueryWrapper<CrmCustomerDO>()
|
return selectList(new LambdaQueryWrapper<CrmCustomerDO>()
|
||||||
.eq(CrmCustomerDO::getLockStatus, lockStatus)
|
.eq(CrmCustomerDO::getLockStatus, lockStatus)
|
||||||
.eq(CrmCustomerDO::getDealStatus, dealStatus)
|
|
||||||
.gt(CrmCustomerDO::getOwnerUserId, 0));
|
.gt(CrmCustomerDO::getOwnerUserId, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
// TODO @lzxhqs:方法名上,带下 BusinessProduct;主要考虑不精简的原因,是因为一个逻辑,可能会出现一些超越它自身方法,省略不容易懂;
|
// TODO @lzxhqs:方法名上,带下 BusinessProduct;主要考虑不精简的原因,是因为一个逻辑,可能会出现一些超越它自身方法,省略不容易懂;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 商机产品关联表 Service 接口
|
* 商机产品关联表 Service 接口
|
||||||
*
|
*
|
||||||
@ -14,31 +15,45 @@ public interface CrmBusinessProductService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量新增商机产品关联数据
|
* 批量新增商机产品关联数据
|
||||||
|
*
|
||||||
* @param list 商机产品集合
|
* @param list 商机产品集合
|
||||||
*/
|
*/
|
||||||
void insertBatch(List<CrmBusinessProductDO> list);
|
void insertBatch(List<CrmBusinessProductDO> list);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据商机id获取商机产品关联数据集合
|
* 根据商机id获取商机产品关联数据集合
|
||||||
|
*
|
||||||
* @param businessId 商机id
|
* @param businessId 商机id
|
||||||
*/
|
*/
|
||||||
List<CrmBusinessProductDO> selectListByBusinessId(Long businessId);
|
List<CrmBusinessProductDO> selectListByBusinessId(Long businessId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量更新商机产品表
|
* 批量更新商机产品表
|
||||||
|
*
|
||||||
* @param list 商机产品数据集合
|
* @param list 商机产品数据集合
|
||||||
*/
|
*/
|
||||||
void updateBatch(List<CrmBusinessProductDO> list);
|
void updateBatch(List<CrmBusinessProductDO> list);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量删除
|
* 批量删除
|
||||||
|
*
|
||||||
* @param list 需要删除的商机产品集合
|
* @param list 需要删除的商机产品集合
|
||||||
*/
|
*/
|
||||||
void deleteBatch(List<CrmBusinessProductDO> list);
|
void deleteBatch(List<CrmBusinessProductDO> list);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*根据商机id删除商机产品关联数据
|
* 根据商机id删除商机产品关联数据
|
||||||
|
*
|
||||||
* @param businessId 商机id
|
* @param businessId 商机id
|
||||||
*/
|
*/
|
||||||
void deleteByBusinessId(Long businessId);
|
void deleteByBusinessId(Long businessId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得合同关联的商品列表
|
||||||
|
*
|
||||||
|
* @param contractId 合同编号
|
||||||
|
* @return 关联的商品列表
|
||||||
|
*/
|
||||||
|
List<CrmBusinessProductDO> selectListByContractId(Long contractId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ public class CrmBusinessProductServiceImpl implements CrmBusinessProductService
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<CrmBusinessProductDO> selectListByBusinessId(Long businessId) {
|
public List<CrmBusinessProductDO> selectListByBusinessId(Long businessId) {
|
||||||
return businessProductMapper.selectList(CrmBusinessProductDO::getBusinessId,businessId);
|
return businessProductMapper.selectList(CrmBusinessProductDO::getBusinessId, businessId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -47,4 +47,9 @@ public class CrmBusinessProductServiceImpl implements CrmBusinessProductService
|
|||||||
businessProductMapper.deleteByBusinessId(businessId);
|
businessProductMapper.deleteByBusinessId(businessId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<CrmBusinessProductDO> selectListByContractId(Long contractId) {
|
||||||
|
return businessProductMapper.selectList(CrmBusinessProductDO::getContractId, contractId);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
|
|||||||
*/
|
*/
|
||||||
private void validateContractExists(Long businessId) {
|
private void validateContractExists(Long businessId) {
|
||||||
// TODO @lzxhqs:保持风格的统一,selectCountByBusinessId 改成 getContractCountByBusinessId;另外,可以不用声明 count,因为就一次性使用,直接把 197 和 198 合并成一行;
|
// TODO @lzxhqs:保持风格的统一,selectCountByBusinessId 改成 getContractCountByBusinessId;另外,可以不用声明 count,因为就一次性使用,直接把 197 和 198 合并成一行;
|
||||||
Long count = contractService.selectCountByBusinessId(businessId);
|
Long count = contractService.getContractCountByBusinessId(businessId);
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
throw exception(BUSINESS_CONTRACT_EXISTS);
|
throw exception(BUSINESS_CONTRACT_EXISTS);
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ public interface CrmContractService {
|
|||||||
* @param id 合同编号
|
* @param id 合同编号
|
||||||
* @param userId 用户编号
|
* @param userId 用户编号
|
||||||
*/
|
*/
|
||||||
void handleApprove(Long id, Long userId);
|
void submitContract(Long id, Long userId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新合同流程审批结果
|
* 更新合同流程审批结果
|
||||||
@ -125,13 +125,12 @@ public interface CrmContractService {
|
|||||||
*/
|
*/
|
||||||
Long getContractCountByCustomerId(Long customerId);
|
Long getContractCountByCustomerId(Long customerId);
|
||||||
|
|
||||||
// TODO @puhui999:要不改成 getContractCountByBusinessId
|
|
||||||
/**
|
/**
|
||||||
* 根据商机ID获取关联客户的合同数量
|
* 根据商机ID获取关联客户的合同数量
|
||||||
*
|
*
|
||||||
* @param businessId 商机编号
|
* @param businessId 商机编号
|
||||||
* @return 数量
|
* @return 数量
|
||||||
*/
|
*/
|
||||||
Long selectCountByBusinessId(Long businessId);
|
Long getContractCountByBusinessId(Long businessId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,12 @@ 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.lang.Assert;
|
||||||
import cn.hutool.core.util.ObjUtil;
|
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.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.listener.dto.BpmResultListenerRespDTO;
|
||||||
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;
|
||||||
import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO;
|
import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO;
|
||||||
@ -87,8 +89,10 @@ public class CrmContractServiceImpl implements CrmContractService {
|
|||||||
CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class).setId(null);
|
CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class).setId(null);
|
||||||
contractMapper.insert(contract);
|
contractMapper.insert(contract);
|
||||||
// 1.2 插入商机关联商品
|
// 1.2 插入商机关联商品
|
||||||
List<CrmBusinessProductDO> businessProduct = convertBusinessProductList(createReqVO);
|
if (CollUtil.isNotEmpty(createReqVO.getProductItems())) { // 如果有的话
|
||||||
businessProductService.insertBatch(businessProduct);
|
List<CrmBusinessProductDO> businessProduct = convertBusinessProductList(createReqVO, contract.getId());
|
||||||
|
businessProductService.insertBatch(businessProduct);
|
||||||
|
}
|
||||||
|
|
||||||
// 2. 创建数据权限
|
// 2. 创建数据权限
|
||||||
crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId)
|
crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId)
|
||||||
@ -106,9 +110,11 @@ public class CrmContractServiceImpl implements CrmContractService {
|
|||||||
success = CRM_CONTRACT_UPDATE_SUCCESS)
|
success = CRM_CONTRACT_UPDATE_SUCCESS)
|
||||||
@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 @合同待定:只有草稿、审批中,可以编辑;
|
Assert.notNull(updateReqVO.getId(), "合同编号不能为空");
|
||||||
if (ObjUtil.notEqual(updateReqVO.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus()) ||
|
CrmContractDO contract = validateContractExists(updateReqVO.getId());
|
||||||
ObjUtil.notEqual(updateReqVO.getAuditStatus(), CrmAuditStatusEnum.PROCESS.getStatus())) {
|
// 只有草稿、审批中,可以编辑;
|
||||||
|
if (ObjUtil.notEqual(contract.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus()) ||
|
||||||
|
ObjUtil.notEqual(contract.getAuditStatus(), CrmAuditStatusEnum.PROCESS.getStatus())) {
|
||||||
throw exception(CONTRACT_UPDATE_FAIL_EDITING_PROHIBITED);
|
throw exception(CONTRACT_UPDATE_FAIL_EDITING_PROHIBITED);
|
||||||
}
|
}
|
||||||
validateRelationDataExists(updateReqVO);
|
validateRelationDataExists(updateReqVO);
|
||||||
@ -117,21 +123,41 @@ public class CrmContractServiceImpl implements CrmContractService {
|
|||||||
// 更新合同
|
// 更新合同
|
||||||
CrmContractDO updateObj = BeanUtils.toBean(updateReqVO, CrmContractDO.class);
|
CrmContractDO updateObj = BeanUtils.toBean(updateReqVO, CrmContractDO.class);
|
||||||
contractMapper.updateById(updateObj);
|
contractMapper.updateById(updateObj);
|
||||||
|
// 更新合同关联商品
|
||||||
// TODO puhui999: @芋艿:合同变更关联的商机后商品怎么处理?
|
updateContractProduct(updateReqVO, updateObj.getId());
|
||||||
// TODO @puhui999:和商品 spu、sku 编辑一样;新增的插入;修改的更新;删除的删除
|
|
||||||
//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));
|
||||||
LogRecordContext.putVariable("contractName", oldContract.getName());
|
LogRecordContext.putVariable("contractName", oldContract.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateContractProduct(CrmContractSaveReqVO updateReqVO, Long contractId) {
|
||||||
|
if (CollUtil.isEmpty(updateReqVO.getProductItems())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<CrmBusinessProductDO> newProductList = convertBusinessProductList(updateReqVO, contractId);
|
||||||
|
List<CrmBusinessProductDO> oldProductList = businessProductService.selectListByContractId(contractId);
|
||||||
|
List<List<CrmBusinessProductDO>> diffList = diffList(oldProductList, newProductList, (oldObj, newObj) -> {
|
||||||
|
if (ObjUtil.notEqual(oldObj.getProductId(), newObj.getProductId())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
newObj.setId(oldObj.getId()); // 设置一下老的编号更新时需要使用
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
if (CollUtil.isNotEmpty(diffList.getFirst())) {
|
||||||
|
businessProductService.insertBatch(diffList.getFirst());
|
||||||
|
}
|
||||||
|
if (CollUtil.isNotEmpty(diffList.get(1))) {
|
||||||
|
businessProductService.updateBatch(diffList.get(1));
|
||||||
|
}
|
||||||
|
if (CollUtil.isNotEmpty(diffList.get(2))) {
|
||||||
|
businessProductService.deleteBatch(diffList.get(2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO @合同待定:缺一个取消合同的接口;只有草稿、审批中可以取消;CrmAuditStatusEnum
|
// TODO @合同待定:缺一个取消合同的接口;只有草稿、审批中可以取消;CrmAuditStatusEnum
|
||||||
|
|
||||||
private List<CrmBusinessProductDO> convertBusinessProductList(CrmContractSaveReqVO reqVO) {
|
private List<CrmBusinessProductDO> convertBusinessProductList(CrmContractSaveReqVO reqVO, Long contractId) {
|
||||||
// 校验商品存在
|
// 校验商品存在
|
||||||
Set<Long> productIds = convertSet(reqVO.getProductItems(), CrmContractSaveReqVO.CrmContractProductItem::getId);
|
Set<Long> productIds = convertSet(reqVO.getProductItems(), CrmContractSaveReqVO.CrmContractProductItem::getId);
|
||||||
List<CrmProductDO> productList = productService.getProductList(productIds);
|
List<CrmProductDO> productList = productService.getProductList(productIds);
|
||||||
@ -140,29 +166,14 @@ public class CrmContractServiceImpl implements CrmContractService {
|
|||||||
}
|
}
|
||||||
Map<Long, CrmProductDO> productMap = convertMap(productList, CrmProductDO::getId);
|
Map<Long, CrmProductDO> productMap = convertMap(productList, CrmProductDO::getId);
|
||||||
return convertList(reqVO.getProductItems(), productItem -> {
|
return convertList(reqVO.getProductItems(), productItem -> {
|
||||||
// TODO @puhui999:这里可以改成直接 return,不用弄一个 businessProduct 变量哈;
|
CrmProductDO product = productMap.get(productItem.getId());
|
||||||
CrmBusinessProductDO businessProduct = BeanUtils.toBean(productMap.get(productItem.getId()), CrmBusinessProductDO.class);
|
return BeanUtils.toBean(product, CrmBusinessProductDO.class)
|
||||||
businessProduct.setId(null).setBusinessId(reqVO.getBusinessId()).setProductId(productItem.getId())
|
.setId(null).setBusinessId(reqVO.getBusinessId()).setProductId(productItem.getId()).setContractId(contractId)
|
||||||
.setCount(productItem.getCount()).setDiscountPercent(productItem.getDiscountPercent()).setTotalPrice(calculator(businessProduct));
|
.setCount(productItem.getCount()).setDiscountPercent(productItem.getDiscountPercent())
|
||||||
return businessProduct;
|
.setTotalPrice(MoneyUtils.calculator(product.getPrice(), productItem.getCount(), productItem.getDiscountPercent()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 计算商品总价
|
|
||||||
*
|
|
||||||
* @param businessProduct 关联商品
|
|
||||||
* @return 商品总价
|
|
||||||
*/
|
|
||||||
// TODO @puhui999:这个逻辑的计算,是不是可以封装到 calculateRatePriceFloor 里;
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验关联数据是否存在
|
* 校验关联数据是否存在
|
||||||
*
|
*
|
||||||
@ -235,9 +246,12 @@ public class CrmContractServiceImpl implements CrmContractService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void handleApprove(Long id, Long userId) {
|
public void submitContract(Long id, Long userId) {
|
||||||
// TODO @puhui999:需要做状态检查
|
// 1. 校验合同是否在审批
|
||||||
|
CrmContractDO contract = validateContractExists(id);
|
||||||
|
if (ObjUtil.notEqual(contract.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus())) {
|
||||||
|
throw exception(CONTRACT_SUBMIT_FAIL_NOT_DRAFT);
|
||||||
|
}
|
||||||
// 创建合同审批流程实例
|
// 创建合同审批流程实例
|
||||||
String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO()
|
String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO()
|
||||||
.setProcessDefinitionKey(CONTRACT_APPROVE).setBusinessKey(String.valueOf(id)));
|
.setProcessDefinitionKey(CONTRACT_APPROVE).setBusinessKey(String.valueOf(id)));
|
||||||
@ -247,6 +261,12 @@ public class CrmContractServiceImpl implements CrmContractService {
|
|||||||
.setAuditStatus(CrmAuditStatusEnum.PROCESS.getStatus()));
|
.setAuditStatus(CrmAuditStatusEnum.PROCESS.getStatus()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateContractAuditStatus(BpmResultListenerRespDTO event) {
|
||||||
|
contractMapper.updateById(new CrmContractDO().setId(Long.parseLong(event.getBusinessKey()))
|
||||||
|
.setAuditStatus(event.getResult()));
|
||||||
|
}
|
||||||
|
|
||||||
//======================= 查询相关 =======================
|
//======================= 查询相关 =======================
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -285,7 +305,7 @@ public class CrmContractServiceImpl implements CrmContractService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long selectCountByBusinessId(Long businessId) {
|
public Long getContractCountByBusinessId(Long businessId) {
|
||||||
return contractMapper.selectCountByBusinessId(businessId);
|
return contractMapper.selectCountByBusinessId(businessId);
|
||||||
}
|
}
|
||||||
// TODO @合同待定:需要新增一个 ContractConfigDO 表,合同配置,重点是到期提醒;
|
// TODO @合同待定:需要新增一个 ContractConfigDO 表,合同配置,重点是到期提醒;
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
package cn.iocoder.yudao.module.crm.service.contract.listener;
|
package cn.iocoder.yudao.module.crm.service.contract.listener;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.api.listener.BpmResultListenerApi;
|
import cn.iocoder.yudao.module.bpm.api.listener.BpmResultListenerApi;
|
||||||
import cn.iocoder.yudao.module.bpm.api.listener.dto.BpmResultListenerRespDTO;
|
import cn.iocoder.yudao.module.bpm.api.listener.dto.BpmResultListenerRespDTO;
|
||||||
|
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
|
||||||
|
import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum;
|
||||||
import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
|
import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
|
||||||
import cn.iocoder.yudao.module.crm.service.contract.CrmContractServiceImpl;
|
import cn.iocoder.yudao.module.crm.service.contract.CrmContractServiceImpl;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
@ -25,7 +29,31 @@ public class CrmContractResultListener implements BpmResultListenerApi {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(BpmResultListenerRespDTO event) {
|
public void onEvent(BpmResultListenerRespDTO event) {
|
||||||
|
boolean currentTaskFinish = isEndResult(event.getResult());
|
||||||
|
if (!currentTaskFinish) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ObjUtil.equal(event.getResult(), BpmProcessInstanceResultEnum.APPROVE.getResult())) {
|
||||||
|
event.setResult(CrmAuditStatusEnum.APPROVE.getStatus());
|
||||||
|
}
|
||||||
|
if (ObjUtil.equal(event.getResult(), BpmProcessInstanceResultEnum.REJECT.getResult())) {
|
||||||
|
event.setResult(CrmAuditStatusEnum.REJECT.getStatus());
|
||||||
|
}
|
||||||
|
if (ObjUtil.equal(event.getResult(), BpmProcessInstanceResultEnum.CANCEL.getResult())) {
|
||||||
|
event.setResult(CrmAuditStatusEnum.CANCEL.getStatus());
|
||||||
|
}
|
||||||
contractService.updateContractAuditStatus(event);
|
contractService.updateContractAuditStatus(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断该结果是否处于 End 最终结果
|
||||||
|
*
|
||||||
|
* @param result 结果
|
||||||
|
* @return 是否
|
||||||
|
*/
|
||||||
|
public static boolean isEndResult(Integer result) {
|
||||||
|
return ObjectUtils.equalsAny(result, BpmProcessInstanceResultEnum.APPROVE.getResult(),
|
||||||
|
BpmProcessInstanceResultEnum.REJECT.getResult(), BpmProcessInstanceResultEnum.CANCEL.getResult());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -93,8 +93,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
|
|||||||
validateCustomerExceedOwnerLimit(createReqVO.getOwnerUserId(), 1);
|
validateCustomerExceedOwnerLimit(createReqVO.getOwnerUserId(), 1);
|
||||||
|
|
||||||
// 2. 插入客户
|
// 2. 插入客户
|
||||||
CrmCustomerDO customer = BeanUtils.toBean(createReqVO, CrmCustomerDO.class).setOwnerUserId(userId)
|
CrmCustomerDO customer = initCustomer(createReqVO, userId);
|
||||||
.setLockStatus(false).setDealStatus(false).setContactLastTime(LocalDateTime.now());
|
|
||||||
customerMapper.insert(customer);
|
customerMapper.insert(customer);
|
||||||
|
|
||||||
// 3. 创建数据权限
|
// 3. 创建数据权限
|
||||||
@ -232,7 +231,6 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
|
|||||||
return customer.getId();
|
return customer.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO @puhui999:操作日志
|
|
||||||
@Override
|
@Override
|
||||||
public CrmCustomerImportRespVO importCustomerList(List<CrmCustomerImportExcelVO> importCustomers,
|
public CrmCustomerImportRespVO importCustomerList(List<CrmCustomerImportExcelVO> importCustomers,
|
||||||
Boolean isUpdateSupport, Long userId) {
|
Boolean isUpdateSupport, Long userId) {
|
||||||
@ -253,14 +251,14 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
|
|||||||
// 判断如果不存在,在进行插入
|
// 判断如果不存在,在进行插入
|
||||||
CrmCustomerDO existCustomer = customerMapper.selectByCustomerName(importCustomer.getName());
|
CrmCustomerDO existCustomer = customerMapper.selectByCustomerName(importCustomer.getName());
|
||||||
if (existCustomer == null) {
|
if (existCustomer == null) {
|
||||||
// TODO @puhui999:可以搞个 initCustomer 方法;这样可以把 create 和导入复用下这个方法;
|
CrmCustomerDO customer = initCustomer(importCustomer, userId);
|
||||||
CrmCustomerDO customer = BeanUtils.toBean(importCustomer, CrmCustomerDO.class).setOwnerUserId(userId)
|
|
||||||
.setLockStatus(false).setDealStatus(false).setContactLastTime(LocalDateTime.now());
|
|
||||||
customerMapper.insert(customer);
|
customerMapper.insert(customer);
|
||||||
respVO.getCreateCustomerNames().add(importCustomer.getName());
|
respVO.getCreateCustomerNames().add(importCustomer.getName());
|
||||||
// 创建数据权限
|
// 创建数据权限
|
||||||
permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType())
|
permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_CUSTOMER.getType())
|
||||||
.setBizId(customer.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人
|
.setBizId(customer.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人
|
||||||
|
// 记录操作日志
|
||||||
|
getSelf().importCustomerLog(customer, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 如果存在,判断是否允许更新
|
// 如果存在,判断是否允许更新
|
||||||
@ -273,10 +271,25 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
|
|||||||
updateCustomer.setId(existCustomer.getId());
|
updateCustomer.setId(existCustomer.getId());
|
||||||
customerMapper.updateById(updateCustomer);
|
customerMapper.updateById(updateCustomer);
|
||||||
respVO.getUpdateCustomerNames().add(importCustomer.getName());
|
respVO.getUpdateCustomerNames().add(importCustomer.getName());
|
||||||
|
// 记录操作日志
|
||||||
|
getSelf().importCustomerLog(updateCustomer, true);
|
||||||
});
|
});
|
||||||
return respVO;
|
return respVO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static CrmCustomerDO initCustomer(Object customer, Long userId) {
|
||||||
|
return BeanUtils.toBean(customer, CrmCustomerDO.class).setOwnerUserId(userId)
|
||||||
|
.setLockStatus(false).setDealStatus(false).setContactLastTime(LocalDateTime.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
@LogRecord(type = CRM_CUSTOMER_TYPE, subType = CRM_CUSTOMER_IMPORT_SUB_TYPE, bizNo = "{{#customer.id}}",
|
||||||
|
success = CRM_CUSTOMER_IMPORT_SUCCESS)
|
||||||
|
public void importCustomerLog(CrmCustomerDO customer, boolean isUpdate) {
|
||||||
|
// 记录操作日志上下文
|
||||||
|
LogRecordContext.putVariable("customer", customer);
|
||||||
|
LogRecordContext.putVariable("isUpdate", isUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
private void validateCustomerForCreate(CrmCustomerImportExcelVO importCustomer) {
|
private void validateCustomerForCreate(CrmCustomerImportExcelVO importCustomer) {
|
||||||
// 校验客户名称不能为空
|
// 校验客户名称不能为空
|
||||||
if (StrUtil.isEmptyIfStr(importCustomer.getName())) {
|
if (StrUtil.isEmptyIfStr(importCustomer.getName())) {
|
||||||
@ -367,15 +380,15 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
|
|||||||
if (poolConfig == null || !poolConfig.getEnabled()) {
|
if (poolConfig == null || !poolConfig.getEnabled()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// 1.1 获取没有锁定的不在公海的客户且没有成交的
|
// 1.1 获取没有锁定的不在公海的客户
|
||||||
List<CrmCustomerDO> notDealCustomerList = customerMapper.selectListByLockAndDealStatusAndNotPool(Boolean.FALSE, Boolean.FALSE);
|
List<CrmCustomerDO> customerList = customerMapper.selectListByLockAndNotPool(Boolean.FALSE);
|
||||||
// 1.2 获取没有锁定的不在公海的客户且成交的
|
|
||||||
// TODO @puhui999:下面也搞到 sql 里去哈;写 or 查询,问题不大的;
|
|
||||||
List<CrmCustomerDO> dealCustomerList = customerMapper.selectListByLockAndDealStatusAndNotPool(Boolean.FALSE, Boolean.TRUE);
|
|
||||||
List<CrmCustomerDO> poolCustomerList = new ArrayList<>();
|
List<CrmCustomerDO> poolCustomerList = new ArrayList<>();
|
||||||
poolCustomerList.addAll(filterList(notDealCustomerList, customer ->
|
poolCustomerList.addAll(filterList(customerList, customer ->
|
||||||
(poolConfig.getDealExpireDays() - LocalDateTimeUtils.between(customer.getCreateTime())) <= 0));
|
!customer.getDealStatus() && (poolConfig.getDealExpireDays() - LocalDateTimeUtils.between(customer.getCreateTime())) <= 0));
|
||||||
poolCustomerList.addAll(filterList(dealCustomerList, customer -> {
|
poolCustomerList.addAll(filterList(customerList, customer -> {
|
||||||
|
if (!customer.getDealStatus()) { // 这里只处理成交的
|
||||||
|
return false;
|
||||||
|
}
|
||||||
LocalDateTime lastTime = ObjUtil.defaultIfNull(customer.getContactLastTime(), customer.getCreateTime());
|
LocalDateTime lastTime = ObjUtil.defaultIfNull(customer.getContactLastTime(), customer.getCreateTime());
|
||||||
return (poolConfig.getContactExpireDays() - LocalDateTimeUtils.between(lastTime)) <= 0;
|
return (poolConfig.getContactExpireDays() - LocalDateTimeUtils.between(lastTime)) <= 0;
|
||||||
}));
|
}));
|
||||||
|
Loading…
Reference in New Issue
Block a user