Browse Source

CRM-合同:完善新增合同插入关联的商品

puhui999 1 year ago
parent
commit
4418a7bebc

+ 1 - 0
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java

@@ -11,6 +11,7 @@ public interface ErrorCodeConstants {
 
     // ========== 合同管理 1-020-000-000 ==========
     ErrorCode CONTRACT_NOT_EXISTS = new ErrorCode(1_020_000_000, "合同不存在");
+    ErrorCode CONTRACT_UPDATE_FAIL_EDITING_PROHIBITED = new ErrorCode(1_020_000_001, "更新合同失败,原因:禁止编辑");
 
     // ========== 线索管理 1-020-001-000 ==========
     ErrorCode CLUE_NOT_EXISTS = new ErrorCode(1_020_001_000, "线索不存在");

+ 4 - 1
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractSaveReqVO.java

@@ -89,6 +89,9 @@ public class CrmContractSaveReqVO {
     @DiffLogField(name = "备注")
     private String remark;
 
+    @Schema(description = "审批状态", example = "1")
+    private Integer auditStatus;
+
     @Schema(description = "产品列表")
     private List<CrmContractProductItem> productItems;
 
@@ -104,7 +107,7 @@ public class CrmContractSaveReqVO {
 
         @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911")
         @NotNull(message = "产品数量不能为空")
-        private Long count;
+        private Integer count;
 
         @Schema(description = "产品折扣")
         private Integer discountPercent;

+ 88 - 5
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java

@@ -2,7 +2,9 @@ package cn.iocoder.yudao.module.crm.service.contract;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.collection.ListUtil;
+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.module.bpm.api.task.BpmProcessInstanceApi;
 import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
@@ -10,16 +12,23 @@ 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.product.CrmProductDO;
 import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper;
 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.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;
 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
+import cn.iocoder.yudao.module.crm.service.product.CrmProductService;
+import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
 import com.mzt.logapi.context.LogRecordContext;
 import com.mzt.logapi.service.impl.DiffParseFunction;
 import com.mzt.logapi.starter.annotation.LogRecord;
@@ -30,10 +39,14 @@ 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.module.crm.enums.ErrorCodeConstants.CONTRACT_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.*;
+import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS;
 
 /**
  * CRM 合同 Service 实现类
@@ -53,16 +66,25 @@ public class CrmContractServiceImpl implements CrmContractService {
     private CrmPermissionService crmPermissionService;
     @Resource
     private CrmBusinessProductService businessProductService;
-
+    @Resource
+    private CrmProductService productService;
     @Resource
     private BpmProcessInstanceApi bpmProcessInstanceApi;
+    @Resource
+    private CrmCustomerService customerService;
+    @Resource
+    private CrmContactService contactService;
+    @Resource
+    private CrmBusinessService businessService;
+    @Resource
+    private AdminUserApi adminUserApi;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
     @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) {
-        // TODO @合同待定:插入合同商品;需要搞个 BusinessProductDO
+        validateRelationDataExists(createReqVO);
         // 插入合同
         CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class).setId(null);
         contractMapper.insert(contract);
@@ -71,6 +93,10 @@ public class CrmContractServiceImpl implements CrmContractService {
         crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId)
                 .setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()).setBizId(contract.getId())
                 .setLevel(CrmPermissionLevelEnum.OWNER.getLevel()));
+
+        // 插入商机关联商品
+        List<CrmBusinessProductDO> businessProduct = convertBusinessProductList(createReqVO);
+        businessProductService.insertBatch(businessProduct);
         // 4. 记录操作日志上下文
         LogRecordContext.putVariable("contract", contract);
         return contract.getId();
@@ -83,12 +109,21 @@ public class CrmContractServiceImpl implements CrmContractService {
     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
     public void updateContract(CrmContractSaveReqVO updateReqVO) {
         // TODO @合同待定:只有草稿、审批中,可以编辑;
+        if (ObjUtil.notEqual(updateReqVO.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus()) ||
+                ObjUtil.notEqual(updateReqVO.getAuditStatus(), CrmAuditStatusEnum.PROCESS.getStatus())) {
+            throw exception(CONTRACT_UPDATE_FAIL_EDITING_PROHIBITED);
+        }
+        validateRelationDataExists(updateReqVO);
         // 校验存在
         CrmContractDO oldContract = validateContractExists(updateReqVO.getId());
         // 更新合同
         CrmContractDO updateObj = BeanUtils.toBean(updateReqVO, CrmContractDO.class);
         contractMapper.updateById(updateObj);
-        // TODO @合同待定:插入合同商品;需要搞个 BusinessProductDO
+
+        // TODO puhui999: @芋艿:合同变更关联的商机后商品怎么处理?
+        //List<CrmBusinessProductDO> businessProduct = convertBusinessProductList(updateReqVO);
+        //businessProductService.selectListByBusinessId()
+        //diffList()
 
         // 3. 记录操作日志上下文
         LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldContract, CrmContractSaveReqVO.class));
@@ -97,8 +132,55 @@ public class CrmContractServiceImpl implements CrmContractService {
 
     // TODO @合同待定:缺一个取消合同的接口;只有草稿、审批中可以取消;CrmAuditStatusEnum
 
-    // TODO @合同待定:缺一个发起审批的接口;只有草稿可以发起审批;CrmAuditStatusEnum
+    private List<CrmBusinessProductDO> convertBusinessProductList(CrmContractSaveReqVO reqVO) {
+        // 校验商品存在
+        Set<Long> productIds = convertSet(reqVO.getProductItems(), CrmContractSaveReqVO.CrmContractProductItem::getId);
+        List<CrmProductDO> productList = productService.getProductList(productIds);
+        if (CollUtil.isEmpty(productIds) || productList.size() != productIds.size()) {
+            throw exception(PRODUCT_NOT_EXISTS);
+        }
+        Map<Long, CrmProductDO> productMap = convertMap(productList, CrmProductDO::getId);
+        return convertList(reqVO.getProductItems(), productItem -> {
+            CrmBusinessProductDO businessProduct = BeanUtils.toBean(productMap.get(productItem.getId()), CrmBusinessProductDO.class);
+            businessProduct.setId(null).setBusinessId(reqVO.getBusinessId()).setProductId(productItem.getId())
+                    .setCount(productItem.getCount()).setDiscountPercent(productItem.getDiscountPercent()).setTotalPrice(calculator(businessProduct));
+            return businessProduct;
+        });
+    }
 
+    /**
+     * 计算商品总价
+     *
+     * @param businessProduct 关联商品
+     * @return 商品总价
+     */
+    private Integer calculator(CrmBusinessProductDO businessProduct) {
+        int price = businessProduct.getPrice() * businessProduct.getCount();
+        if (businessProduct.getDiscountPercent() == null) {
+            return price;
+        }
+        return MoneyUtils.calculateRatePriceFloor(price, (double) (businessProduct.getDiscountPercent() / 100));
+    }
+
+    /**
+     * 校验关联数据是否存在
+     *
+     * @param reqVO 请求
+     */
+    private void validateRelationDataExists(CrmContractSaveReqVO reqVO) {
+        // 1. 校验客户
+        if (reqVO.getCustomerId() != null && customerService.getCustomer(reqVO.getCustomerId()) == null) {
+            throw exception(CUSTOMER_NOT_EXISTS);
+        }
+        // 2. 校验负责人
+        if (reqVO.getOwnerUserId() != null && adminUserApi.getUser(reqVO.getOwnerUserId()) == null) {
+            throw exception(USER_NOT_EXISTS);
+        }
+        // 4. 如果有关联商机,则需要校验存在
+        if (reqVO.getBusinessId() != null && businessService.getBusiness(reqVO.getBusinessId()) == null) {
+            throw exception(BUSINESS_NOT_EXISTS);
+        }
+    }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -151,6 +233,7 @@ public class CrmContractServiceImpl implements CrmContractService {
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void handleApprove(Long id, Long userId) {
         // 创建合同审批流程实例
         String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO()

+ 1 - 0
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/listener/CrmContractResultListener.java

@@ -1,4 +1,5 @@
 package cn.iocoder.yudao.module.crm.service.contract.listener;
 
 public class CrmContractResultListener {
+    // TODO puhui999: @芋艿: 艿艿写一下这个,没研究明白哈哈
 }