feat(crm): 增加渠道商转介功能并优化绩效计算

- 在 CrmContractProductSettlementDTO 中添加 channelNums 字段,用于记录渠道商转介数量
- 在 CrmBusinessDO、CrmBusinessRespVO 和 CrmBusinessSaveReqVO 中添加与渠道商相关的信息字段
- 修改 CrmContractMapper.xml,增加渠道商转介数量的计算逻辑
- 在 SalesPerformanceSettlementDO 和相关的 VO 类中添加渠道商销售和回款相关字段
- 更新 SalesPerformanceSettlementServiceImpl,支持渠道商转介数量和回款金额的统计
This commit is contained in:
furongxin 2025-03-31 10:09:49 +08:00
parent f2d3f9c9cf
commit 5aacccc0c3
9 changed files with 76 additions and 7 deletions

View File

@ -22,6 +22,9 @@ public class CrmContractProductSettlementDTO {
@Schema(description = "数量") @Schema(description = "数量")
private Integer nums; private Integer nums;
@Schema(description = "渠道商转介数量")
private Integer channelNums;
@Schema(description = "折扣") @Schema(description = "折扣")
private BigDecimal discount; private BigDecimal discount;

View File

@ -76,4 +76,15 @@ public class CrmBusinessRespVO {
@Schema(description = "负责人") @Schema(description = "负责人")
private String ownUserName; private String ownUserName;
@Schema(description = "是否渠道商转介 | 0否 1是")
private Integer isChannel;
@Schema(description = "渠道商名称")
private String channelName;
@Schema(description = "渠道商联系方式")
private String channelPhone;
@Schema(description = "渠道商银行卡号")
private String channelBankNo;
} }

View File

@ -54,8 +54,19 @@ public class CrmBusinessSaveReqVO {
@Schema(description = "负责人ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "24317") @Schema(description = "负责人ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "24317")
private Long ownerUserId; private Long ownerUserId;
@Schema(description = "商机产品关联列表") @Schema(description = "商机产品关联列表")
private List<CrmBusinessProductDO> businessProducts; private List<CrmBusinessProductDO> businessProducts;
@Schema(description = "是否渠道商转介 | 0否 1是")
private Integer isChannel;
@Schema(description = "渠道商名称")
private String channelName;
@Schema(description = "渠道商联系方式")
private String channelPhone;
@Schema(description = "渠道商银行卡号")
private String channelBankNo;
} }

View File

