diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java index 7603f3c3b..ec1b35db4 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java @@ -135,7 +135,6 @@ public class CrmBusinessController { return success(BeanUtils.toBean(businessService.getBusinessList(ids, getLoginUserId()), CrmBusinessRespVO.class)); } - // TODO 芋艿:处理下 @GetMapping("/simple-all-list") @Operation(summary = "获得联系人的精简列表") @PreAuthorize("@ss.hasPermission('crm:contact:query')") @@ -144,7 +143,8 @@ public class CrmBusinessController { reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页 PageResult pageResult = businessService.getBusinessPage(reqVO, getLoginUserId()); return success(convertList(pageResult.getList(), business -> // 只返回 id、name 字段 - new CrmBusinessRespVO().setId(business.getId()).setName(business.getName()))); + new CrmBusinessRespVO().setId(business.getId()).setName(business.getName()) + .setCustomerId(business.getCustomerId()))); } @GetMapping("/page") diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java index 4d9385199..6c27fbb01 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java @@ -120,7 +120,8 @@ public class CrmContactController { public CommonResult> getSimpleContactList() { List list = contactService.getContactList(getLoginUserId()); return success(convertList(list, contact -> // 只返回 id、name 字段 - new CrmContactRespVO().setId(contact.getId()).setName(contact.getName()))); + new CrmContactRespVO().setId(contact.getId()).setName(contact.getName()) + .setCustomerId(contact.getCustomerId()))); } @GetMapping("/page") 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 65226866f..147c598d6 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 @@ -16,7 +16,9 @@ import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTrans 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; @@ -108,13 +110,16 @@ public class CrmContractController { 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); + CrmContractRespVO contractVO = buildContractDetailList(singletonList(contract)).get(0); + // 拼接产品项 + List businessProducts = contractService.getContractProductListByContractId(contractVO.getId()); + Map productMap = productService.getProductMap( + convertSet(businessProducts, CrmContractProductDO::getProductId)); + contractVO.setProducts(BeanUtils.toBean(businessProducts, CrmContractRespVO.Product.class, businessProductVO -> + MapUtils.findAndThen(productMap, businessProductVO.getProductId(), + product -> businessProductVO.setProductName(product.getName()) + .setProductNo(product.getNo()).setProductUnit(product.getUnit())))); + return contractVO; } @GetMapping("/page") 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 738cfaa79..f32549e77 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 @@ -121,13 +121,13 @@ public class CrmContractRespVO { private LocalDateTime updateTime; @Schema(description = "产品列表") - private List products; + private List products; @Schema(description = "产品列表") @Data @NoArgsConstructor @AllArgsConstructor - public static class Item { + public static class Product { @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "888") private Long id; @@ -145,7 +145,7 @@ public class CrmContractRespVO { private BigDecimal productPrice; @Schema(description = "合同价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") - private BigDecimal businessPrice; + private BigDecimal contractPrice; @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") private BigDecimal count; 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 423c0ab93..322127f42 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 @@ -100,7 +100,7 @@ public class CrmContractSaveReqVO { @Schema(description = "合同价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") @NotNull(message = "合同价格不能为空") - private BigDecimal businessPrice; + private BigDecimal contractPrice; @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") @NotNull(message = "产品数量不能为空") 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 88ded4391..ec50e50be 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 @@ -44,7 +44,7 @@ public class CrmContractProductDO extends BaseDO { /** * 产品单价,单位:元 */ - private Integer productPrice; + private BigDecimal productPrice; /** * 合同价格, 单位:分 */ @@ -58,6 +58,6 @@ public class CrmContractProductDO extends BaseDO { * * totalPrice = businessPrice * count */ - private Integer totalPrice; + private BigDecimal totalPrice; } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java index bcb7f0903..63ef761a7 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java @@ -11,7 +11,6 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; import cn.iocoder.yudao.module.crm.enums.business.CrmBusinessEndStatusEnum; -import cn.iocoder.yudao.module.crm.service.business.bo.CrmBusinessUpdateProductReqBO; import jakarta.validation.Valid; import java.time.LocalDateTime; @@ -80,13 +79,6 @@ public interface CrmBusinessService { */ void transferBusiness(CrmBusinessTransferReqVO reqVO, Long userId); - /** - * 更新商机关联商品 - * - * @param updateProductReqBO 请求 - */ - void updateBusinessProduct(CrmBusinessUpdateProductReqBO updateProductReqBO); - /** * 获得商机 * @@ -95,6 +87,14 @@ public interface CrmBusinessService { */ CrmBusinessDO getBusiness(Long id); + /** + * 校验商机是否有效 + * + * @param id 编号 + * @return 商机 + */ + CrmBusinessDO validateBusiness(Long id); + /** * 获得商机列表 * 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 78b64a976..11b6193fc 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 @@ -19,7 +19,6 @@ 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; -import cn.iocoder.yudao.module.crm.service.business.bo.CrmBusinessUpdateProductReqBO; import cn.iocoder.yudao.module.crm.service.contact.CrmContactBusinessService; import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; @@ -91,10 +90,10 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { // 1.1 校验产品项的有效性 List businessProducts = validateBusinessProducts(createReqVO.getProducts()); // 1.2 校验关联字段 - validateBusinessForCreate(createReqVO); + validateRelationDataExists(createReqVO); // 2.1 插入商机 - CrmBusinessDO business = BeanUtils.toBean(createReqVO, CrmBusinessDO.class).setOwnerUserId(userId); + CrmBusinessDO business = BeanUtils.toBean(createReqVO, CrmBusinessDO.class); business.setStatusId(businessStatusService.getBusinessStatusListByTypeId(createReqVO.getStatusTypeId()).get(0).getId()); // 默认状态 calculateTotalPrice(business, businessProducts); businessMapper.insert(business); @@ -105,9 +104,9 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { } // 3. 创建数据权限 - // 设置当前操作的人为负责人 - permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType()) - .setBizId(business.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); + permissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(business.getOwnerUserId()) + .setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType()).setBizId(business.getId()) + .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 4. 在联系人的详情页,如果直接【新建商机】,则需要关联下 if (createReqVO.getContactId() != null) { @@ -132,7 +131,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { // 1.2 校验产品项的有效性 List businessProducts = validateBusinessProducts(updateReqVO.getProducts()); // 1.3 校验关联字段 - validateBusinessForCreate(updateReqVO); + validateRelationDataExists(updateReqVO); // 2.1 更新商机 CrmBusinessDO updateObj = BeanUtils.toBean(updateReqVO, CrmBusinessDO.class); @@ -184,7 +183,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { } } - private void validateBusinessForCreate(CrmBusinessSaveReqVO saveReqVO) { + private void validateRelationDataExists(CrmBusinessSaveReqVO saveReqVO) { // 校验商机状态 if (saveReqVO.getStatusTypeId() != null) { businessStatusService.validateBusinessStatusType(saveReqVO.getStatusTypeId()); @@ -207,9 +206,8 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { // 1. 校验产品存在 productService.validProductList(convertSet(list, CrmBusinessSaveReqVO.Product::getProductId)); // 2. 转化为 CrmBusinessProductDO 列表 - return convertList(list, o -> BeanUtils.toBean(o, CrmBusinessProductDO.class, item -> { - item.setTotalPrice(MoneyUtils.priceMultiply(item.getBusinessPrice(), item.getCount())); - })); + return convertList(list, o -> BeanUtils.toBean(o, CrmBusinessProductDO.class, + item -> item.setTotalPrice(MoneyUtils.priceMultiply(item.getBusinessPrice(), item.getCount())))); } private void calculateTotalPrice(CrmBusinessDO business, List businessProducts) { @@ -218,7 +216,6 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { business.setTotalPrice(business.getTotalProductPrice().subtract(discountPrice)); } - @Override @LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_UPDATE_STATUS_SUB_TYPE, bizNo = "{{#reqVO.id}}", success = CRM_BUSINESS_UPDATE_STATUS_SUCCESS) @@ -312,14 +309,6 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { LogRecordContext.putVariable("business", business); } - @Override - public void updateBusinessProduct(CrmBusinessUpdateProductReqBO updateProductReqBO) { - // 更新商机关联商品 TODO yunai -// List productList = buildBusinessProductList( -// BeanUtils.toBean(updateProductReqBO.getProductItems(), CrmBusinessSaveReqVO.Product.class), updateProductReqBO.getId()); -// updateBusinessProduct(productList, updateProductReqBO.getId()); - } - //======================= 查询相关 ======================= @Override @@ -328,6 +317,11 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { return businessMapper.selectById(id); } + @Override + public CrmBusinessDO validateBusiness(Long id) { + return validateBusinessExists(id); + } + @Override public List getBusinessList(Collection ids, Long userId) { if (CollUtil.isEmpty(ids)) { diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/bo/CrmBusinessUpdateProductReqBO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/bo/CrmBusinessUpdateProductReqBO.java deleted file mode 100644 index 0c8d7efbf..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/bo/CrmBusinessUpdateProductReqBO.java +++ /dev/null @@ -1,49 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.business.bo; - -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.List; - -/** - * 更新商机商品 Update Req BO - * - * @author HUIHUI - */ -@Data -public class CrmBusinessUpdateProductReqBO { - - /** - * 商机编号 - */ - @NotNull(message = "商机编号不能为空") - private Long id; - - // TODO @芋艿:再想想 - @NotEmpty(message = "产品列表不能为空") - private List items; - - @Schema(description = "产品列表") - @Data - @NoArgsConstructor - @AllArgsConstructor - public static class Item { - - @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/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 27d685f1d..1018cc120 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,6 +5,7 @@ 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; @@ -16,7 +17,6 @@ import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractSaveR 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.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; @@ -24,7 +24,7 @@ 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.CrmBusinessService; -import cn.iocoder.yudao.module.crm.service.business.bo.CrmBusinessUpdateProductReqBO; +import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; 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; @@ -40,16 +40,14 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; +import java.math.BigDecimal; 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.*; import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*; -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS; /** * CRM 合同 Service 实现类 @@ -78,6 +76,8 @@ public class CrmContractServiceImpl implements CrmContractService { private CrmCustomerService customerService; @Resource private CrmBusinessService businessService; + @Resource + private CrmContactService contactService; @Resource private AdminUserApi adminUserApi; @@ -89,30 +89,29 @@ public class CrmContractServiceImpl implements CrmContractService { @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_CREATE_SUB_TYPE, bizNo = "{{#contract.id}}", success = CRM_CONTRACT_CREATE_SUCCESS) public Long createContract(CrmContractSaveReqVO createReqVO, Long userId) { + // 1.1 校验产品项的有效性 + List contractProducts = validateContractProducts(createReqVO.getProducts()); + // 1.2 校验关联字段 validateRelationDataExists(createReqVO); - // 1.1 插入合同 - CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class).setId(null); + // TODO 芋艿:生成 no + + // 2.1 插入合同 + CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class); + contract.setNo(System.currentTimeMillis() + ""); // TODO + calculateTotalPrice(contract, contractProducts); contractMapper.insert(contract); - // 1.2 插入合同关联商品 - if (CollUtil.isNotEmpty(createReqVO.getProducts())) { // 如果有的话 - List productList = convertContractProductList(createReqVO, contract.getId()); - contractProductMapper.insertBatch(productList); - // 更新合同商品总金额 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.getProducts(), CrmBusinessUpdateProductReqBO.Item.class))); - } + // 2.2 插入合同关联商品 + if (CollUtil.isNotEmpty(contractProducts)) { + contractProducts.forEach(item -> item.setContractId(contract.getId())); + contractProductMapper.insertBatch(contractProducts); } - // 2. 创建数据权限 - crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId) + // 3. 创建数据权限 + crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(contract.getOwnerUserId()) .setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()).setBizId(contract.getId()) .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); - // 3. 记录操作日志上下文 + // 4. 记录操作日志上下文 LogRecordContext.putVariable("contract", contract); return contract.getId(); } @@ -124,6 +123,7 @@ public class CrmContractServiceImpl implements CrmContractService { @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) public void updateContract(CrmContractSaveReqVO updateReqVO) { Assert.notNull(updateReqVO.getId(), "合同编号不能为空"); + updateReqVO.setOwnerUserId(null); // 不允许更新的字段 // 1.1 校验存在 CrmContractDO contract = validateContractExists(updateReqVO.getId()); // 1.2 只有草稿、审批中,可以编辑; @@ -131,65 +131,41 @@ public class CrmContractServiceImpl implements CrmContractService { CrmAuditStatusEnum.PROCESS.getStatus())) { throw exception(CONTRACT_UPDATE_FAIL_EDITING_PROHIBITED); } + // 1.3 校验产品项的有效性 + List contractProducts = validateContractProducts(updateReqVO.getProducts()); + // 1.4 校验关联字段 validateRelationDataExists(updateReqVO); // 2.1 更新合同 CrmContractDO updateObj = BeanUtils.toBean(updateReqVO, CrmContractDO.class); + calculateTotalPrice(updateObj, contractProducts); contractMapper.updateById(updateObj); // 2.2 更新合同关联商品 - updateContractProduct(updateReqVO, updateObj.getId()); + updateContractProduct(updateReqVO.getId(), contractProducts); // 3. 记录操作日志上下文 LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(contract, CrmContractSaveReqVO.class)); LogRecordContext.putVariable("contractName", contract.getName()); } - private void updateContractProduct(CrmContractSaveReqVO updateReqVO, Long contractId) { - if (CollUtil.isEmpty(updateReqVO.getProducts())) { - return; - } - List newProductList = convertContractProductList(updateReqVO, contractId); - List oldProductList = contractProductMapper.selectListByContractId(contractId); - List> diffList = diffList(oldProductList, newProductList, (oldObj, newObj) -> { - boolean match = ObjUtil.equal(oldObj.getProductId(), newObj.getProductId()); - if (match) { - newObj.setId(oldObj.getId()); // 设置一下老的编号更新时需要使用 - } - return match; - }); + private void updateContractProduct(Long id, List newList) { + List oldList = contractProductMapper.selectListByContractId(id); + List> diffList = diffList(oldList, newList, // id 不同,就认为是不同的记录 + (oldVal, newVal) -> oldVal.getId().equals(newVal.getId())); if (CollUtil.isNotEmpty(diffList.get(0))) { + diffList.get(0).forEach(o -> o.setContractId(id)); contractProductMapper.insertBatch(diffList.get(0)); } if (CollUtil.isNotEmpty(diffList.get(1))) { contractProductMapper.updateBatch(diffList.get(1)); } if (CollUtil.isNotEmpty(diffList.get(2))) { - contractProductMapper.deleteBatchIds(convertList(diffList.get(2), CrmContractProductDO::getId)); + contractProductMapper.deleteBatchIds(convertSet(diffList.get(2), CrmContractProductDO::getId)); } } // TODO @合同待定:缺一个取消合同的接口;只有草稿、审批中可以取消;CrmAuditStatusEnum - private List convertContractProductList(CrmContractSaveReqVO reqVO, Long contractId) { - // 校验商品存在 - 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); - // 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())); -// }); - } - /** * 校验关联数据是否存在 * @@ -197,17 +173,38 @@ public class CrmContractServiceImpl implements CrmContractService { */ private void validateRelationDataExists(CrmContractSaveReqVO reqVO) { // 1. 校验客户 - if (reqVO.getCustomerId() != null && customerService.getCustomer(reqVO.getCustomerId()) == null) { - throw exception(CUSTOMER_NOT_EXISTS); + if (reqVO.getCustomerId() != null) { + customerService.validateCustomer(reqVO.getCustomerId()); } // 2. 校验负责人 - if (reqVO.getOwnerUserId() != null && adminUserApi.getUser(reqVO.getOwnerUserId()) == null) { - throw exception(USER_NOT_EXISTS); + if (reqVO.getOwnerUserId() != null) { + adminUserApi.validateUser(reqVO.getOwnerUserId()); } // 3. 如果有关联商机,则需要校验存在 - if (reqVO.getBusinessId() != null && businessService.getBusiness(reqVO.getBusinessId()) == null) { - throw exception(BUSINESS_NOT_EXISTS); + if (reqVO.getBusinessId() != null) { + businessService.validateBusiness(reqVO.getBusinessId()); } + // 4. 校验签约相关字段 + if (reqVO.getSignContactId() != null) { + contactService.validateContact(reqVO.getSignContactId()); + } + if (reqVO.getSignUserId() != null) { + adminUserApi.validateUser(reqVO.getSignUserId()); + } + } + + private List validateContractProducts(List list) { + // 1. 校验产品存在 + productService.validProductList(convertSet(list, CrmContractSaveReqVO.Product::getProductId)); + // 2. 转化为 CrmContractProductDO 列表 + return convertList(list, o -> BeanUtils.toBean(o, CrmContractProductDO.class, + item -> item.setTotalPrice(MoneyUtils.priceMultiply(item.getContractPrice(), item.getCount())))); + } + + private void calculateTotalPrice(CrmContractDO contract, List contractProducts) { + contract.setTotalProductPrice(getSumValue(contractProducts, CrmContractProductDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO)); + BigDecimal discountPrice = MoneyUtils.priceMultiplyPercent(contract.getTotalProductPrice(), contract.getDiscountPercent()); + contract.setTotalPrice(contract.getTotalProductPrice().subtract(discountPrice)); } @Override