Commit ef26b5e8dc2512aab50bb25d52c8f92a8ef7ab01

Authored by YunaiV
1 parent c97c9f88

✨ CRM:完善合同的列表实现

Showing 12 changed files with 200 additions and 263 deletions
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessRespVO.java
@@ -130,7 +130,7 @@ public class CrmBusinessRespVO { @@ -130,7 +130,7 @@ public class CrmBusinessRespVO {
130 @Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") 130 @Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00")
131 private BigDecimal productPrice; 131 private BigDecimal productPrice;
132 132
133 - @Schema(description = "合同价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") 133 + @Schema(description = "商机价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00")
134 private BigDecimal businessPrice; 134 private BigDecimal businessPrice;
135 135
136 @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") 136 @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911")
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java
@@ -53,7 +53,7 @@ public class CrmBusinessSaveReqVO { @@ -53,7 +53,7 @@ public class CrmBusinessSaveReqVO {
53 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) 53 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
54 private LocalDateTime dealTime; 54 private LocalDateTime dealTime;
55 55
56 - @Schema(description = "整单折扣") 56 + @Schema(description = "整单折扣", requiredMode = Schema.RequiredMode.REQUIRED, example = "55.00")
57 @DiffLogField(name = "整单折扣") 57 @DiffLogField(name = "整单折扣")
58 @NotNull(message = "整单折扣不能为空") 58 @NotNull(message = "整单折扣不能为空")
59 private BigDecimal discountPercent; 59 private BigDecimal discountPercent;
@@ -82,8 +82,8 @@ public class CrmBusinessSaveReqVO { @@ -82,8 +82,8 @@ public class CrmBusinessSaveReqVO {
82 @NotNull(message = "产品单价不能为空") 82 @NotNull(message = "产品单价不能为空")
83 private BigDecimal productPrice; 83 private BigDecimal productPrice;
84 84
85 - @Schema(description = "合同价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00")  
86 - @NotNull(message = "合同价格不能为空") 85 + @Schema(description = "商机价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00")
  86 + @NotNull(message = "商机价格不能为空")
87 private BigDecimal businessPrice; 87 private BigDecimal businessPrice;
88 88
89 @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") 89 @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911")
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java
@@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil; @@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.lang.Assert; 4 import cn.hutool.core.lang.Assert;
5 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 5 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
7 import cn.iocoder.yudao.framework.common.util.number.NumberUtils; 8 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
8 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 9 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
9 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; 10 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
@@ -12,18 +13,17 @@ import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageR @@ -12,18 +13,17 @@ import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageR
12 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractRespVO; 13 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractRespVO;
13 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractSaveReqVO; 14 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractSaveReqVO;
14 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; 15 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO;
15 -import cn.iocoder.yudao.module.crm.convert.contract.CrmContractConvert;  
16 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 16 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
17 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; 17 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
18 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; 18 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
19 -import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractProductDO;  
20 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; 19 import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
21 -import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO;  
22 import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService; 20 import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService;
23 import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; 21 import cn.iocoder.yudao.module.crm.service.contact.CrmContactService;
24 import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; 22 import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
25 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; 23 import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
26 import cn.iocoder.yudao.module.crm.service.product.CrmProductService; 24 import cn.iocoder.yudao.module.crm.service.product.CrmProductService;
  25 +import cn.iocoder.yudao.module.system.api.dept.DeptApi;
  26 +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
27 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 27 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
28 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; 28 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
29 import io.swagger.v3.oas.annotations.Operation; 29 import io.swagger.v3.oas.annotations.Operation;
@@ -44,6 +44,7 @@ import java.util.stream.Stream; @@ -44,6 +44,7 @@ import java.util.stream.Stream;
44 44
45 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 45 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
46 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; 46 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
  47 +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
47 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; 48 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
48 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; 49 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
49 import static java.util.Collections.singletonList; 50 import static java.util.Collections.singletonList;
@@ -64,8 +65,11 @@ public class CrmContractController { @@ -64,8 +65,11 @@ public class CrmContractController {
64 private CrmBusinessService businessService; 65 private CrmBusinessService businessService;
65 @Resource 66 @Resource
66 private CrmProductService productService; 67 private CrmProductService productService;
  68 +
67 @Resource 69 @Resource
68 private AdminUserApi adminUserApi; 70 private AdminUserApi adminUserApi;
  71 + @Resource
  72 + private DeptApi deptApi;
69 73
70 @PostMapping("/create") 74 @PostMapping("/create")
71 @Operation(summary = "创建合同") 75 @Operation(summary = "创建合同")
@@ -96,15 +100,21 @@ public class CrmContractController { @@ -96,15 +100,21 @@ public class CrmContractController {
96 @Parameter(name = "id", description = "编号", required = true, example = "1024") 100 @Parameter(name = "id", description = "编号", required = true, example = "1024")
97 @PreAuthorize("@ss.hasPermission('crm:contract:query')") 101 @PreAuthorize("@ss.hasPermission('crm:contract:query')")
98 public CommonResult<CrmContractRespVO> getContract(@RequestParam("id") Long id) { 102 public CommonResult<CrmContractRespVO> getContract(@RequestParam("id") Long id) {
99 - // 1. 查询合同  
100 CrmContractDO contract = contractService.getContract(id); 103 CrmContractDO contract = contractService.getContract(id);
  104 + return success(buildContractDetail(contract));
  105 + }
  106 +
  107 + private CrmContractRespVO buildContractDetail(CrmContractDO contract) {
101 if (contract == null) { 108 if (contract == null) {
102 - return success(null); 109 + return null;
103 } 110 }
104 -  
105 - // 2. 拼接合同信息  
106 - List<CrmContractRespVO> respVOList = buildContractDetailList(singletonList(contract));  
107 - return success(respVOList.get(0)); 111 +// List<CrmProductDO> productList = null;
  112 +// if (contractList.size() == 1) {
  113 +// List<CrmContractProductDO> contractProductList = contractService.getContractProductListByContractId(contractList.get(0).getId());
  114 +// contractProductMap = convertMap(contractProductList, CrmContractProductDO::getProductId);
  115 +// productList = productService.getProductList(convertSet(contractProductList, CrmContractProductDO::getProductId));
  116 +// }
  117 + return buildContractDetailList(singletonList(contract)).get(0);
108 } 118 }
109 119
110 @GetMapping("/page") 120 @GetMapping("/page")
@@ -161,27 +171,35 @@ public class CrmContractController { @@ -161,27 +171,35 @@ public class CrmContractController {
161 if (CollUtil.isEmpty(contractList)) { 171 if (CollUtil.isEmpty(contractList)) {
162 return Collections.emptyList(); 172 return Collections.emptyList();
163 } 173 }
164 - // 1. 获取客户列表  
165 - List<CrmCustomerDO> customerList = customerService.getCustomerList( 174 + // 1.1 获取客户列表
  175 + Map<Long, CrmCustomerDO> customerMap = customerService.getCustomerMap(
166 convertSet(contractList, CrmContractDO::getCustomerId)); 176 convertSet(contractList, CrmContractDO::getCustomerId));
167 - // 2. 获取创建人、负责人列表 177 + // 1.2 获取创建人、负责人列表
168 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(contractList, 178 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(contractList,
169 contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); 179 contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
170 - // 3. 获取联系人 180 + Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
  181 + // 1.3 获取联系人
171 Map<Long, CrmContactDO> contactMap = convertMap(contactService.getContactList(convertSet(contractList, 182 Map<Long, CrmContactDO> contactMap = convertMap(contactService.getContactList(convertSet(contractList,
172 - CrmContractDO::getContactId)), CrmContactDO::getId);  
173 - // 4. 获取商机 183 + CrmContractDO::getSignContactId)), CrmContactDO::getId);
  184 + // 1.4 获取商机
174 Map<Long, CrmBusinessDO> businessMap = convertMap(businessService.getBusinessList(convertSet(contractList, 185 Map<Long, CrmBusinessDO> businessMap = convertMap(businessService.getBusinessList(convertSet(contractList,
175 CrmContractDO::getBusinessId)), CrmBusinessDO::getId); 186 CrmContractDO::getBusinessId)), CrmBusinessDO::getId);
176 - // 5. 获取合同关联的商品  
177 - Map<Long, CrmContractProductDO> contractProductMap = null;  
178 - List<CrmProductDO> productList = null;  
179 - if (contractList.size() == 1) {  
180 - List<CrmContractProductDO> contractProductList = contractService.getContractProductListByContractId(contractList.get(0).getId());  
181 - contractProductMap = convertMap(contractProductList, CrmContractProductDO::getProductId);  
182 - productList = productService.getProductList(convertSet(contractProductList, CrmContractProductDO::getProductId));  
183 - }  
184 - return CrmContractConvert.INSTANCE.convertList(contractList, userMap, customerList, contactMap, businessMap, contractProductMap, productList); 187 + // 2. 拼接数据
  188 + return BeanUtils.toBean(contractList, CrmContractRespVO.class, contractVO -> {
  189 + // 2.1 设置客户信息
  190 + findAndThen(customerMap, contractVO.getCustomerId(), customer -> contractVO.setCustomerName(customer.getName()));
  191 + // 2.2 设置用户信息
  192 + findAndThen(userMap, Long.parseLong(contractVO.getCreator()), user -> contractVO.setCreatorName(user.getNickname()));
  193 + MapUtils.findAndThen(userMap, contractVO.getOwnerUserId(), user -> {
  194 + contractVO.setOwnerUserName(user.getNickname());
  195 + MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> contractVO.setOwnerUserDeptName(dept.getName()));
  196 + });
  197 + findAndThen(userMap, contractVO.getSignUserId(), user -> contractVO.setSignUserName(user.getNickname()));
  198 + // 2.3 设置联系人信息
  199 + findAndThen(contactMap, contractVO.getSignContactId(), contact -> contractVO.setSignContactName(contact.getName()));
  200 + // 2.4 设置商机信息
  201 + findAndThen(businessMap, contractVO.getBusinessId(), business -> contractVO.setBusinessName(business.getName()));
  202 + });
185 } 203 }
186 204
187 @GetMapping("/check-contract-count") 205 @GetMapping("/check-contract-count")
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractRespVO.java
@@ -6,13 +6,11 @@ import io.swagger.v3.oas.annotations.media.Schema; @@ -6,13 +6,11 @@ import io.swagger.v3.oas.annotations.media.Schema;
6 import lombok.AllArgsConstructor; 6 import lombok.AllArgsConstructor;
7 import lombok.Data; 7 import lombok.Data;
8 import lombok.NoArgsConstructor; 8 import lombok.NoArgsConstructor;
9 -import org.springframework.format.annotation.DateTimeFormat;  
10 9
  10 +import java.math.BigDecimal;
11 import java.time.LocalDateTime; 11 import java.time.LocalDateTime;
12 import java.util.List; 12 import java.util.List;
13 13
14 -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;  
15 -  
16 @Schema(description = "管理后台 - CRM 合同 Response VO") 14 @Schema(description = "管理后台 - CRM 合同 Response VO")
17 @Data 15 @Data
18 @ExcelIgnoreUnannotated 16 @ExcelIgnoreUnannotated
@@ -26,6 +24,10 @@ public class CrmContractRespVO { @@ -26,6 +24,10 @@ public class CrmContractRespVO {
26 @ExcelProperty("合同名称") 24 @ExcelProperty("合同名称")
27 private String name; 25 private String name;
28 26
  27 + @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20230101")
  28 + @ExcelProperty("合同编号")
  29 + private String no;
  30 +
29 @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "18336") 31 @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "18336")
30 @ExcelProperty("客户编号") 32 @ExcelProperty("客户编号")
31 private Long customerId; 33 private Long customerId;
@@ -40,72 +42,70 @@ public class CrmContractRespVO { @@ -40,72 +42,70 @@ public class CrmContractRespVO {
40 @ExcelProperty("商机名称") 42 @ExcelProperty("商机名称")
41 private String businessName; 43 private String businessName;
42 44
  45 + @Schema(description = "最后跟进时间")
  46 + @ExcelProperty("最后跟进时间")
  47 + private LocalDateTime contactLastTime;
  48 +
  49 + @Schema(description = "负责人的用户编号", example = "25682")
  50 + @ExcelProperty("负责人的用户编号")
  51 + private Long ownerUserId;
  52 + @Schema(description = "负责人名字", example = "25682")
  53 + @ExcelProperty("负责人名字")
  54 + private String ownerUserName;
  55 + @Schema(description = "负责人部门")
  56 + @ExcelProperty("负责人部门")
  57 + private String ownerUserDeptName;
  58 +
43 @Schema(description = "工作流编号", example = "1043") 59 @Schema(description = "工作流编号", example = "1043")
44 @ExcelProperty("工作流编号") 60 @ExcelProperty("工作流编号")
45 private Long processInstanceId; 61 private Long processInstanceId;
46 62
  63 + @Schema(description = "审批状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  64 + @ExcelProperty("审批状态")
  65 + private Integer auditStatus;
  66 +
47 @Schema(description = "下单日期", requiredMode = Schema.RequiredMode.REQUIRED) 67 @Schema(description = "下单日期", requiredMode = Schema.RequiredMode.REQUIRED)
48 @ExcelProperty("下单日期") 68 @ExcelProperty("下单日期")
49 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
50 private LocalDateTime orderDate; 69 private LocalDateTime orderDate;
51 70
52 - @Schema(description = "负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17144")  
53 - @ExcelProperty("负责人的用户编号")  
54 - private Long ownerUserId;  
55 -  
56 - // TODO @芋艿:未来应该支持自动生成;  
57 - @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20230101")  
58 - @ExcelProperty("合同编号")  
59 - private String no;  
60 -  
61 @Schema(description = "开始时间") 71 @Schema(description = "开始时间")
62 @ExcelProperty("开始时间") 72 @ExcelProperty("开始时间")
63 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
64 private LocalDateTime startTime; 73 private LocalDateTime startTime;
65 74
66 @Schema(description = "结束时间") 75 @Schema(description = "结束时间")
67 @ExcelProperty("结束时间") 76 @ExcelProperty("结束时间")
68 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
69 private LocalDateTime endTime; 77 private LocalDateTime endTime;
70 78
71 - @Schema(description = "合同金额", example = "5617")  
72 - @ExcelProperty("合同金额")  
73 - private Integer price; 79 + @Schema(description = "产品总金额", example = "19510")
  80 + @ExcelProperty("产品总金额")
  81 + private BigDecimal totalProductPrice;
74 82
75 @Schema(description = "整单折扣") 83 @Schema(description = "整单折扣")
76 @ExcelProperty("整单折扣") 84 @ExcelProperty("整单折扣")
77 - private Integer discountPercent; 85 + private BigDecimal discountPercent;
78 86
79 - @Schema(description = "产品总金额", example = "19510")  
80 - @ExcelProperty("产品总金额")  
81 - private Integer productPrice; 87 + @Schema(description = "合同金额", example = "5617")
  88 + @ExcelProperty("合同金额")
  89 + private BigDecimal totalPrice;
82 90
83 - @Schema(description = "联系人编号", example = "18546")  
84 - @ExcelProperty("联系人编号")  
85 - private Long contactId;  
86 - @Schema(description = "联系人编号", example = "18546")  
87 - @ExcelProperty("联系人编号")  
88 - private String contactName; 91 + @Schema(description = "客户签约人编号", example = "18546")
  92 + private Long signContactId;
  93 + @Schema(description = "客户签约人", example = "小豆")
  94 + @ExcelProperty("客户签约人")
  95 + private String signContactName;
89 96
90 @Schema(description = "公司签约人", example = "14036") 97 @Schema(description = "公司签约人", example = "14036")
91 - @ExcelProperty("公司签约人")  
92 private Long signUserId; 98 private Long signUserId;
93 - @Schema(description = "公司签约人", example = "14036") 99 + @Schema(description = "公司签约人", example = "小明")
94 @ExcelProperty("公司签约人") 100 @ExcelProperty("公司签约人")
95 private String signUserName; 101 private String signUserName;
96 102
97 - @Schema(description = "最后跟进时间")  
98 - @ExcelProperty("最后跟进时间")  
99 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
100 - private LocalDateTime contactLastTime;  
101 -  
102 @Schema(description = "备注", example = "你猜") 103 @Schema(description = "备注", example = "你猜")
103 @ExcelProperty("备注") 104 @ExcelProperty("备注")
104 private String remark; 105 private String remark;
105 106
106 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 107 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
107 @ExcelProperty("创建时间") 108 @ExcelProperty("创建时间")
108 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
109 private LocalDateTime createTime; 109 private LocalDateTime createTime;
110 110
111 @Schema(description = "创建人", example = "25682") 111 @Schema(description = "创建人", example = "25682")
@@ -118,19 +118,10 @@ public class CrmContractRespVO { @@ -118,19 +118,10 @@ public class CrmContractRespVO {
118 118
119 @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED) 119 @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
120 @ExcelProperty("更新时间") 120 @ExcelProperty("更新时间")
121 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
122 private LocalDateTime updateTime; 121 private LocalDateTime updateTime;
123 122
124 - @Schema(description = "负责人", example = "test")  
125 - @ExcelProperty("负责人")  
126 - private String ownerUserName;  
127 -  
128 - @Schema(description = "审批状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")  
129 - @ExcelProperty("审批状态")  
130 - private Integer auditStatus;  
131 -  
132 @Schema(description = "产品列表") 123 @Schema(description = "产品列表")
133 - private List<Item> items; 124 + private List<Item> products;
134 125
135 @Schema(description = "产品列表") 126 @Schema(description = "产品列表")
136 @Data 127 @Data
@@ -138,26 +129,29 @@ public class CrmContractRespVO { @@ -138,26 +129,29 @@ public class CrmContractRespVO {
138 @AllArgsConstructor 129 @AllArgsConstructor
139 public static class Item { 130 public static class Item {
140 131
141 - @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529") 132 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "888")
142 private Long id; 133 private Long id;
143 134
144 - @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是产品")  
145 - private String name;  
146 -  
147 - @Schema(description = "产品编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "N881")  
148 - private String no; 135 + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529")
  136 + private Long productId;
  137 + @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
  138 + private String productName;
  139 + @Schema(description = "产品条码", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529")
  140 + private String productNo;
  141 + @Schema(description = "产品单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
  142 + private Integer productUnit;
149 143
150 - @Schema(description = "单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")  
151 - private Integer unit; 144 + @Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00")
  145 + private BigDecimal productPrice;
152 146
153 - @Schema(description = "价格,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")  
154 - private Integer price; 147 + @Schema(description = "合同价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00")
  148 + private BigDecimal businessPrice;
155 149
156 - @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")  
157 - private Integer count; 150 + @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911")
  151 + private BigDecimal count;
158 152
159 - @Schema(description = "产品折扣", example = "99")  
160 - private Integer discountPercent; 153 + @Schema(description = "总计价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00")
  154 + private BigDecimal totalPrice;
161 155
162 } 156 }
163 157
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractSaveReqVO.java
@@ -12,6 +12,7 @@ import lombok.Data; @@ -12,6 +12,7 @@ import lombok.Data;
12 import lombok.NoArgsConstructor; 12 import lombok.NoArgsConstructor;
13 import org.springframework.format.annotation.DateTimeFormat; 13 import org.springframework.format.annotation.DateTimeFormat;
14 14
  15 +import java.math.BigDecimal;
15 import java.time.LocalDateTime; 16 import java.time.LocalDateTime;
16 import java.util.List; 17 import java.util.List;
17 18
@@ -38,22 +39,16 @@ public class CrmContractSaveReqVO { @@ -38,22 +39,16 @@ public class CrmContractSaveReqVO {
38 @DiffLogField(name = "商机", function = CrmBusinessParseFunction.NAME) 39 @DiffLogField(name = "商机", function = CrmBusinessParseFunction.NAME)
39 private Long businessId; 40 private Long businessId;
40 41
41 - @Schema(description = "下单日期", requiredMode = Schema.RequiredMode.REQUIRED)  
42 - @DiffLogField(name = "下单日期")  
43 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
44 - @NotNull(message = "下单日期不能为空")  
45 - private LocalDateTime orderDate;  
46 -  
47 @Schema(description = "负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17144") 42 @Schema(description = "负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17144")
48 @DiffLogField(name = "负责人", function = SysAdminUserParseFunction.NAME) 43 @DiffLogField(name = "负责人", function = SysAdminUserParseFunction.NAME)
49 @NotNull(message = "负责人不能为空") 44 @NotNull(message = "负责人不能为空")
50 private Long ownerUserId; 45 private Long ownerUserId;
51 46
52 - // TODO @芋艿:未来应该支持自动生成;  
53 - @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20230101")  
54 - @DiffLogField(name = "合同编号")  
55 - @NotNull(message = "合同编号不能为空")  
56 - private String no; 47 + @Schema(description = "下单日期", requiredMode = Schema.RequiredMode.REQUIRED)
  48 + @DiffLogField(name = "下单日期")
  49 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  50 + @NotNull(message = "下单日期不能为空")
  51 + private LocalDateTime orderDate;
57 52
58 @Schema(description = "开始时间") 53 @Schema(description = "开始时间")
59 @DiffLogField(name = "开始时间") 54 @DiffLogField(name = "开始时间")
@@ -65,21 +60,18 @@ public class CrmContractSaveReqVO { @@ -65,21 +60,18 @@ public class CrmContractSaveReqVO {
65 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) 60 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
66 private LocalDateTime endTime; 61 private LocalDateTime endTime;
67 62
68 - @Schema(description = "合同金额", example = "5617")  
69 - @DiffLogField(name = "合同金额")  
70 - private Integer price;  
71 -  
72 - @Schema(description = "整单折扣") 63 + @Schema(description = "整单折扣", requiredMode = Schema.RequiredMode.REQUIRED, example = "55.00")
73 @DiffLogField(name = "整单折扣") 64 @DiffLogField(name = "整单折扣")
74 - private Integer discountPercent; 65 + @NotNull(message = "整单折扣不能为空")
  66 + private BigDecimal discountPercent;
75 67
76 - @Schema(description = "产品总金额", example = "19510")  
77 - @DiffLogField(name = "产品总金额")  
78 - private Integer productPrice; 68 + @Schema(description = "合同金额", example = "5617")
  69 + @DiffLogField(name = "合同金额")
  70 + private BigDecimal totalPrice;
79 71
80 - @Schema(description = "联系人编号", example = "18546")  
81 - @DiffLogField(name = "联系人", function = CrmContactParseFunction.NAME)  
82 - private Long contactId; 72 + @Schema(description = "客户签约人编号", example = "18546")
  73 + @DiffLogField(name = "客户签约人", function = CrmContactParseFunction.NAME)
  74 + private Long signContactId;
83 75
84 @Schema(description = "公司签约人", example = "14036") 76 @Schema(description = "公司签约人", example = "14036")
85 @DiffLogField(name = "公司签约人", function = SysAdminUserParseFunction.NAME) 77 @DiffLogField(name = "公司签约人", function = SysAdminUserParseFunction.NAME)
@@ -89,27 +81,31 @@ public class CrmContractSaveReqVO { @@ -89,27 +81,31 @@ public class CrmContractSaveReqVO {
89 @DiffLogField(name = "备注") 81 @DiffLogField(name = "备注")
90 private String remark; 82 private String remark;
91 83
92 -  
93 @Schema(description = "产品列表") 84 @Schema(description = "产品列表")
94 - private List<CrmContractProductItem> productItems; 85 + private List<Product> products;
95 86
96 @Schema(description = "产品列表") 87 @Schema(description = "产品列表")
97 @Data 88 @Data
98 @NoArgsConstructor 89 @NoArgsConstructor
99 @AllArgsConstructor 90 @AllArgsConstructor
100 - public static class CrmContractProductItem { 91 + public static class Product {
101 92
102 - @Schema(description = "产品编号", example = "20529") 93 + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529")
103 @NotNull(message = "产品编号不能为空") 94 @NotNull(message = "产品编号不能为空")
104 - private Long id; 95 + private Long productId;
  96 +
  97 + @Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00")
  98 + @NotNull(message = "产品单价不能为空")
  99 + private BigDecimal productPrice;
  100 +
  101 + @Schema(description = "合同价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00")
  102 + @NotNull(message = "合同价格不能为空")
  103 + private BigDecimal businessPrice;
105 104
106 @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") 105 @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911")
107 @NotNull(message = "产品数量不能为空") 106 @NotNull(message = "产品数量不能为空")
108 private Integer count; 107 private Integer count;
109 108
110 - @Schema(description = "产品折扣")  
111 - private Integer discountPercent;  
112 -  
113 } 109 }
114 110
115 } 111 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/CrmContractConvert.java deleted
1 -package cn.iocoder.yudao.module.crm.convert.contract;  
2 -  
3 -import cn.hutool.core.collection.CollUtil;  
4 -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;  
5 -import cn.iocoder.yudao.framework.common.util.object.BeanUtils;  
6 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractRespVO;  
7 -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO;  
8 -import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;  
9 -import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;  
10 -import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;  
11 -import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractProductDO;  
12 -import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;  
13 -import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO;  
14 -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;  
15 -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;  
16 -import org.mapstruct.Mapper;  
17 -import org.mapstruct.Mapping;  
18 -import org.mapstruct.factory.Mappers;  
19 -  
20 -import java.util.List;  
21 -import java.util.Map;  
22 -  
23 -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;  
24 -import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;  
25 -  
26 -/**  
27 - * 合同 Convert  
28 - *  
29 - * @author dhb52  
30 - */  
31 -@Mapper  
32 -public interface CrmContractConvert {  
33 -  
34 - CrmContractConvert INSTANCE = Mappers.getMapper(CrmContractConvert.class);  
35 -  
36 - @Mapping(target = "bizId", source = "reqVO.id")  
37 - CrmPermissionTransferReqBO convert(CrmContractTransferReqVO reqVO, Long userId);  
38 -  
39 - default List<CrmContractRespVO> convertList(List<CrmContractDO> contractList, Map<Long, AdminUserRespDTO> userMap,  
40 - List<CrmCustomerDO> customerList, Map<Long, CrmContactDO> contactMap,  
41 - Map<Long, CrmBusinessDO> businessMap, Map<Long, CrmContractProductDO> contractProductMap,  
42 - List<CrmProductDO> productList) {  
43 - List<CrmContractRespVO> respVOList = BeanUtils.toBean(contractList, CrmContractRespVO.class);  
44 - // 拼接关联字段  
45 - Map<Long, CrmCustomerDO> customerMap = convertMap(customerList, CrmCustomerDO::getId);  
46 - respVOList.forEach(contract -> {  
47 - findAndThen(userMap, contract.getOwnerUserId(), user -> contract.setOwnerUserName(user.getNickname()));  
48 - findAndThen(userMap, Long.parseLong(contract.getCreator()), user -> contract.setCreatorName(user.getNickname()));  
49 - findAndThen(userMap, contract.getSignUserId(), user -> contract.setSignUserName(user.getNickname()));  
50 - findAndThen(customerMap, contract.getCustomerId(), customer -> contract.setCustomerName(customer.getName()));  
51 - findAndThen(contactMap, contract.getContactId(), contact -> contract.setContactName(contact.getName()));  
52 - findAndThen(businessMap, contract.getBusinessId(), business -> contract.setBusinessName(business.getName()));  
53 - });  
54 - if (CollUtil.isNotEmpty(respVOList) && respVOList.size() == 1) {  
55 - setContractRespVOProductItems(respVOList.get(0), contractProductMap, productList);  
56 - }  
57 - return respVOList;  
58 - }  
59 -  
60 - default void setContractRespVOProductItems(CrmContractRespVO respVO, Map<Long, CrmContractProductDO> contractProductMap,  
61 - List<CrmProductDO> productList) {  
62 - respVO.setItems(CollectionUtils.convertList(productList, product -> {  
63 - CrmContractRespVO.Item productItemRespVO = BeanUtils.toBean(product, CrmContractRespVO.Item.class);  
64 - findAndThen(contractProductMap, product.getId(), contractProduct ->  
65 - productItemRespVO.setCount(contractProduct.getCount()).setDiscountPercent(contractProduct.getDiscountPercent()));  
66 - return productItemRespVO;  
67 - }));  
68 - }  
69 -  
70 -}  
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessProductDO.java
@@ -50,7 +50,7 @@ public class CrmBusinessProductDO extends BaseDO { @@ -50,7 +50,7 @@ public class CrmBusinessProductDO extends BaseDO {
50 */ 50 */
51 private BigDecimal productPrice; 51 private BigDecimal productPrice;
52 /** 52 /**
53 - * 合同价格, 单位:元 53 + * 商机价格, 单位:元
54 */ 54 */
55 private BigDecimal businessPrice; 55 private BigDecimal businessPrice;
56 /** 56 /**
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/CrmContractDO.java
@@ -10,9 +10,9 @@ import com.baomidou.mybatisplus.annotation.TableId; @@ -10,9 +10,9 @@ import com.baomidou.mybatisplus.annotation.TableId;
10 import com.baomidou.mybatisplus.annotation.TableName; 10 import com.baomidou.mybatisplus.annotation.TableName;
11 import lombok.*; 11 import lombok.*;
12 12
  13 +import java.math.BigDecimal;
13 import java.time.LocalDateTime; 14 import java.time.LocalDateTime;
14 15
15 -// TODO 芋艿:实体的梳理  
16 /** 16 /**
17 * CRM 合同 DO 17 * CRM 合同 DO
18 * 18 *
@@ -34,25 +34,38 @@ public class CrmContractDO extends BaseDO { @@ -34,25 +34,38 @@ public class CrmContractDO extends BaseDO {
34 @TableId 34 @TableId
35 private Long id; 35 private Long id;
36 /** 36 /**
37 - * 合同编号  
38 - */  
39 - private String no;  
40 - /**  
41 * 合同名称 37 * 合同名称
42 */ 38 */
43 private String name; 39 private String name;
44 /** 40 /**
  41 + * 合同编号
  42 + */
  43 + private String no;
  44 + /**
45 * 客户编号 45 * 客户编号
46 * 46 *
47 * 关联 {@link CrmCustomerDO#getId()} 47 * 关联 {@link CrmCustomerDO#getId()}
48 */ 48 */
49 private Long customerId; 49 private Long customerId;
50 /** 50 /**
51 - * 商机编号 51 + * 商机编号,非必须
52 * 52 *
53 * 关联 {@link CrmBusinessDO#getId()} 53 * 关联 {@link CrmBusinessDO#getId()}
54 */ 54 */
55 private Long businessId; 55 private Long businessId;
  56 +
  57 + /**
  58 + * 最后跟进时间
  59 + */
  60 + private LocalDateTime contactLastTime;
  61 +
  62 + /**
  63 + * 负责人的用户编号
  64 + *
  65 + * 关联 AdminUserDO 的 id 字段
  66 + */
  67 + private Long ownerUserId;
  68 +
56 /** 69 /**
57 * 工作流编号 70 * 工作流编号
58 * 71 *
@@ -60,6 +73,13 @@ public class CrmContractDO extends BaseDO { @@ -60,6 +73,13 @@ public class CrmContractDO extends BaseDO {
60 */ 73 */
61 private String processInstanceId; 74 private String processInstanceId;
62 /** 75 /**
  76 + * 审批状态
  77 + *
  78 + * 枚举 {@link CrmAuditStatusEnum}
  79 + */
  80 + private Integer auditStatus;
  81 +
  82 + /**
63 * 下单日期 83 * 下单日期
64 */ 84 */
65 private LocalDateTime orderDate; 85 private LocalDateTime orderDate;
@@ -72,50 +92,32 @@ public class CrmContractDO extends BaseDO { @@ -72,50 +92,32 @@ public class CrmContractDO extends BaseDO {
72 */ 92 */
73 private LocalDateTime endTime; 93 private LocalDateTime endTime;
74 /** 94 /**
75 - * 合同金额,单位:分 95 + * 产品总金额,单位:元
76 */ 96 */
77 - private Integer price; 97 + private BigDecimal totalProductPrice;
78 /** 98 /**
79 * 整单折扣 99 * 整单折扣
80 */ 100 */
81 - private Integer discountPercent; 101 + private BigDecimal discountPercent;
82 /** 102 /**
83 - * 产品总金额,单位:分 103 + * 合同总金额,单位:分
84 */ 104 */
85 - private Integer productPrice; 105 + private BigDecimal totalPrice;
86 /** 106 /**
87 - * 客户签约人 107 + * 客户签约人,非必须
88 * 108 *
89 * 关联 {@link CrmContactDO#getId()} 109 * 关联 {@link CrmContactDO#getId()}
90 */ 110 */
91 - private Long contactId; 111 + private Long signContactId;
92 /** 112 /**
93 - * 公司签约人 113 + * 公司签约人,非必须
94 * 114 *
95 * 关联 AdminUserDO 的 id 字段 115 * 关联 AdminUserDO 的 id 字段
96 */ 116 */
97 private Long signUserId; 117 private Long signUserId;
98 /** 118 /**
99 - * 最后跟进时间  
100 - */  
101 - private LocalDateTime contactLastTime;  
102 - /**  
103 * 备注 119 * 备注
104 */ 120 */
105 private String remark; 121 private String remark;
106 122
107 - /**  
108 - * 负责人的用户编号  
109 - *  
110 - * 关联 AdminUserDO 的 id 字段  
111 - */  
112 - private Long ownerUserId;  
113 -  
114 - /**  
115 - * 审批状态  
116 - *  
117 - * 枚举 {@link CrmAuditStatusEnum}  
118 - */  
119 - private Integer auditStatus;  
120 -  
121 } 123 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/CrmContractProductDO.java
@@ -7,8 +7,10 @@ import com.baomidou.mybatisplus.annotation.TableId; @@ -7,8 +7,10 @@ import com.baomidou.mybatisplus.annotation.TableId;
7 import com.baomidou.mybatisplus.annotation.TableName; 7 import com.baomidou.mybatisplus.annotation.TableName;
8 import lombok.*; 8 import lombok.*;
9 9
  10 +import java.math.BigDecimal;
  11 +
10 /** 12 /**
11 - * 合同产品关联表 DO 13 + * CRM 合同产品关联表 DO
12 * 14 *
13 * @author HUIHUI 15 * @author HUIHUI
14 */ 16 */
@@ -28,38 +30,33 @@ public class CrmContractProductDO extends BaseDO { @@ -28,38 +30,33 @@ public class CrmContractProductDO extends BaseDO {
28 @TableId 30 @TableId
29 private Long id; 31 private Long id;
30 /** 32 /**
31 - * 产品编号  
32 - *  
33 - * 关联 {@link CrmProductDO#getId()}  
34 - */  
35 - private Long productId;  
36 - /**  
37 * 合同编号 33 * 合同编号
38 * 34 *
39 * 关联 {@link CrmContractDO#getId()} 35 * 关联 {@link CrmContractDO#getId()}
40 */ 36 */
41 private Long contractId; 37 private Long contractId;
42 /** 38 /**
43 - * 产品单价 39 + * 产品编号
  40 + *
  41 + * 关联 {@link CrmProductDO#getId()}
44 */ 42 */
45 - private Integer price; 43 + private Long productId;
46 /** 44 /**
47 - * 销售价格, 单位:分 45 + * 产品单价,单位:元
48 */ 46 */
49 - private Integer salesPrice; 47 + private Integer productPrice;
50 /** 48 /**
51 - * 数量 49 + * 合同价格, 单位:分
52 */ 50 */
53 - private Integer count; 51 + private BigDecimal contractPrice;
54 /** 52 /**
55 - * 折扣 53 + * 数量
56 */ 54 */
57 - private Integer discountPercent; 55 + private BigDecimal count;
58 /** 56 /**
59 - * 总计价格(折扣后价格)  
60 - * = {@link #price}  
61 - * * {@link #count}  
62 - * * ({@link #discountPercent / 100}) 57 + * 总计价格,单位:元
  58 + *
  59 + * totalPrice = businessPrice * count
63 */ 60 */
64 private Integer totalPrice; 61 private Integer totalPrice;
65 62
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java
@@ -81,7 +81,7 @@ public interface CrmContractMapper extends BaseMapperX&lt;CrmContractDO&gt; { @@ -81,7 +81,7 @@ public interface CrmContractMapper extends BaseMapperX&lt;CrmContractDO&gt; {
81 } 81 }
82 82
83 default Long selectCountByContactId(Long contactId) { 83 default Long selectCountByContactId(Long contactId) {
84 - return selectCount(CrmContractDO::getContactId, contactId); 84 + return selectCount(CrmContractDO::getSignContactId, contactId);
85 } 85 }
86 86
87 default Long selectCountByBusinessId(Long businessId) { 87 default Long selectCountByBusinessId(Long businessId) {
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java
@@ -141,7 +141,6 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -141,7 +141,6 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
141 // 2.2 更新商机关联商品 141 // 2.2 更新商机关联商品
142 updateBusinessProduct(updateObj.getId(), businessProducts); 142 updateBusinessProduct(updateObj.getId(), businessProducts);
143 143
144 - // TODO @商机待定:如果状态发生变化,插入商机状态变更记录表  
145 // 3. 记录操作日志上下文 144 // 3. 记录操作日志上下文
146 LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldBusiness, CrmBusinessSaveReqVO.class)); 145 LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldBusiness, CrmBusinessSaveReqVO.class));
147 LogRecordContext.putVariable("businessName", oldBusiness.getName()); 146 LogRecordContext.putVariable("businessName", oldBusiness.getName());
@@ -264,7 +263,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @@ -264,7 +263,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
264 // 1.2 校验是否关联合同 263 // 1.2 校验是否关联合同
265 validateContractExists(id); 264 validateContractExists(id);
266 265
267 - // 删除 266 + // 删除商机
268 businessMapper.deleteById(id); 267 businessMapper.deleteById(id);
269 // 删除数据权限 268 // 删除数据权限
270 permissionService.deletePermission(CrmBizTypeEnum.CRM_BUSINESS.getType(), id); 269 permissionService.deletePermission(CrmBizTypeEnum.CRM_BUSINESS.getType(), id);
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java
@@ -5,7 +5,6 @@ import cn.hutool.core.collection.ListUtil; @@ -5,7 +5,6 @@ import cn.hutool.core.collection.ListUtil;
5 import cn.hutool.core.lang.Assert; 5 import cn.hutool.core.lang.Assert;
6 import cn.hutool.core.util.ObjUtil; 6 import cn.hutool.core.util.ObjUtil;
7 import cn.iocoder.yudao.framework.common.pojo.PageResult; 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
8 -import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;  
9 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 8 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
10 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; 9 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
11 import cn.iocoder.yudao.module.bpm.api.listener.dto.BpmResultListenerRespDTO; 10 import cn.iocoder.yudao.module.bpm.api.listener.dto.BpmResultListenerRespDTO;
@@ -15,7 +14,6 @@ import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; @@ -15,7 +14,6 @@ import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
15 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO; 14 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO;
16 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractSaveReqVO; 15 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractSaveReqVO;
17 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; 16 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO;
18 -import cn.iocoder.yudao.module.crm.convert.contract.CrmContractConvert;  
19 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; 17 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
20 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractProductDO; 18 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractProductDO;
21 import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; 19 import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO;
@@ -31,6 +29,7 @@ import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; @@ -31,6 +29,7 @@ import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
31 import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO; 29 import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO;
32 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; 30 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
33 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; 31 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
  32 +import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
34 import cn.iocoder.yudao.module.crm.service.product.CrmProductService; 33 import cn.iocoder.yudao.module.crm.service.product.CrmProductService;
35 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 34 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
36 import com.mzt.logapi.context.LogRecordContext; 35 import com.mzt.logapi.context.LogRecordContext;
@@ -95,16 +94,16 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -95,16 +94,16 @@ public class CrmContractServiceImpl implements CrmContractService {
95 CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class).setId(null); 94 CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class).setId(null);
96 contractMapper.insert(contract); 95 contractMapper.insert(contract);
97 // 1.2 插入合同关联商品 96 // 1.2 插入合同关联商品
98 - if (CollUtil.isNotEmpty(createReqVO.getProductItems())) { // 如果有的话 97 + if (CollUtil.isNotEmpty(createReqVO.getProducts())) { // 如果有的话
99 List<CrmContractProductDO> productList = convertContractProductList(createReqVO, contract.getId()); 98 List<CrmContractProductDO> productList = convertContractProductList(createReqVO, contract.getId());
100 contractProductMapper.insertBatch(productList); 99 contractProductMapper.insertBatch(productList);
101 - // 更新合同商品总金额  
102 - contractMapper.updateById(new CrmContractDO().setId(contract.getId()).setProductPrice(  
103 - getSumValue(productList, CrmContractProductDO::getTotalPrice, Integer::sum))); 100 + // 更新合同商品总金额 TODO 芋艿
  101 +// contractMapper.updateById(new CrmContractDO().setId(contract.getId()).setTotalProductPrice(
  102 +// getSumValue(productList, CrmContractProductDO::getTotalPrice, Integer::sum)));
104 // 如果存在合同关联了商机则更新商机商品关联 103 // 如果存在合同关联了商机则更新商机商品关联
105 if (contract.getBusinessId() != null) { 104 if (contract.getBusinessId() != null) {
106 businessService.updateBusinessProduct(new CrmBusinessUpdateProductReqBO().setId(contract.getBusinessId()) 105 businessService.updateBusinessProduct(new CrmBusinessUpdateProductReqBO().setId(contract.getBusinessId())
107 - .setItems(BeanUtils.toBean(createReqVO.getProductItems(), CrmBusinessUpdateProductReqBO.Item.class))); 106 + .setItems(BeanUtils.toBean(createReqVO.getProducts(), CrmBusinessUpdateProductReqBO.Item.class)));
108 } 107 }
109 } 108 }
110 109
@@ -146,7 +145,7 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -146,7 +145,7 @@ public class CrmContractServiceImpl implements CrmContractService {
146 } 145 }
147 146
148 private void updateContractProduct(CrmContractSaveReqVO updateReqVO, Long contractId) { 147 private void updateContractProduct(CrmContractSaveReqVO updateReqVO, Long contractId) {
149 - if (CollUtil.isEmpty(updateReqVO.getProductItems())) { 148 + if (CollUtil.isEmpty(updateReqVO.getProducts())) {
150 return; 149 return;
151 } 150 }
152 List<CrmContractProductDO> newProductList = convertContractProductList(updateReqVO, contractId); 151 List<CrmContractProductDO> newProductList = convertContractProductList(updateReqVO, contractId);
@@ -173,20 +172,22 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -173,20 +172,22 @@ public class CrmContractServiceImpl implements CrmContractService {
173 172
174 private List<CrmContractProductDO> convertContractProductList(CrmContractSaveReqVO reqVO, Long contractId) { 173 private List<CrmContractProductDO> convertContractProductList(CrmContractSaveReqVO reqVO, Long contractId) {
175 // 校验商品存在 174 // 校验商品存在
176 - Set<Long> productIds = convertSet(reqVO.getProductItems(), CrmContractSaveReqVO.CrmContractProductItem::getId); 175 + Set<Long> productIds = convertSet(reqVO.getProducts(), CrmContractSaveReqVO.Product::getProductId);
177 List<CrmProductDO> productList = productService.getProductList(productIds); 176 List<CrmProductDO> productList = productService.getProductList(productIds);
178 if (CollUtil.isEmpty(productIds) || productList.size() != productIds.size()) { 177 if (CollUtil.isEmpty(productIds) || productList.size() != productIds.size()) {
179 throw exception(PRODUCT_NOT_EXISTS); 178 throw exception(PRODUCT_NOT_EXISTS);
180 } 179 }
181 Map<Long, CrmProductDO> productMap = convertMap(productList, CrmProductDO::getId); 180 Map<Long, CrmProductDO> productMap = convertMap(productList, CrmProductDO::getId);
182 - return convertList(reqVO.getProductItems(), productItem -> {  
183 - CrmProductDO product = productMap.get(productItem.getId());  
184 - return BeanUtils.toBean(product, CrmContractProductDO.class)  
185 - .setId(null).setProductId(productItem.getId()).setContractId(contractId)  
186 - .setCount(productItem.getCount()).setDiscountPercent(productItem.getDiscountPercent())  
187 - // TODO 芋艿:这里临时注释掉  
188 - .setTotalPrice(MoneyUtils.calculator(null, productItem.getCount(), productItem.getDiscountPercent()));  
189 - }); 181 + // TODO 芋艿
  182 + return null;
  183 +// return convertList(reqVO.getProducts(), productItem -> {
  184 +// CrmProductDO product = productMap.get(productItem.getId());
  185 +// return BeanUtils.toBean(product, CrmContractProductDO.class)
  186 +// .setId(null).setProductId(productItem.getId()).setContractId(contractId)
  187 +// .setCount(productItem.getCount()).setDiscountPercent(productItem.getDiscountPercent())
  188 +// // TODO 芋艿:这里临时注释掉
  189 +// .setTotalPrice(MoneyUtils.calculator(null, productItem.getCount(), productItem.getDiscountPercent()));
  190 +// });
190 } 191 }
191 192
192 /** 193 /**
@@ -245,8 +246,8 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -245,8 +246,8 @@ public class CrmContractServiceImpl implements CrmContractService {
245 CrmContractDO contract = validateContractExists(reqVO.getId()); 246 CrmContractDO contract = validateContractExists(reqVO.getId());
246 247
247 // 2.1 数据权限转移 248 // 2.1 数据权限转移
248 - crmPermissionService.transferPermission(  
249 - CrmContractConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType())); 249 + crmPermissionService.transferPermission(new CrmPermissionTransferReqBO(userId, CrmBizTypeEnum.CRM_CONTRACT.getType(),
  250 + reqVO.getId(), reqVO.getNewOwnerUserId(), reqVO.getOldOwnerPermissionLevel()));
250 // 2.2 设置负责人 251 // 2.2 设置负责人
251 contractMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId()); 252 contractMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());
252 253