@ -41,9 +41,15 @@ public class SalesPerformanceSettlementRespVO {
@Schema(description = "实际回款额") @Schema(description = "实际回款额")
private BigDecimal actualPayment; private BigDecimal actualPayment;
@Schema(description = "渠道回款额")
private BigDecimal channelPayment;
@Schema(description = "实际销售额") @Schema(description = "实际销售额")
private Integer actualSale; private Integer actualSale;
@Schema(description = "渠道销售额")
private Integer channelSale;
@Schema(description = "回款目标") @Schema(description = "回款目标")
private BigDecimal paymentTarget; private BigDecimal paymentTarget;

View File

@ -32,9 +32,15 @@ public class SalesPerformanceSettlementSaveReqVO {
@Schema(description = "实际回款额") @Schema(description = "实际回款额")
private BigDecimal actualPayment; private BigDecimal actualPayment;
@Schema(description = "渠道回款额")
private BigDecimal channelPayment;
@Schema(description = "实际销售额") @Schema(description = "实际销售额")
private Integer actualSale; private Integer actualSale;
@Schema(description = "渠道销售额")
private Integer channelSale;
@Schema(description = "评分") @Schema(description = "评分")
private BigDecimal score; private BigDecimal score;

View File

@ -77,6 +77,20 @@ public class CrmBusinessDO extends BaseDO {
* 负责人ID * 负责人ID
*/ */
private Long ownerUserId; private Long ownerUserId;
/**
* 是否渠道商转介 | 0否 1是
*/
private Integer isChannel;
/**
* 渠道商名称
*/
private String channelName;
/**
* 渠道商电话
*/
private String channelPhone;
/**
* 渠道商银行账号
*/
private String channelBankNo;
} }

View File

@ -51,10 +51,18 @@ public class SalesPerformanceSettlementDO extends BaseDO {
* 实际回款额 * 实际回款额
*/ */
private BigDecimal actualPayment; private BigDecimal actualPayment;
/**
* 渠道商回款额
*/
private BigDecimal channelPayment;
/** /**
* 实际销售额 * 实际销售额
*/ */
private Integer actualSale; private Integer actualSale;
/**
* 渠道商销售额
*/
private Integer channelSale;
/** /**
* 评分 * 评分
*/ */

View File

@ -55,6 +55,7 @@ import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
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.framework.common.util.collection.CollectionUtils.convertMap;
import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.NOT_EDITABLE_UNTIL_SALES_TARGET_HAS_BEEN_APPLIED; import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.NOT_EDITABLE_UNTIL_SALES_TARGET_HAS_BEEN_APPLIED;
/** /**
@ -219,6 +220,10 @@ public class SalesPerformanceSettlementServiceImpl extends ServiceImpl<SalesPerf
//根据用户id分组 并且合并数量 //根据用户id分组 并且合并数量
Map<Long, Integer> productMap = contractProductSettlementDTOList.stream().collect(Collectors.groupingBy(CrmContractProductSettlementDTO::getUserId, Map<Long, Integer> productMap = contractProductSettlementDTOList.stream().collect(Collectors.groupingBy(CrmContractProductSettlementDTO::getUserId,
Collectors.summingInt(CrmContractProductSettlementDTO::getNums))); Collectors.summingInt(CrmContractProductSettlementDTO::getNums)));
//根据用户id分组 并且合并渠道商转介数量
Map<Long, Integer> channelMap = contractProductSettlementDTOList.stream().collect(Collectors.groupingBy(CrmContractProductSettlementDTO::getUserId,
Collectors.summingInt(CrmContractProductSettlementDTO::getChannelNums)));
// -- 回款申请 / - 回了多少就是多少咯 - 这个没啥业务判断当前月回了多少款即可 // -- 回款申请 / - 回了多少就是多少咯 - 这个没啥业务判断当前月回了多少款即可
LocalDateTime beginTime = LocalDateTimeUtils.beginOfMonth(now); LocalDateTime beginTime = LocalDateTimeUtils.beginOfMonth(now);
LocalDateTime endTime = LocalDateTimeUtils.endOfMonth(now); LocalDateTime endTime = LocalDateTimeUtils.endOfMonth(now);
@ -227,8 +232,8 @@ public class SalesPerformanceSettlementServiceImpl extends ServiceImpl<SalesPerf
receiptSettlementVO.setCreateTime(times); receiptSettlementVO.setCreateTime(times);
List<ReceiptSettlementDTO> receiptSettlementList = receiptApi.getReceiptSettlement(receiptSettlementVO).getCheckedData(); List<ReceiptSettlementDTO> receiptSettlementList = receiptApi.getReceiptSettlement(receiptSettlementVO).getCheckedData();
receiptSettlementList = CollUtil.isEmpty(receiptSettlementList) ? Collections.emptyList() : receiptSettlementList; receiptSettlementList = CollUtil.isEmpty(receiptSettlementList) ? Collections.emptyList() : receiptSettlementList;
Map<Long, BigDecimal> receiptSettlementMap = receiptSettlementList.stream() Map<Long, ReceiptSettlementDTO> receiptSettlementMap = convertMap(receiptSettlementList, ReceiptSettlementDTO::getUserId);
.collect(Collectors.toMap(ReceiptSettlementDTO::getUserId, ReceiptSettlementDTO::getMoney));
List<SalesPerformanceSettlementDO> salesPerformanceSettlementDOS = salesPerformanceSettlementMapper.selectList(new LambdaQueryWrapperX<SalesPerformanceSettlementDO>() List<SalesPerformanceSettlementDO> salesPerformanceSettlementDOS = salesPerformanceSettlementMapper.selectList(new LambdaQueryWrapperX<SalesPerformanceSettlementDO>()
.eq(SalesPerformanceSettlementDO::getYear, year) .eq(SalesPerformanceSettlementDO::getYear, year)
.eq(SalesPerformanceSettlementDO::getMonth, month)); .eq(SalesPerformanceSettlementDO::getMonth, month));
@ -244,6 +249,7 @@ public class SalesPerformanceSettlementServiceImpl extends ServiceImpl<SalesPerf
//获取绩效考核设置 //获取绩效考核设置
for (UserLiveTreeListVO vo : userLiveList) { for (UserLiveTreeListVO vo : userLiveList) {
SalesPerformanceSettlementDO salesPerformanceSettlementDO = map.get(vo.getUserId()); SalesPerformanceSettlementDO salesPerformanceSettlementDO = map.get(vo.getUserId());
ReceiptSettlementDTO receiptSettlementDTO = receiptSettlementMap.get(vo.getUserId());
if (salesPerformanceSettlementDO == null) { if (salesPerformanceSettlementDO == null) {
salesPerformanceSettlementDO = new SalesPerformanceSettlementDO(); salesPerformanceSettlementDO = new SalesPerformanceSettlementDO();
} }
@ -251,7 +257,9 @@ public class SalesPerformanceSettlementServiceImpl extends ServiceImpl<SalesPerf
salesPerformanceSettlementDO.setYear(String.valueOf(now.getYear())); salesPerformanceSettlementDO.setYear(String.valueOf(now.getYear()));
salesPerformanceSettlementDO.setMonth(String.format("%02d", now.getMonthValue())); salesPerformanceSettlementDO.setMonth(String.format("%02d", now.getMonthValue()));
salesPerformanceSettlementDO.setActualSale(productMap.getOrDefault(vo.getUserId(), 0)); salesPerformanceSettlementDO.setActualSale(productMap.getOrDefault(vo.getUserId(), 0));
salesPerformanceSettlementDO.setActualPayment(receiptSettlementMap.getOrDefault(vo.getUserId(), BigDecimal.ZERO)); salesPerformanceSettlementDO.setChannelSale(channelMap.getOrDefault(vo.getUserId(), 0));
salesPerformanceSettlementDO.setActualPayment(receiptSettlementDTO != null ? receiptSettlementDTO.getMoney() : BigDecimal.ZERO);
salesPerformanceSettlementDO.setChannelPayment(receiptSettlementDTO != null ? receiptSettlementDTO.getChannelAmount() : BigDecimal.ZERO);
SalesPerformanceDTO salesPerformanceDTO = salesPerformanceMap.get(vo.getUserId()); SalesPerformanceDTO salesPerformanceDTO = salesPerformanceMap.get(vo.getUserId());
if (salesPerformanceDTO == null) { if (salesPerformanceDTO == null) {
continue; continue;

View File

@ -130,11 +130,13 @@
a.product_id AS productId, a.product_id AS productId,
a.price AS price, a.price AS price,
a.nums AS nums, a.nums AS nums,
CASE WHEN bu.is_channel = 1 THEN a.nums ELSE 0 END AS channelNums,
a.discount AS discount, a.discount AS discount,
a.subtotal AS subtotal a.subtotal AS subtotal
FROM FROM
crm_contract_product AS a crm_contract_product AS a
LEFT JOIN bpm_oa_contract AS b ON a.contract_id = b.id LEFT JOIN bpm_oa_contract AS b ON a.contract_id = b.id
LEFT JOIN crm_business bu ON bu.id = b.business_id
WHERE WHERE
a.deleted = 0 a.deleted = 0
and b.deleted = 0 and b.deleted = 0