Commit 5fbb423621d75ff503d26b008dfd584c66ffd097

Authored by YunaiV
1 parent 33b056e6

✨ CRM:完善合同的待回款金额

yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java
@@ -25,6 +25,7 @@ import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; @@ -25,6 +25,7 @@ import cn.iocoder.yudao.module.crm.service.contact.CrmContactService;
25 import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; 25 import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
26 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; 26 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
27 import cn.iocoder.yudao.module.crm.service.product.CrmProductService; 27 import cn.iocoder.yudao.module.crm.service.product.CrmProductService;
  28 +import cn.iocoder.yudao.module.crm.service.receivable.CrmReceivableService;
28 import cn.iocoder.yudao.module.system.api.dept.DeptApi; 29 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
29 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; 30 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
30 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 31 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
@@ -40,6 +41,7 @@ import org.springframework.validation.annotation.Validated; @@ -40,6 +41,7 @@ import org.springframework.validation.annotation.Validated;
40 import org.springframework.web.bind.annotation.*; 41 import org.springframework.web.bind.annotation.*;
41 42
42 import java.io.IOException; 43 import java.io.IOException;
  44 +import java.math.BigDecimal;
43 import java.util.Collections; 45 import java.util.Collections;
44 import java.util.List; 46 import java.util.List;
45 import java.util.Map; 47 import java.util.Map;
@@ -68,6 +70,8 @@ public class CrmContractController { @@ -68,6 +70,8 @@ public class CrmContractController {
68 private CrmBusinessService businessService; 70 private CrmBusinessService businessService;
69 @Resource 71 @Resource
70 private CrmProductService productService; 72 private CrmProductService productService;
  73 + @Resource
  74 + private CrmReceivableService receivableService;
71 75
72 @Resource 76 @Resource
73 private AdminUserApi adminUserApi; 77 private AdminUserApi adminUserApi;
@@ -192,6 +196,9 @@ public class CrmContractController { @@ -192,6 +196,9 @@ public class CrmContractController {
192 // 1.4 获取商机 196 // 1.4 获取商机
193 Map<Long, CrmBusinessDO> businessMap = businessService.getBusinessMap( 197 Map<Long, CrmBusinessDO> businessMap = businessService.getBusinessMap(
194 convertSet(contractList, CrmContractDO::getBusinessId)); 198 convertSet(contractList, CrmContractDO::getBusinessId));
  199 + // 1.5 获得已回款金额
  200 + Map<Long, BigDecimal> receivablePriceMap = receivableService.getReceivablePriceMapByContractId(
  201 + convertSet(contractList, CrmContractDO::getId));
195 // 2. 拼接数据 202 // 2. 拼接数据
196 return BeanUtils.toBean(contractList, CrmContractRespVO.class, contractVO -> { 203 return BeanUtils.toBean(contractList, CrmContractRespVO.class, contractVO -> {
197 // 2.1 设置客户信息 204 // 2.1 设置客户信息
@@ -207,6 +214,8 @@ public class CrmContractController { @@ -207,6 +214,8 @@ public class CrmContractController {
207 findAndThen(contactMap, contractVO.getSignContactId(), contact -> contractVO.setSignContactName(contact.getName())); 214 findAndThen(contactMap, contractVO.getSignContactId(), contact -> contractVO.setSignContactName(contact.getName()));
208 // 2.4 设置商机信息 215 // 2.4 设置商机信息
209 findAndThen(businessMap, contractVO.getBusinessId(), business -> contractVO.setBusinessName(business.getName())); 216 findAndThen(businessMap, contractVO.getBusinessId(), business -> contractVO.setBusinessName(business.getName()));
  217 + // 2.5 设置已回款金额
  218 + contractVO.setTotalReceivablePrice(receivablePriceMap.getOrDefault(contractVO.getId(), BigDecimal.ZERO));
210 }); 219 });
211 } 220 }
212 221
@@ -232,9 +241,16 @@ public class CrmContractController { @@ -232,9 +241,16 @@ public class CrmContractController {
232 CrmContractPageReqVO pageReqVO = new CrmContractPageReqVO().setCustomerId(customerId); 241 CrmContractPageReqVO pageReqVO = new CrmContractPageReqVO().setCustomerId(customerId);
233 pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); // 不分页 242 pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); // 不分页
234 PageResult<CrmContractDO> pageResult = contractService.getContractPageByCustomerId(pageReqVO); 243 PageResult<CrmContractDO> pageResult = contractService.getContractPageByCustomerId(pageReqVO);
  244 + if (CollUtil.isEmpty(pageResult.getList())) {
  245 + return success(Collections.emptyList());
  246 + }
  247 + // 拼接数据
  248 + Map<Long, BigDecimal> receivablePriceMap = receivableService.getReceivablePriceMapByContractId(
  249 + convertSet(pageResult.getList(), CrmContractDO::getId));
235 return success(convertList(pageResult.getList(), contract -> new CrmContractRespVO() // 只返回 id、name 等精简字段 250 return success(convertList(pageResult.getList(), contract -> new CrmContractRespVO() // 只返回 id、name 等精简字段
236 .setId(contract.getId()).setName(contract.getName()).setAuditStatus(contract.getAuditStatus()) 251 .setId(contract.getId()).setName(contract.getName()).setAuditStatus(contract.getAuditStatus())
237 - .setTotalPrice(contract.getTotalPrice()))); // TODO @芋艿:未回款金额 252 + .setTotalPrice(contract.getTotalPrice())
  253 + .setTotalReceivablePrice(receivablePriceMap.getOrDefault(contract.getId(), BigDecimal.ZERO))));
238 } 254 }
239 255
240 } 256 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/contract/CrmContractRespVO.java
@@ -88,6 +88,10 @@ public class CrmContractRespVO { @@ -88,6 +88,10 @@ public class CrmContractRespVO {
88 @ExcelProperty("合同金额") 88 @ExcelProperty("合同金额")
89 private BigDecimal totalPrice; 89 private BigDecimal totalPrice;
90 90
  91 + @Schema(description = "已回款金额", example = "5617")
  92 + @ExcelProperty("已回款金额")
  93 + private BigDecimal totalReceivablePrice;
  94 +
91 @Schema(description = "客户签约人编号", example = "18546") 95 @Schema(description = "客户签约人编号", example = "18546")
92 private Long signContactId; 96 private Long signContactId;
93 @Schema(description = "客户签约人", example = "小豆") 97 @Schema(description = "客户签约人", example = "小豆")
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/receivable/CrmReceivableMapper.java
1 package cn.iocoder.yudao.module.crm.dal.mysql.receivable; 1 package cn.iocoder.yudao.module.crm.dal.mysql.receivable;
2 2
  3 +import cn.hutool.core.collection.CollUtil;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 6 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
@@ -11,10 +12,16 @@ import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum; @@ -11,10 +12,16 @@ import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum;
11 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; 12 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
12 import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum; 13 import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
13 import cn.iocoder.yudao.module.crm.util.CrmPermissionUtils; 14 import cn.iocoder.yudao.module.crm.util.CrmPermissionUtils;
  15 +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
14 import org.apache.ibatis.annotations.Mapper; 16 import org.apache.ibatis.annotations.Mapper;
15 17
  18 +import java.math.BigDecimal;
16 import java.util.Collection; 19 import java.util.Collection;
  20 +import java.util.Collections;
17 import java.util.List; 21 import java.util.List;
  22 +import java.util.Map;
  23 +
  24 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
18 25
19 /** 26 /**
20 * 回款 Mapper 27 * 回款 Mapper
@@ -71,4 +78,18 @@ public interface CrmReceivableMapper extends BaseMapperX&lt;CrmReceivableDO&gt; { @@ -71,4 +78,18 @@ public interface CrmReceivableMapper extends BaseMapperX&lt;CrmReceivableDO&gt; {
71 return selectCount(query); 78 return selectCount(query);
72 } 79 }
73 80
  81 + default Map<Long, BigDecimal> selectReceivablePriceMapByContractId(Collection<Long> contractIds) {
  82 + if (CollUtil.isEmpty(contractIds)) {
  83 + return Collections.emptyMap();
  84 + }
  85 + // SQL sum 查询
  86 + List<Map<String, Object>> result = selectMaps(new QueryWrapper<CrmReceivableDO>()
  87 + .select("contract_id, SUM(price) AS total_price")
  88 + .eq("audit_status", CrmAuditStatusEnum.APPROVE.getStatus())
  89 + .groupBy("contract_id")
  90 + .in("contract_id", contractIds));
  91 + // 获得金额
  92 + return convertMap(result, obj -> (Long) obj.get("contract_id"), obj -> (BigDecimal) obj.get("total_price"));
  93 + }
  94 +
74 } 95 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java
@@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; @@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
7 import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO; 7 import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO;
8 import jakarta.validation.Valid; 8 import jakarta.validation.Valid;
9 9
  10 +import java.math.BigDecimal;
10 import java.util.Collection; 11 import java.util.Collection;
11 import java.util.List; 12 import java.util.List;
12 import java.util.Map; 13 import java.util.Map;
@@ -113,4 +114,12 @@ public interface CrmReceivableService { @@ -113,4 +114,12 @@ public interface CrmReceivableService {
113 */ 114 */
114 Long getCheckReceivablesCount(Long userId); 115 Long getCheckReceivablesCount(Long userId);
115 116
  117 + /**
  118 + * 获得合同已回款金额 Map
  119 + *
  120 + * @param contractIds 合同编号
  121 + * @return 回款金额 Map
  122 + */
  123 + Map<Long, BigDecimal> getReceivablePriceMapByContractId(Collection<Long> contractIds);
  124 +
116 } 125 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java
@@ -35,8 +35,10 @@ import org.springframework.stereotype.Service; @@ -35,8 +35,10 @@ import org.springframework.stereotype.Service;
35 import org.springframework.transaction.annotation.Transactional; 35 import org.springframework.transaction.annotation.Transactional;
36 import org.springframework.validation.annotation.Validated; 36 import org.springframework.validation.annotation.Validated;
37 37
  38 +import java.math.BigDecimal;
38 import java.util.Collection; 39 import java.util.Collection;
39 import java.util.List; 40 import java.util.List;
  41 +import java.util.Map;
40 42
41 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 43 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
42 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; 44 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
@@ -258,4 +260,9 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { @@ -258,4 +260,9 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
258 return receivableMapper.selectCheckReceivablesCount(userId); 260 return receivableMapper.selectCheckReceivablesCount(userId);
259 } 261 }
260 262
  263 + @Override
  264 + public Map<Long, BigDecimal> getReceivablePriceMapByContractId(Collection<Long> contractIds) {
  265 + return receivableMapper.selectReceivablePriceMapByContractId(contractIds);
  266 + }
  267 +
261 } 268 }