Commit ef26b5e8dc2512aab50bb25d52c8f92a8ef7ab01
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<CrmContractDO> { | @@ -81,7 +81,7 @@ public interface CrmContractMapper extends BaseMapperX<CrmContractDO> { | ||
| 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 |