diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessRespVO.java index bbea613c8..49cdcb80b 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessRespVO.java +++ b/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 { @Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") private BigDecimal productPrice; - @Schema(description = "合同价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") + @Schema(description = "商机价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") private BigDecimal businessPrice; @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java index 8b0c53d21..a9ebaae05 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java +++ b/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 { @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime dealTime; - @Schema(description = "整单折扣") + @Schema(description = "整单折扣", requiredMode = Schema.RequiredMode.REQUIRED, example = "55.00") @DiffLogField(name = "整单折扣") @NotNull(message = "整单折扣不能为空") private BigDecimal discountPercent; @@ -82,8 +82,8 @@ public class CrmBusinessSaveReqVO { @NotNull(message = "产品单价不能为空") private BigDecimal productPrice; - @Schema(description = "合同价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") - @NotNull(message = "合同价格不能为空") + @Schema(description = "商机价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") + @NotNull(message = "商机价格不能为空") private BigDecimal businessPrice; @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java index d691a1701..65226866f 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java +++ b/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; import cn.hutool.core.lang.Assert; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; @@ -12,18 +13,17 @@ import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageR import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractRespVO; import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractSaveReqVO; import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; -import cn.iocoder.yudao.module.crm.convert.contract.CrmContractConvert; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractProductDO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService; import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; import cn.iocoder.yudao.module.crm.service.product.CrmProductService; +import cn.iocoder.yudao.module.system.api.dept.DeptApi; +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import io.swagger.v3.oas.annotations.Operation; @@ -44,6 +44,7 @@ import java.util.stream.Stream; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; import static java.util.Collections.singletonList; @@ -64,8 +65,11 @@ public class CrmContractController { private CrmBusinessService businessService; @Resource private CrmProductService productService; + @Resource private AdminUserApi adminUserApi; + @Resource + private DeptApi deptApi; @PostMapping("/create") @Operation(summary = "创建合同") @@ -96,15 +100,21 @@ public class CrmContractController { @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('crm:contract:query')") public CommonResult getContract(@RequestParam("id") Long id) { - // 1. 查询合同 CrmContractDO contract = contractService.getContract(id); - if (contract == null) { - return success(null); - } + return success(buildContractDetail(contract)); + } - // 2. 拼接合同信息 - List respVOList = buildContractDetailList(singletonList(contract)); - return success(respVOList.get(0)); + private CrmContractRespVO buildContractDetail(CrmContractDO contract) { + if (contract == null) { + return null; + } +// List productList = null; +// if (contractList.size() == 1) { +// List contractProductList = contractService.getContractProductListByContractId(contractList.get(0).getId()); +// contractProductMap = convertMap(contractProductList, CrmContractProductDO::getProductId); +// productList = productService.getProductList(convertSet(contractProductList, CrmContractProductDO::getProductId)); +// } + return buildContractDetailList(singletonList(contract)).get(0); } @GetMapping("/page") @@ -161,27 +171,35 @@ public class CrmContractController { if (CollUtil.isEmpty(contractList)) { return Collections.emptyList(); } - // 1. 获取客户列表 - List customerList = customerService.getCustomerList( + // 1.1 获取客户列表 + Map customerMap = customerService.getCustomerMap( convertSet(contractList, CrmContractDO::getCustomerId)); - // 2. 获取创建人、负责人列表 + // 1.2 获取创建人、负责人列表 Map userMap = adminUserApi.getUserMap(convertListByFlatMap(contractList, contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); - // 3. 获取联系人 + Map deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId)); + // 1.3 获取联系人 Map contactMap = convertMap(contactService.getContactList(convertSet(contractList, - CrmContractDO::getContactId)), CrmContactDO::getId); - // 4. 获取商机 + CrmContractDO::getSignContactId)), CrmContactDO::getId); + // 1.4 获取商机 Map businessMap = convertMap(businessService.getBusinessList(convertSet(contractList, CrmContractDO::getBusinessId)), CrmBusinessDO::getId); - // 5. 获取合同关联的商品 - Map contractProductMap = null; - List productList = null; - if (contractList.size() == 1) { - List contractProductList = contractService.getContractProductListByContractId(contractList.get(0).getId()); - contractProductMap = convertMap(contractProductList, CrmContractProductDO::getProductId); - productList = productService.getProductList(convertSet(contractProductList, CrmContractProductDO::getProductId)); - } - return CrmContractConvert.INSTANCE.convertList(contractList, userMap, customerList, contactMap, businessMap, contractProductMap, productList); + // 2. 拼接数据 + return BeanUtils.toBean(contractList, CrmContractRespVO.class, contractVO -> { + // 2.1 设置客户信息 + findAndThen(customerMap, contractVO.getCustomerId(), customer -> contractVO.setCustomerName(customer.getName())); + // 2.2 设置用户信息 + findAndThen(userMap, Long.parseLong(contractVO.getCreator()), user -> contractVO.setCreatorName(user.getNickname())); + MapUtils.findAndThen(userMap, contractVO.getOwnerUserId(), user -> { + contractVO.setOwnerUserName(user.getNickname()); + MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> contractVO.setOwnerUserDeptName(dept.getName())); + }); + findAndThen(userMap, contractVO.getSignUserId(), user -> contractVO.setSignUserName(user.getNickname())); + // 2.3 设置联系人信息 + findAndThen(contactMap, contractVO.getSignContactId(), contact -> contractVO.setSignContactName(contact.getName())); + // 2.4 设置商机信息 + findAndThen(businessMap, contractVO.getBusinessId(), business -> contractVO.setBusinessName(business.getName())); + }); } @GetMapping("/check-contract-count") diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractRespVO.java index 554e285dd..738cfaa79 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractRespVO.java +++ b/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; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -import org.springframework.format.annotation.DateTimeFormat; +import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.List; -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - @Schema(description = "管理后台 - CRM 合同 Response VO") @Data @ExcelIgnoreUnannotated @@ -26,6 +24,10 @@ public class CrmContractRespVO { @ExcelProperty("合同名称") private String name; + @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20230101") + @ExcelProperty("合同编号") + private String no; + @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "18336") @ExcelProperty("客户编号") private Long customerId; @@ -40,72 +42,70 @@ public class CrmContractRespVO { @ExcelProperty("商机名称") private String businessName; + @Schema(description = "最后跟进时间") + @ExcelProperty("最后跟进时间") + private LocalDateTime contactLastTime; + + @Schema(description = "负责人的用户编号", example = "25682") + @ExcelProperty("负责人的用户编号") + private Long ownerUserId; + @Schema(description = "负责人名字", example = "25682") + @ExcelProperty("负责人名字") + private String ownerUserName; + @Schema(description = "负责人部门") + @ExcelProperty("负责人部门") + private String ownerUserDeptName; + @Schema(description = "工作流编号", example = "1043") @ExcelProperty("工作流编号") private Long processInstanceId; + @Schema(description = "审批状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") + @ExcelProperty("审批状态") + private Integer auditStatus; + @Schema(description = "下单日期", requiredMode = Schema.RequiredMode.REQUIRED) @ExcelProperty("下单日期") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime orderDate; - @Schema(description = "负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17144") - @ExcelProperty("负责人的用户编号") - private Long ownerUserId; - - // TODO @芋艿:未来应该支持自动生成; - @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20230101") - @ExcelProperty("合同编号") - private String no; - @Schema(description = "开始时间") @ExcelProperty("开始时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime startTime; @Schema(description = "结束时间") @ExcelProperty("结束时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime endTime; - @Schema(description = "合同金额", example = "5617") - @ExcelProperty("合同金额") - private Integer price; - - @Schema(description = "整单折扣") - @ExcelProperty("整单折扣") - private Integer discountPercent; - @Schema(description = "产品总金额", example = "19510") @ExcelProperty("产品总金额") - private Integer productPrice; + private BigDecimal totalProductPrice; - @Schema(description = "联系人编号", example = "18546") - @ExcelProperty("联系人编号") - private Long contactId; - @Schema(description = "联系人编号", example = "18546") - @ExcelProperty("联系人编号") - private String contactName; + @Schema(description = "整单折扣") + @ExcelProperty("整单折扣") + private BigDecimal discountPercent; + + @Schema(description = "合同金额", example = "5617") + @ExcelProperty("合同金额") + private BigDecimal totalPrice; + + @Schema(description = "客户签约人编号", example = "18546") + private Long signContactId; + @Schema(description = "客户签约人", example = "小豆") + @ExcelProperty("客户签约人") + private String signContactName; @Schema(description = "公司签约人", example = "14036") - @ExcelProperty("公司签约人") private Long signUserId; - @Schema(description = "公司签约人", example = "14036") + @Schema(description = "公司签约人", example = "小明") @ExcelProperty("公司签约人") private String signUserName; - @Schema(description = "最后跟进时间") - @ExcelProperty("最后跟进时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime contactLastTime; - @Schema(description = "备注", example = "你猜") @ExcelProperty("备注") private String remark; @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @ExcelProperty("创建时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime createTime; @Schema(description = "创建人", example = "25682") @@ -118,19 +118,10 @@ public class CrmContractRespVO { @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED) @ExcelProperty("更新时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime updateTime; - @Schema(description = "负责人", example = "test") - @ExcelProperty("负责人") - private String ownerUserName; - - @Schema(description = "审批状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") - @ExcelProperty("审批状态") - private Integer auditStatus; - @Schema(description = "产品列表") - private List items; + private List products; @Schema(description = "产品列表") @Data @@ -138,26 +129,29 @@ public class CrmContractRespVO { @AllArgsConstructor public static class Item { - @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529") + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "888") private Long id; - @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "我是产品") - private String name; + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529") + private Long productId; + @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") + private String productName; + @Schema(description = "产品条码", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529") + private String productNo; + @Schema(description = "产品单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") + private Integer productUnit; - @Schema(description = "产品编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "N881") - private String no; + @Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") + private BigDecimal productPrice; - @Schema(description = "单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") - private Integer unit; + @Schema(description = "合同价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") + private BigDecimal businessPrice; - @Schema(description = "价格,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") - private Integer price; + @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") + private BigDecimal count; - @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "20") - private Integer count; - - @Schema(description = "产品折扣", example = "99") - private Integer discountPercent; + @Schema(description = "总计价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") + private BigDecimal totalPrice; } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractSaveReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractSaveReqVO.java index 20b20580e..423c0ab93 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractSaveReqVO.java +++ b/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; import lombok.NoArgsConstructor; import org.springframework.format.annotation.DateTimeFormat; +import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.List; @@ -38,22 +39,16 @@ public class CrmContractSaveReqVO { @DiffLogField(name = "商机", function = CrmBusinessParseFunction.NAME) private Long businessId; - @Schema(description = "下单日期", requiredMode = Schema.RequiredMode.REQUIRED) - @DiffLogField(name = "下单日期") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @NotNull(message = "下单日期不能为空") - private LocalDateTime orderDate; - @Schema(description = "负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17144") @DiffLogField(name = "负责人", function = SysAdminUserParseFunction.NAME) @NotNull(message = "负责人不能为空") private Long ownerUserId; - // TODO @芋艿:未来应该支持自动生成; - @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20230101") - @DiffLogField(name = "合同编号") - @NotNull(message = "合同编号不能为空") - private String no; + @Schema(description = "下单日期", requiredMode = Schema.RequiredMode.REQUIRED) + @DiffLogField(name = "下单日期") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @NotNull(message = "下单日期不能为空") + private LocalDateTime orderDate; @Schema(description = "开始时间") @DiffLogField(name = "开始时间") @@ -65,21 +60,18 @@ public class CrmContractSaveReqVO { @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime endTime; + @Schema(description = "整单折扣", requiredMode = Schema.RequiredMode.REQUIRED, example = "55.00") + @DiffLogField(name = "整单折扣") + @NotNull(message = "整单折扣不能为空") + private BigDecimal discountPercent; + @Schema(description = "合同金额", example = "5617") @DiffLogField(name = "合同金额") - private Integer price; + private BigDecimal totalPrice; - @Schema(description = "整单折扣") - @DiffLogField(name = "整单折扣") - private Integer discountPercent; - - @Schema(description = "产品总金额", example = "19510") - @DiffLogField(name = "产品总金额") - private Integer productPrice; - - @Schema(description = "联系人编号", example = "18546") - @DiffLogField(name = "联系人", function = CrmContactParseFunction.NAME) - private Long contactId; + @Schema(description = "客户签约人编号", example = "18546") + @DiffLogField(name = "客户签约人", function = CrmContactParseFunction.NAME) + private Long signContactId; @Schema(description = "公司签约人", example = "14036") @DiffLogField(name = "公司签约人", function = SysAdminUserParseFunction.NAME) @@ -89,27 +81,31 @@ public class CrmContractSaveReqVO { @DiffLogField(name = "备注") private String remark; - @Schema(description = "产品列表") - private List productItems; + private List products; @Schema(description = "产品列表") @Data @NoArgsConstructor @AllArgsConstructor - public static class CrmContractProductItem { + public static class Product { - @Schema(description = "产品编号", example = "20529") + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529") @NotNull(message = "产品编号不能为空") - private Long id; + private Long productId; + + @Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") + @NotNull(message = "产品单价不能为空") + private BigDecimal productPrice; + + @Schema(description = "合同价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") + @NotNull(message = "合同价格不能为空") + private BigDecimal businessPrice; @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") @NotNull(message = "产品数量不能为空") private Integer count; - @Schema(description = "产品折扣") - private Integer discountPercent; - } } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/CrmContractConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/CrmContractConvert.java deleted file mode 100644 index 0b816f37a..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contract/CrmContractConvert.java +++ /dev/null @@ -1,70 +0,0 @@ -package cn.iocoder.yudao.module.crm.convert.contract; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractRespVO; -import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; -import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractProductDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; -import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.factory.Mappers; - -import java.util.List; -import java.util.Map; - -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; -import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; - -/** - * 合同 Convert - * - * @author dhb52 - */ -@Mapper -public interface CrmContractConvert { - - CrmContractConvert INSTANCE = Mappers.getMapper(CrmContractConvert.class); - - @Mapping(target = "bizId", source = "reqVO.id") - CrmPermissionTransferReqBO convert(CrmContractTransferReqVO reqVO, Long userId); - - default List convertList(List contractList, Map userMap, - List customerList, Map contactMap, - Map businessMap, Map contractProductMap, - List productList) { - List respVOList = BeanUtils.toBean(contractList, CrmContractRespVO.class); - // 拼接关联字段 - Map customerMap = convertMap(customerList, CrmCustomerDO::getId); - respVOList.forEach(contract -> { - findAndThen(userMap, contract.getOwnerUserId(), user -> contract.setOwnerUserName(user.getNickname())); - findAndThen(userMap, Long.parseLong(contract.getCreator()), user -> contract.setCreatorName(user.getNickname())); - findAndThen(userMap, contract.getSignUserId(), user -> contract.setSignUserName(user.getNickname())); - findAndThen(customerMap, contract.getCustomerId(), customer -> contract.setCustomerName(customer.getName())); - findAndThen(contactMap, contract.getContactId(), contact -> contract.setContactName(contact.getName())); - findAndThen(businessMap, contract.getBusinessId(), business -> contract.setBusinessName(business.getName())); - }); - if (CollUtil.isNotEmpty(respVOList) && respVOList.size() == 1) { - setContractRespVOProductItems(respVOList.get(0), contractProductMap, productList); - } - return respVOList; - } - - default void setContractRespVOProductItems(CrmContractRespVO respVO, Map contractProductMap, - List productList) { - respVO.setItems(CollectionUtils.convertList(productList, product -> { - CrmContractRespVO.Item productItemRespVO = BeanUtils.toBean(product, CrmContractRespVO.Item.class); - findAndThen(contractProductMap, product.getId(), contractProduct -> - productItemRespVO.setCount(contractProduct.getCount()).setDiscountPercent(contractProduct.getDiscountPercent())); - return productItemRespVO; - })); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessProductDO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessProductDO.java index 16990dcc5..2f66fc34d 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessProductDO.java +++ b/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 { */ private BigDecimal productPrice; /** - * 合同价格, 单位:元 + * 商机价格, 单位:元 */ private BigDecimal businessPrice; /** diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/CrmContractDO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/CrmContractDO.java index 0c01a3394..89f4fd98a 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/CrmContractDO.java +++ b/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; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; +import java.math.BigDecimal; import java.time.LocalDateTime; -// TODO 芋艿:实体的梳理 /** * CRM 合同 DO * @@ -33,14 +33,14 @@ public class CrmContractDO extends BaseDO { */ @TableId private Long id; - /** - * 合同编号 - */ - private String no; /** * 合同名称 */ private String name; + /** + * 合同编号 + */ + private String no; /** * 客户编号 * @@ -48,17 +48,37 @@ public class CrmContractDO extends BaseDO { */ private Long customerId; /** - * 商机编号 + * 商机编号,非必须 * * 关联 {@link CrmBusinessDO#getId()} */ private Long businessId; + + /** + * 最后跟进时间 + */ + private LocalDateTime contactLastTime; + + /** + * 负责人的用户编号 + * + * 关联 AdminUserDO 的 id 字段 + */ + private Long ownerUserId; + /** * 工作流编号 * * 关联 ProcessInstance 的 id 属性 */ private String processInstanceId; + /** + * 审批状态 + * + * 枚举 {@link CrmAuditStatusEnum} + */ + private Integer auditStatus; + /** * 下单日期 */ @@ -72,50 +92,32 @@ public class CrmContractDO extends BaseDO { */ private LocalDateTime endTime; /** - * 合同金额,单位:分 + * 产品总金额,单位:元 */ - private Integer price; + private BigDecimal totalProductPrice; /** * 整单折扣 */ - private Integer discountPercent; + private BigDecimal discountPercent; /** - * 产品总金额,单位:分 + * 合同总金额,单位:分 */ - private Integer productPrice; + private BigDecimal totalPrice; /** - * 客户签约人 + * 客户签约人,非必须 * * 关联 {@link CrmContactDO#getId()} */ - private Long contactId; + private Long signContactId; /** - * 公司签约人 + * 公司签约人,非必须 * * 关联 AdminUserDO 的 id 字段 */ private Long signUserId; - /** - * 最后跟进时间 - */ - private LocalDateTime contactLastTime; /** * 备注 */ private String remark; - /** - * 负责人的用户编号 - * - * 关联 AdminUserDO 的 id 字段 - */ - private Long ownerUserId; - - /** - * 审批状态 - * - * 枚举 {@link CrmAuditStatusEnum} - */ - private Integer auditStatus; - } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/CrmContractProductDO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/CrmContractProductDO.java index d0489e490..88ded4391 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/CrmContractProductDO.java +++ b/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; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; +import java.math.BigDecimal; + /** - * 合同产品关联表 DO + * CRM 合同产品关联表 DO * * @author HUIHUI */ @@ -27,12 +29,6 @@ public class CrmContractProductDO extends BaseDO { */ @TableId private Long id; - /** - * 产品编号 - * - * 关联 {@link CrmProductDO#getId()} - */ - private Long productId; /** * 合同编号 * @@ -40,26 +36,27 @@ public class CrmContractProductDO extends BaseDO { */ private Long contractId; /** - * 产品单价 + * 产品编号 + * + * 关联 {@link CrmProductDO#getId()} */ - private Integer price; + private Long productId; /** - * 销售价格, 单位:分 + * 产品单价,单位:元 */ - private Integer salesPrice; + private Integer productPrice; + /** + * 合同价格, 单位:分 + */ + private BigDecimal contractPrice; /** * 数量 */ - private Integer count; + private BigDecimal count; /** - * 折扣 - */ - private Integer discountPercent; - /** - * 总计价格(折扣后价格) - * = {@link #price} - * * {@link #count} - * * ({@link #discountPercent / 100}) + * 总计价格,单位:元 + * + * totalPrice = businessPrice * count */ private Integer totalPrice; diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java index 690bc5302..d1556be3e 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java +++ b/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 { } default Long selectCountByContactId(Long contactId) { - return selectCount(CrmContractDO::getContactId, contactId); + return selectCount(CrmContractDO::getSignContactId, contactId); } default Long selectCountByBusinessId(Long businessId) { diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java index a15fe8068..78b64a976 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java +++ b/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 { // 2.2 更新商机关联商品 updateBusinessProduct(updateObj.getId(), businessProducts); - // TODO @商机待定:如果状态发生变化,插入商机状态变更记录表 // 3. 记录操作日志上下文 LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldBusiness, CrmBusinessSaveReqVO.class)); LogRecordContext.putVariable("businessName", oldBusiness.getName()); @@ -264,7 +263,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { // 1.2 校验是否关联合同 validateContractExists(id); - // 删除 + // 删除商机 businessMapper.deleteById(id); // 删除数据权限 permissionService.deletePermission(CrmBizTypeEnum.CRM_BUSINESS.getType(), id); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java index 58e00a53b..27d685f1d 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java +++ b/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; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ObjUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; import cn.iocoder.yudao.module.bpm.api.listener.dto.BpmResultListenerRespDTO; @@ -15,7 +14,6 @@ import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO; import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractSaveReqVO; import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; -import cn.iocoder.yudao.module.crm.convert.contract.CrmContractConvert; import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractProductDO; import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; @@ -31,6 +29,7 @@ import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO; import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; +import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; import cn.iocoder.yudao.module.crm.service.product.CrmProductService; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import com.mzt.logapi.context.LogRecordContext; @@ -95,16 +94,16 @@ public class CrmContractServiceImpl implements CrmContractService { CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class).setId(null); contractMapper.insert(contract); // 1.2 插入合同关联商品 - if (CollUtil.isNotEmpty(createReqVO.getProductItems())) { // 如果有的话 + if (CollUtil.isNotEmpty(createReqVO.getProducts())) { // 如果有的话 List productList = convertContractProductList(createReqVO, contract.getId()); contractProductMapper.insertBatch(productList); - // 更新合同商品总金额 - contractMapper.updateById(new CrmContractDO().setId(contract.getId()).setProductPrice( - getSumValue(productList, CrmContractProductDO::getTotalPrice, Integer::sum))); + // 更新合同商品总金额 TODO 芋艿 +// contractMapper.updateById(new CrmContractDO().setId(contract.getId()).setTotalProductPrice( +// getSumValue(productList, CrmContractProductDO::getTotalPrice, Integer::sum))); // 如果存在合同关联了商机则更新商机商品关联 if (contract.getBusinessId() != null) { businessService.updateBusinessProduct(new CrmBusinessUpdateProductReqBO().setId(contract.getBusinessId()) - .setItems(BeanUtils.toBean(createReqVO.getProductItems(), CrmBusinessUpdateProductReqBO.Item.class))); + .setItems(BeanUtils.toBean(createReqVO.getProducts(), CrmBusinessUpdateProductReqBO.Item.class))); } } @@ -146,7 +145,7 @@ public class CrmContractServiceImpl implements CrmContractService { } private void updateContractProduct(CrmContractSaveReqVO updateReqVO, Long contractId) { - if (CollUtil.isEmpty(updateReqVO.getProductItems())) { + if (CollUtil.isEmpty(updateReqVO.getProducts())) { return; } List newProductList = convertContractProductList(updateReqVO, contractId); @@ -173,20 +172,22 @@ public class CrmContractServiceImpl implements CrmContractService { private List convertContractProductList(CrmContractSaveReqVO reqVO, Long contractId) { // 校验商品存在 - Set productIds = convertSet(reqVO.getProductItems(), CrmContractSaveReqVO.CrmContractProductItem::getId); + Set productIds = convertSet(reqVO.getProducts(), CrmContractSaveReqVO.Product::getProductId); List productList = productService.getProductList(productIds); if (CollUtil.isEmpty(productIds) || productList.size() != productIds.size()) { throw exception(PRODUCT_NOT_EXISTS); } Map productMap = convertMap(productList, CrmProductDO::getId); - return convertList(reqVO.getProductItems(), productItem -> { - CrmProductDO product = productMap.get(productItem.getId()); - return BeanUtils.toBean(product, CrmContractProductDO.class) - .setId(null).setProductId(productItem.getId()).setContractId(contractId) - .setCount(productItem.getCount()).setDiscountPercent(productItem.getDiscountPercent()) - // TODO 芋艿:这里临时注释掉 - .setTotalPrice(MoneyUtils.calculator(null, productItem.getCount(), productItem.getDiscountPercent())); - }); + // TODO 芋艿 + return null; +// return convertList(reqVO.getProducts(), productItem -> { +// CrmProductDO product = productMap.get(productItem.getId()); +// return BeanUtils.toBean(product, CrmContractProductDO.class) +// .setId(null).setProductId(productItem.getId()).setContractId(contractId) +// .setCount(productItem.getCount()).setDiscountPercent(productItem.getDiscountPercent()) +// // TODO 芋艿:这里临时注释掉 +// .setTotalPrice(MoneyUtils.calculator(null, productItem.getCount(), productItem.getDiscountPercent())); +// }); } /** @@ -245,8 +246,8 @@ public class CrmContractServiceImpl implements CrmContractService { CrmContractDO contract = validateContractExists(reqVO.getId()); // 2.1 数据权限转移 - crmPermissionService.transferPermission( - CrmContractConvert.INSTANCE.convert(reqVO, userId).setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType())); + crmPermissionService.transferPermission(new CrmPermissionTransferReqBO(userId, CrmBizTypeEnum.CRM_CONTRACT.getType(), + reqVO.getId(), reqVO.getNewOwnerUserId(), reqVO.getOldOwnerPermissionLevel())); // 2.2 设置负责人 contractMapper.updateOwnerUserIdById(reqVO.getId(), reqVO.getNewOwnerUserId());