From 84f3b230d20b8db543861835500197b55318b7f8 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Mon, 5 Feb 2024 00:14:50 +0800 Subject: [PATCH] =?UTF-8?q?CRM-=E5=90=88=E5=90=8C:=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=90=88=E5=90=8C=E5=85=B3=E8=81=94=E5=95=86=E5=93=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CrmBusinessStatusTypeController.java | 4 +- .../vo/business/CrmBusinessSaveReqVO.java | 31 +++-- .../product/CrmBusinessProductPageReqVO.java | 15 --- .../vo/product/CrmBusinessProductRespVO.java | 11 -- .../product/CrmBusinessProductSaveReqVO.java | 49 -------- .../admin/contract/CrmContractController.java | 68 +++++----- .../CrmBusinessStatusConvert.java | 2 +- .../CrmBusinessStatusTypeConvert.java | 2 +- .../CrmBusinessProductConvert.java | 21 ---- .../convert/contract/CrmContractConvert.java | 21 +++- .../business/CrmBusinessProductDO.java | 18 --- .../contract/CrmContractProductDO.java | 63 ++++++++++ .../dal/dataobject/contract/package-info.java | 4 - .../business/CrmBusinessProductMapper.java | 7 ++ .../contract/CrmContractProductMapper.java | 31 +++++ .../dal/mysql/product/CrmProductMapper.java | 9 -- .../business/CrmBusinessProductService.java | 57 --------- .../CrmBusinessProductServiceImpl.java | 55 -------- .../business/CrmBusinessServiceImpl.java | 119 +++++++++--------- .../service/contract/CrmContractService.java | 9 ++ .../contract/CrmContractServiceImpl.java | 51 ++++---- .../product/CrmProductServiceImpl.java | 2 +- .../ErpProductUnitServiceImplTest.java | 25 ++-- .../product/ProductServiceImplTest.java | 25 ++-- 24 files changed, 302 insertions(+), 397 deletions(-) delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductPageReqVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductRespVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductSaveReqVO.java rename yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/{businessstatus => business}/CrmBusinessStatusConvert.java (92%) rename yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/{businessstatustype => business}/CrmBusinessStatusTypeConvert.java (96%) delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessproduct/CrmBusinessProductConvert.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/CrmContractProductDO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/package-info.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractProductMapper.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessProductService.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessProductServiceImpl.java diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessStatusTypeController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessStatusTypeController.java index 925fa4953..337590044 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessStatusTypeController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessStatusTypeController.java @@ -14,8 +14,8 @@ import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusiness import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeQueryVO; import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeRespVO; import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeSaveReqVO; -import cn.iocoder.yudao.module.crm.convert.businessstatus.CrmBusinessStatusConvert; -import cn.iocoder.yudao.module.crm.convert.businessstatustype.CrmBusinessStatusTypeConvert; +import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessStatusConvert; +import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessStatusTypeConvert; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO; import cn.iocoder.yudao.module.crm.service.business.CrmBusinessStatusService; 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 672450c4a..c3b167ef1 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 @@ -1,18 +1,18 @@ package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business; import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.product.CrmBusinessProductSaveReqVO; import cn.iocoder.yudao.module.crm.enums.business.CrmBizEndStatus; import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmCustomerParseFunction; import com.mzt.logapi.starter.annotation.DiffLogField; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; +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.ArrayList; import java.util.List; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; @@ -58,7 +58,6 @@ public class CrmBusinessSaveReqVO { @DiffLogField(name = "商机金额") private Integer price; - // TODO @lzxhqs:折扣使用 Integer 类型,存储时,默认 * 100;展示的时候,前端需要 / 100;避免精度丢失问题 @Schema(description = "整单折扣") @DiffLogField(name = "整单折扣") private Integer discountPercent; @@ -75,11 +74,29 @@ public class CrmBusinessSaveReqVO { @InEnum(CrmBizEndStatus.class) private Integer endStatus; - // TODO @lzxhqs:不设置默认 new ArrayList<>();一般 pojo 不设置默认值哈 - @Schema(description = "商机产品列表") - private List products = new ArrayList<>(); - @Schema(description = "联系人编号", example = "110") private Long contactId; // 使用场景,在【联系人详情】添加商机时,如果需要关联两者,需要传递 contactId 字段 + @Schema(description = "产品列表") + private List productItems; + + @Schema(description = "产品列表") + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class CrmBusinessProductItem { + + @Schema(description = "产品编号", example = "20529") + @NotNull(message = "产品编号不能为空") + private Long id; + + @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/controller/admin/business/vo/product/CrmBusinessProductPageReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductPageReqVO.java deleted file mode 100644 index 4804768a5..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductPageReqVO.java +++ /dev/null @@ -1,15 +0,0 @@ -package cn.iocoder.yudao.module.crm.controller.admin.business.vo.product; - -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -// TODO @lzxhqs:这个类,如果没用到,可以考虑删除哈 -@Schema(description = "管理后台 - 商机产品分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class CrmBusinessProductPageReqVO extends PageParam { -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductRespVO.java deleted file mode 100644 index d4996816f..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductRespVO.java +++ /dev/null @@ -1,11 +0,0 @@ -package cn.iocoder.yudao.module.crm.controller.admin.business.vo.product; - -import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -@Schema(description = "管理后台 - 商机产品关联 Response VO") -@Data -@ExcelIgnoreUnannotated -public class CrmBusinessProductRespVO { -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductSaveReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductSaveReqVO.java deleted file mode 100644 index f28f0f350..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductSaveReqVO.java +++ /dev/null @@ -1,49 +0,0 @@ -package cn.iocoder.yudao.module.crm.controller.admin.business.vo.product; - -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; -import lombok.Data; - -import java.math.BigDecimal; - -@Schema(description = "管理后台 - CRM 商机产品关联表 创建/更新 Request VO") -@Data -public class CrmBusinessProductSaveReqVO { - - @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "32129") - private Long id; - - @Schema(description = "商机编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") - @NotNull(message = "商机编号不能为空") - private Long businessId; - - @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") - @NotNull(message = "产品编号不能为空") - private Long productId; - - @Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") - @NotNull(message = "产品单价不能为空") - private BigDecimal price; - - @Schema(description = "销售价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") - @NotNull(message = "销售价格不能为空") - private BigDecimal salesPrice; - - @Schema(description = "数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") - @NotNull(message = "数量不能为空") - private BigDecimal num; - - @Schema(description = "折扣", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") - @NotNull(message = "折扣不能为空") - private BigDecimal discount; - - @Schema(description = "小计(折扣后价格)", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") - @NotNull(message = "小计(折扣后价格)不能为空") - private BigDecimal subtotal; - - @Schema(description = "单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") - @NotEmpty(message = "单位不能为空") - private String unit; - -} 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 aaaccbd81..982ec274c 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 @@ -11,12 +11,11 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.*; 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.business.CrmBusinessProductDO; 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.CrmBusinessProductService; 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; @@ -30,7 +29,6 @@ import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.Valid; -import org.springframework.context.annotation.Lazy; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -43,7 +41,6 @@ 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; @@ -62,11 +59,7 @@ public class CrmContractController { @Resource private CrmBusinessService businessService; @Resource - @Lazy - private CrmBusinessProductService businessProductService; - @Resource private CrmProductService productService; - @Resource private AdminUserApi adminUserApi; @@ -105,22 +98,9 @@ public class CrmContractController { return success(null); } - // 2.1 拼接合同信息 + // 2. 拼接合同信息 List respVOList = buildContractDetailList(Collections.singletonList(contract)); - // 2.2 拼接产品信息 - // TODO @puhui999:下面这块也可以搞到 convert 里哈;可以在 ContractDetailList 加个开关,是不是查询商品信息;ps:jdk21 的方法不太能去用,因为 jdk8 项目要兼容; - CrmContractRespVO respVO = respVOList.get(0); - List businessProductList = businessProductService.getBusinessProductListByContractId(id); - Map businessProductMap = convertMap(businessProductList, CrmBusinessProductDO::getProductId); - List productList = productService.getProductListByIds(convertSet(businessProductList, CrmBusinessProductDO::getProductId)); - respVO.setProductItems(convertList(productList, product -> { - CrmContractRespVO.CrmContractProductItemRespVO productItemRespVO = BeanUtils.toBean(product, CrmContractRespVO.CrmContractProductItemRespVO.class); - findAndThen(businessProductMap, product.getId(), businessProduct -> { - productItemRespVO.setCount(businessProduct.getCount()).setDiscountPercent(businessProduct.getDiscountPercent()); - }); - return productItemRespVO; - })); - return success(respVO); + return success(respVOList.get(0)); } @GetMapping("/page") @@ -151,6 +131,22 @@ public class CrmContractController { BeanUtils.toBean(pageResult.getList(), CrmContractExcelVO.class)); } + @PutMapping("/transfer") + @Operation(summary = "合同转移") + @PreAuthorize("@ss.hasPermission('crm:contract:update')") + public CommonResult transferContract(@Valid @RequestBody CrmContractTransferReqVO reqVO) { + contractService.transferContract(reqVO, getLoginUserId()); + return success(true); + } + + @PutMapping("/submit") + @Operation(summary = "提交合同审批") + @PreAuthorize("@ss.hasPermission('crm:contract:update')") + public CommonResult submitContract(@RequestParam("id") Long id) { + contractService.submitContract(id, getLoginUserId()); + return success(true); + } + /** * 构建详细的合同结果 * @@ -173,23 +169,15 @@ public class CrmContractController { // 4. 获取商机 Map businessMap = convertMap(businessService.getBusinessList(convertSet(contractList, CrmContractDO::getBusinessId)), CrmBusinessDO::getId); - return CrmContractConvert.INSTANCE.convertList(contractList, userMap, customerList, contactMap, businessMap); - } - - @PutMapping("/transfer") - @Operation(summary = "合同转移") - @PreAuthorize("@ss.hasPermission('crm:contract:update')") - public CommonResult transferContract(@Valid @RequestBody CrmContractTransferReqVO reqVO) { - contractService.transferContract(reqVO, getLoginUserId()); - return success(true); - } - - @PutMapping("/submit") - @Operation(summary = "提交合同审批") - @PreAuthorize("@ss.hasPermission('crm:contract:update')") - public CommonResult submitContract(@RequestParam("id") Long id) { - contractService.submitContract(id, getLoginUserId()); - return success(true); + // 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.getProductListByIds(convertSet(contractProductList, CrmContractProductDO::getProductId)); + } + return CrmContractConvert.INSTANCE.convertList(contractList, userMap, customerList, contactMap, businessMap, contractProductMap, productList); } } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessstatus/CrmBusinessStatusConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessStatusConvert.java similarity index 92% rename from yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessstatus/CrmBusinessStatusConvert.java rename to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessStatusConvert.java index df2532b27..52186e3d9 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessstatus/CrmBusinessStatusConvert.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessStatusConvert.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.crm.convert.businessstatus; +package cn.iocoder.yudao.module.crm.convert.business; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusRespVO; diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessstatustype/CrmBusinessStatusTypeConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessStatusTypeConvert.java similarity index 96% rename from yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessstatustype/CrmBusinessStatusTypeConvert.java rename to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessStatusTypeConvert.java index be203b580..4876fb537 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessstatustype/CrmBusinessStatusTypeConvert.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessStatusTypeConvert.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.crm.convert.businessstatustype; +package cn.iocoder.yudao.module.crm.convert.business; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeRespVO; diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessproduct/CrmBusinessProductConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessproduct/CrmBusinessProductConvert.java deleted file mode 100644 index 2fcd54d84..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessproduct/CrmBusinessProductConvert.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.module.crm.convert.businessproduct; - -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.product.CrmBusinessProductSaveReqVO; -import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -// TODO @lzxhqs:看看是不是用 BeanUtils 替代了 -/** - * @author lzxhqs - * @version 1.0 - * @title CrmBusinessProductConvert - * @description - * @create 2024/1/12 - */ -@Mapper -public interface CrmBusinessProductConvert { - CrmBusinessProductConvert INSTANCE = Mappers.getMapper(CrmBusinessProductConvert.class); - - CrmBusinessProductDO convert(CrmBusinessProductSaveReqVO product); -} 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 index c9247e6a5..444876040 100644 --- 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 @@ -1,12 +1,16 @@ 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; @@ -34,7 +38,8 @@ public interface CrmContractConvert { default List convertList(List contractList, Map userMap, List customerList, Map contactMap, - Map businessMap) { + Map businessMap, Map contractProductMap, + List productList) { List respVOList = BeanUtils.toBean(contractList, CrmContractRespVO.class); // 拼接关联字段 Map customerMap = convertMap(customerList, CrmCustomerDO::getId); @@ -46,7 +51,21 @@ public interface CrmContractConvert { 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.setProductItems(CollectionUtils.convertList(productList, product -> { + CrmContractRespVO.CrmContractProductItemRespVO productItemRespVO = BeanUtils.toBean(product, CrmContractRespVO.CrmContractProductItemRespVO.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 77c5ba779..79d6a2a7b 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 @@ -1,9 +1,7 @@ package cn.iocoder.yudao.module.crm.dal.dataobject.business; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; -import cn.iocoder.yudao.module.crm.enums.DictTypeConstants; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -41,19 +39,10 @@ public class CrmBusinessProductDO extends BaseDO { * 关联 {@link CrmProductDO#getId()} */ private Long productId; - // TODO 芋艿:需要在看下 CRM - /** - * 合同编号 - * - * 关联 {@link CrmContractDO#getId()} - */ - private Long contractId; - /** * 产品单价 */ private Integer price; - /** * 销售价格, 单位:分 */ @@ -71,11 +60,4 @@ public class CrmBusinessProductDO extends BaseDO { */ private Integer totalPrice; - /** - * 单位 - * - * 字典 {@link DictTypeConstants#CRM_PRODUCT_UNIT} - */ - private Integer unit; - } 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 new file mode 100644 index 000000000..f0f506857 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/CrmContractProductDO.java @@ -0,0 +1,63 @@ +package cn.iocoder.yudao.module.crm.dal.dataobject.contract; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * 合同产品关联表 DO + * + * @author HUIHUI + */ +@TableName("crm_contract_product") +@KeySequence("crm_contract_product_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class CrmContractProductDO extends BaseDO { + + /** + * 主键 + */ + @TableId + private Long id; + /** + * 产品编号 + * + * 关联 {@link CrmProductDO#getId()} + */ + private Long productId; + /** + * 合同编号 + * + * 关联 {@link CrmContractDO#getId()} + */ + private Long contractId; + /** + * 产品单价 + */ + private Integer price; + /** + * 销售价格, 单位:分 + */ + private Integer salesPrice; + /** + * 数量 + */ + private Integer count; + /** + * 折扣 + */ + private Integer discountPercent; + /** + * 总计价格(折扣后价格) + */ + private Integer totalPrice; + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/package-info.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/package-info.java deleted file mode 100644 index a981b5dfc..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/contract/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 合同 - */ -package cn.iocoder.yudao.module.crm.dal.dataobject.contract; diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessProductMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessProductMapper.java index 1730067fe..35fccdbdf 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessProductMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessProductMapper.java @@ -2,9 +2,12 @@ package cn.iocoder.yudao.module.crm.dal.mysql.business; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO; import org.apache.ibatis.annotations.Mapper; +import java.util.List; + /** * 商机产品 Mapper * @@ -21,4 +24,8 @@ public interface CrmBusinessProductMapper extends BaseMapperX selectListByBusinessId(Long businessId) { + return selectList(new LambdaQueryWrapperX().eq(CrmBusinessProductDO::getBusinessId, businessId)); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractProductMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractProductMapper.java new file mode 100644 index 000000000..fd6347a9e --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractProductMapper.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.crm.dal.mysql.contract; + + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractProductDO; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * 合同产品 Mapper + * + * @author HUIHUI + */ +@Mapper +public interface CrmContractProductMapper extends BaseMapperX { + + default void deleteByContractId(Long contractId) { // TODO @lzxhqs:第一个方法,和类之间最好空一行; + delete(CrmContractProductDO::getContractId, contractId); + } + + default CrmContractProductDO selectByContractId(Long contractId) { + return selectOne(CrmContractProductDO::getContractId, contractId); + } + + default List selectListByContractId(Long contractId) { + return selectList(new LambdaQueryWrapperX().eq(CrmContractProductDO::getContractId, contractId)); + } + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/product/CrmProductMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/product/CrmProductMapper.java index 8a7fa600b..30a07eec2 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/product/CrmProductMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/product/CrmProductMapper.java @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.crm.dal.mysql.product; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductPageReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; @@ -10,9 +9,6 @@ import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils; import org.apache.ibatis.annotations.Mapper; -import java.util.Collection; -import java.util.List; - /** * CRM 产品 Mapper * @@ -38,9 +34,4 @@ public interface CrmProductMapper extends BaseMapperX { return selectOne(CrmProductDO::getNo, no); } - // TODO @puhui999:selectBatchIds - default List selectListByIds(Collection ids) { - return selectList(new LambdaQueryWrapperX().in(CrmProductDO::getId, ids)); - } - } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessProductService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessProductService.java deleted file mode 100644 index a68ac37b9..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessProductService.java +++ /dev/null @@ -1,57 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.business; - -import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO; - -import java.util.List; - -/** - * 商机产品关联表 Service 接口 - * - * @author lzxhqs - */ -public interface CrmBusinessProductService { - - /** - * 批量新增商机产品关联数据 - * - * @param list 商机产品集合 - */ - void createBusinessProductBatch(List list); - - /** - * 批量更新商机产品表 - * - * @param list 商机产品数据集合 - */ - void updateBusinessProductBatch(List list); - - /** - * 批量删除 - * - * @param list 需要删除的商机产品集合 - */ - void deleteBusinessProductBatch(List list); - - /** - * 根据商机编号,删除商机产品关联数据 - * - * @param businessId 商机id - */ - void deleteBusinessProductByBusinessId(Long businessId); - - /** - * 根据商机编号,获取商机产品关联数据集合 - * - * @param businessId 商机编号 - */ - List getBusinessProductListByBusinessId(Long businessId); - - /** - * 根据合同编号,获得合同关联的商品列表 - * - * @param contractId 合同编号 - * @return 关联的商品列表 - */ - List getBusinessProductListByContractId(Long contractId); - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessProductServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessProductServiceImpl.java deleted file mode 100644 index 0762d4555..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessProductServiceImpl.java +++ /dev/null @@ -1,55 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.business; - -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO; -import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessProductMapper; -import jakarta.annotation.Resource; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import java.util.List; - -/** - * 商机产品关联表 Service 实现类 - * - * @author lzxhqs - */ -@Service -@Validated -public class CrmBusinessProductServiceImpl implements CrmBusinessProductService { - - @Resource - private CrmBusinessProductMapper businessProductMapper; - - @Override - public void createBusinessProductBatch(List list) { - businessProductMapper.insertBatch(list); - } - - @Override - public void updateBusinessProductBatch(List list) { - businessProductMapper.updateBatch(list); - } - - // TODO @puhui999:这个方法,可以直接调用 deleteList 方法,然后传递 ids 就好了; - @Override - public void deleteBusinessProductBatch(List list) { - businessProductMapper.deleteBatchIds(CollectionUtils.convertList(list, CrmBusinessProductDO::getId)); - } - - @Override - public void deleteBusinessProductByBusinessId(Long businessId) { - businessProductMapper.deleteByBusinessId(businessId); - } - - @Override - public List getBusinessProductListByContractId(Long contractId) { - return businessProductMapper.selectList(CrmBusinessProductDO::getContractId, contractId); - } - - @Override - public List getBusinessProductListByBusinessId(Long businessId) { - return businessProductMapper.selectList(CrmBusinessProductDO::getBusinessId, 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 df7348cfe..7de0ca424 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 @@ -5,17 +5,18 @@ import cn.hutool.core.collection.ListUtil; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO; import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessSaveReqVO; import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.product.CrmBusinessProductSaveReqVO; import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert; -import cn.iocoder.yudao.module.crm.convert.businessproduct.CrmBusinessProductConvert; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO; import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactBusinessDO; +import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessMapper; +import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessProductMapper; import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission; @@ -24,6 +25,7 @@ import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; 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.product.CrmProductService; import com.mzt.logapi.context.LogRecordContext; import com.mzt.logapi.service.impl.DiffParseFunction; import com.mzt.logapi.starter.annotation.LogRecord; @@ -35,11 +37,12 @@ import org.springframework.validation.annotation.Validated; import java.util.Collection; import java.util.List; +import java.util.Map; +import java.util.Set; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BUSINESS_CONTRACT_EXISTS; -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BUSINESS_NOT_EXISTS; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; +import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*; /** @@ -53,9 +56,9 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @Resource private CrmBusinessMapper businessMapper; - @Resource - private CrmBusinessProductService businessProductService; + private CrmBusinessProductMapper businessProductMapper; + @Resource @Lazy // 延迟加载,避免循环依赖 private CrmContractService contractService; @@ -63,6 +66,8 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { private CrmPermissionService permissionService; @Resource private CrmContactBusinessService contactBusinessService; + @Resource + private CrmProductService productService; @Override @Transactional(rollbackFor = Exception.class) @@ -71,12 +76,15 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { public Long createBusiness(CrmBusinessSaveReqVO createReqVO, Long userId) { createReqVO.setId(null); // 1. 插入商机 - CrmBusinessDO business = BeanUtils.toBean(createReqVO, CrmBusinessDO.class) - .setOwnerUserId(userId); + CrmBusinessDO business = BeanUtils.toBean(createReqVO, CrmBusinessDO.class).setOwnerUserId(userId); businessMapper.insert(business); - // TODO 商机待定:插入商机与产品的关联表;校验商品存在 - if (CollUtil.isNotEmpty(createReqVO.getProducts())) { - createBusinessProducts(createReqVO.getProducts(), business.getId(), false); + // 1.2 插入商机关联商品 + if (CollUtil.isNotEmpty(createReqVO.getProductItems())) { // 如果有的话 + List productList = convertBusinessProductList(createReqVO, business.getId()); + businessProductMapper.insertBatch(productList); + // 更新合同商品总金额 + businessMapper.updateById(new CrmBusinessDO().setId(business.getId()).setProductPrice( + getSumValue(productList, CrmBusinessProductDO::getTotalPrice, Integer::sum))); } // TODO 商机待定:在联系人的详情页,如果直接【新建商机】,则需要关联下。这里要搞个 CrmContactBusinessDO 表 createContactBusiness(business.getId(), createReqVO.getContactId()); @@ -92,13 +100,6 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { } // TODO @lzxhqs:CrmContactBusinessService 调用这个;这样逻辑才能收敛哈; - /** - * @param businessId 商机id - * @param contactId 联系人id - * @throws - * @description 联系人与商机的关联 - * @author lzxhqs - */ private void createContactBusiness(Long businessId, Long contactId) { CrmContactBusinessDO contactBusiness = new CrmContactBusinessDO(); contactBusiness.setBusinessId(businessId); @@ -106,37 +107,6 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { contactBusinessService.insert(contactBusiness); } - // TODO @lzxhqs:这个方法注释格式不对;删除@description,然后把 插入商机产品关联表 作为方法注释; - /** - * 插入商机产品关联表 - * - * @param products 产品集合 - * @param businessId 商机id - * @param updateFlag 更新标识 true 代表更新 - * @author lzxhqs - */ - private void createBusinessProducts(List products, Long businessId, Boolean updateFlag) { - List list = CollectionUtils.convertList(products, product -> - CrmBusinessProductConvert.INSTANCE.convert(product).setBusinessId(businessId)); - if (Boolean.TRUE.equals(updateFlag)) { -// 根据商机 id从商机产品关联表中获取已存在的数据集合 - List oldProducts = businessProductService.getBusinessProductListByBusinessId(businessId); - List> diffList = CollectionUtils.diffList(oldProducts, list, (oldValue, newValue) -> - ObjectUtil.equal(oldValue.getProductId(), newValue.getProductId())); - if (CollUtil.isNotEmpty(diffList.getFirst())) { - businessProductService.createBusinessProductBatch(diffList.getFirst()); - } - if (CollUtil.isNotEmpty(diffList.get(1))) { - businessProductService.updateBusinessProductBatch(diffList.get(1)); - } - if (CollUtil.isNotEmpty(diffList.get(2))) { - businessProductService.deleteBusinessProductBatch(diffList.get(2)); - } - } else { - businessProductService.createBusinessProductBatch(list); - } - } - @Override @Transactional(rollbackFor = Exception.class) @LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}", @@ -146,16 +116,12 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { // 1. 校验存在 CrmBusinessDO oldBusiness = validateBusinessExists(updateReqVO.getId()); - // 2. 更新商机 + // 2.1 更新商机 CrmBusinessDO updateObj = BeanUtils.toBean(updateReqVO, CrmBusinessDO.class); businessMapper.updateById(updateObj); - // TODO 商机待定:插入商机与产品的关联表;校验商品存在 - // TODO @lzxhqs:createBusinessProducts 可以抽成两个方法,一个新增;一个修改,修改需要把 businessProductService.deleteByBusinessId(updateReqVO.getId()); 一起处理进去; - if (CollUtil.isNotEmpty(updateReqVO.getProducts())) { - createBusinessProducts(updateReqVO.getProducts(), updateReqVO.getId(), true); - } else { - businessProductService.deleteBusinessProductByBusinessId(updateReqVO.getId()); - } + // 2.2 更新商机关联商品 + List productList = convertBusinessProductList(updateReqVO, updateObj.getId()); + updateBusinessProduct(productList, updateObj.getId()); // TODO @商机待定:如果状态发生变化,插入商机状态变更记录表 // 3. 记录操作日志上下文 @@ -188,6 +154,43 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { LogRecordContext.putVariable("businessName", business.getName()); } + private void updateBusinessProduct(List newProductList, Long businessId) { + List oldProducts = businessProductMapper.selectListByBusinessId(businessId); + List> diffList = CollectionUtils.diffList(oldProducts, newProductList, (oldValue, newValue) -> { + boolean condition = ObjectUtil.equal(oldValue.getProductId(), newValue.getProductId()); + if (condition) { + newValue.setId(oldValue.getId()); // 更新需要原始编号 + } + return condition; + }); + if (CollUtil.isNotEmpty(diffList.get(0))) { + businessProductMapper.insertBatch(diffList.get(0)); + } + if (CollUtil.isNotEmpty(diffList.get(1))) { + businessProductMapper.updateBatch(diffList.get(1)); + } + if (CollUtil.isNotEmpty(diffList.get(2))) { + businessProductMapper.deleteBatchIds(convertSet(diffList.get(2), CrmBusinessProductDO::getId)); + } + } + + private List convertBusinessProductList(CrmBusinessSaveReqVO reqVO, Long businessId) { + // 校验商品存在 + Set productIds = convertSet(reqVO.getProductItems(), CrmBusinessSaveReqVO.CrmBusinessProductItem::getId); + 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, CrmBusinessProductDO.class) + .setId(null).setProductId(productItem.getId()).setBusinessId(businessId) + .setCount(productItem.getCount()).setDiscountPercent(productItem.getDiscountPercent()) + .setTotalPrice(MoneyUtils.calculator(product.getPrice(), productItem.getCount(), productItem.getDiscountPercent())); + }); + } + /** * 删除校验合同是关联合同 * diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java index 3e79b73ed..0bd527ae0 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageR 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.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.service.followup.bo.CrmUpdateFollowUpReqBO; import jakarta.validation.Valid; @@ -134,4 +135,12 @@ public interface CrmContractService { */ Long getContractCountByBusinessId(Long businessId); + /** + * 获取合同商品列表 + * + * @param contactId 合同编号 + * @return 合同商品列表 + */ + List getContractProductListByContractId(Long contactId); + } 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 4af609edd..0cf9065e4 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 @@ -15,15 +15,15 @@ import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageR 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.CrmBusinessProductDO; 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; import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper; +import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractProductMapper; import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum; import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission; -import cn.iocoder.yudao.module.crm.service.business.CrmBusinessProductService; import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService; import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO; @@ -63,12 +63,12 @@ public class CrmContractServiceImpl implements CrmContractService { @Resource private CrmContractMapper contractMapper; + @Resource + private CrmContractProductMapper contractProductMapper; @Resource private CrmPermissionService crmPermissionService; @Resource - private CrmBusinessProductService businessProductService; - @Resource private CrmProductService productService; @Resource private CrmCustomerService customerService; @@ -89,11 +89,14 @@ public class CrmContractServiceImpl implements CrmContractService { // 1.1 插入合同 CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class).setId(null); contractMapper.insert(contract); - // 1.2 插入商机关联商品 + // 1.2 插入合同关联商品 if (CollUtil.isNotEmpty(createReqVO.getProductItems())) { // 如果有的话 - List businessProduct = convertBusinessProductList(createReqVO, contract.getId()); - businessProductService.createBusinessProductBatch(businessProduct); + List productList = convertContractProductList(createReqVO, contract.getId()); + contractProductMapper.insertBatch(productList); // 更新合同商品总金额 + contractMapper.updateById(new CrmContractDO().setId(contract.getId()).setProductPrice( + getSumValue(productList, CrmContractProductDO::getTotalPrice, Integer::sum))); + // TODO @puhui999: 如果存在合同关联了商机则更新商机商品关联 } // 2. 创建数据权限 @@ -137,29 +140,29 @@ public class CrmContractServiceImpl implements CrmContractService { if (CollUtil.isEmpty(updateReqVO.getProductItems())) { return; } - List newProductList = convertBusinessProductList(updateReqVO, contractId); - List oldProductList = businessProductService.getBusinessProductListByContractId(contractId); - List> diffList = diffList(oldProductList, newProductList, (oldObj, newObj) -> { - if (ObjUtil.notEqual(oldObj.getProductId(), newObj.getProductId())) { - return false; + List newProductList = convertContractProductList(updateReqVO, contractId); + List oldProductList = contractProductMapper.selectListByContractId(contractId); + List> diffList = diffList(oldProductList, newProductList, (oldObj, newObj) -> { + boolean equal = ObjUtil.equal(oldObj.getProductId(), newObj.getProductId()); + if (equal) { + newObj.setId(oldObj.getId()); // 设置一下老的编号更新时需要使用 } - newObj.setId(oldObj.getId()); // 设置一下老的编号更新时需要使用 - return true; + return equal; }); - if (CollUtil.isNotEmpty(diffList.getFirst())) { - businessProductService.createBusinessProductBatch(diffList.getFirst()); + if (CollUtil.isNotEmpty(diffList.get(0))) { + contractProductMapper.insertBatch(diffList.get(0)); } if (CollUtil.isNotEmpty(diffList.get(1))) { - businessProductService.updateBusinessProductBatch(diffList.get(1)); + contractProductMapper.updateBatch(diffList.get(1)); } if (CollUtil.isNotEmpty(diffList.get(2))) { - businessProductService.deleteBusinessProductBatch(diffList.get(2)); + contractProductMapper.deleteBatchIds(convertList(diffList.get(2), CrmContractProductDO::getId)); } } // TODO @合同待定:缺一个取消合同的接口;只有草稿、审批中可以取消;CrmAuditStatusEnum - private List convertBusinessProductList(CrmContractSaveReqVO reqVO, Long contractId) { + private List convertContractProductList(CrmContractSaveReqVO reqVO, Long contractId) { // 校验商品存在 Set productIds = convertSet(reqVO.getProductItems(), CrmContractSaveReqVO.CrmContractProductItem::getId); List productList = productService.getProductList(productIds); @@ -169,8 +172,8 @@ public class CrmContractServiceImpl implements CrmContractService { Map productMap = convertMap(productList, CrmProductDO::getId); return convertList(reqVO.getProductItems(), productItem -> { CrmProductDO product = productMap.get(productItem.getId()); - return BeanUtils.toBean(product, CrmBusinessProductDO.class) - .setId(null).setBusinessId(reqVO.getBusinessId()).setProductId(productItem.getId()).setContractId(contractId) + return BeanUtils.toBean(product, CrmContractProductDO.class) + .setId(null).setProductId(productItem.getId()).setContractId(contractId) .setCount(productItem.getCount()).setDiscountPercent(productItem.getDiscountPercent()) .setTotalPrice(MoneyUtils.calculator(product.getPrice(), productItem.getCount(), productItem.getDiscountPercent())); }); @@ -313,5 +316,11 @@ public class CrmContractServiceImpl implements CrmContractService { public Long getContractCountByBusinessId(Long businessId) { return contractMapper.selectCountByBusinessId(businessId); } + + @Override + public List getContractProductListByContractId(Long contactId) { + return contractProductMapper.selectListByContractId(contactId); + } + // TODO @合同待定:需要新增一个 ContractConfigDO 表,合同配置,重点是到期提醒; } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductServiceImpl.java index 55f8a3593..95205524e 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductServiceImpl.java @@ -160,7 +160,7 @@ public class CrmProductServiceImpl implements CrmProductService { if (CollUtil.isEmpty(ids)) { return Collections.emptyList(); } - return productMapper.selectListByIds(ids); + return productMapper.selectBatchIds(ids); } } diff --git a/yudao-module-erp/yudao-module-erp-biz/src/test/java/cn/iocoder/yudao/module/erp/service/product/ErpProductUnitServiceImplTest.java b/yudao-module-erp/yudao-module-erp-biz/src/test/java/cn/iocoder/yudao/module/erp/service/product/ErpProductUnitServiceImplTest.java index c4023df0e..669d88569 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/test/java/cn/iocoder/yudao/module/erp/service/product/ErpProductUnitServiceImplTest.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/test/java/cn/iocoder/yudao/module/erp/service/product/ErpProductUnitServiceImplTest.java @@ -1,24 +1,23 @@ package cn.iocoder.yudao.module.erp.service.product; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.unit.ErpProductUnitPageReqVO; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.unit.ErpProductUnitSaveReqVO; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import jakarta.annotation.Resource; - -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; - import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO; import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductUnitMapper; -import cn.iocoder.yudao.framework.common.pojo.PageResult; - +import jakarta.annotation.Resource; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import org.springframework.context.annotation.Import; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.module.erp.ErrorCodeConstants.PRODUCT_UNIT_NOT_EXISTS; import static org.junit.jupiter.api.Assertions.*; /** diff --git a/yudao-module-erp/yudao-module-erp-biz/src/test/java/cn/iocoder/yudao/module/erp/service/product/ProductServiceImplTest.java b/yudao-module-erp/yudao-module-erp-biz/src/test/java/cn/iocoder/yudao/module/erp/service/product/ProductServiceImplTest.java index 03298bcc3..89a7020ef 100644 --- a/yudao-module-erp/yudao-module-erp-biz/src/test/java/cn/iocoder/yudao/module/erp/service/product/ProductServiceImplTest.java +++ b/yudao-module-erp/yudao-module-erp-biz/src/test/java/cn/iocoder/yudao/module/erp/service/product/ProductServiceImplTest.java @@ -1,24 +1,23 @@ package cn.iocoder.yudao.module.erp.service.product; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductPageReqVO; import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ProductSaveReqVO; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import jakarta.annotation.Resource; - -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; - import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO; import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductMapper; -import cn.iocoder.yudao.framework.common.pojo.PageResult; - +import jakarta.annotation.Resource; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import org.springframework.context.annotation.Import; -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; -import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.*; -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static cn.iocoder.yudao.module.erp.ErrorCodeConstants.PRODUCT_NOT_EXISTS; import static org.junit.jupiter.api.Assertions.*; /**