mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-01 02:38:43 +08:00 
			
		
		
		
	CRM-合同:完善新增合同插入关联的商品
This commit is contained in:
		| @@ -11,6 +11,7 @@ public interface ErrorCodeConstants { | |||||||
|  |  | ||||||
|     // ========== 合同管理 1-020-000-000 ========== |     // ========== 合同管理 1-020-000-000 ========== | ||||||
|     ErrorCode CONTRACT_NOT_EXISTS = new ErrorCode(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 ========== |     // ========== 线索管理 1-020-001-000 ========== | ||||||
|     ErrorCode CLUE_NOT_EXISTS = new ErrorCode(1_020_001_000, "线索不存在"); |     ErrorCode CLUE_NOT_EXISTS = new ErrorCode(1_020_001_000, "线索不存在"); | ||||||
|   | |||||||
| @@ -89,6 +89,9 @@ public class CrmContractSaveReqVO { | |||||||
|     @DiffLogField(name = "备注") |     @DiffLogField(name = "备注") | ||||||
|     private String remark; |     private String remark; | ||||||
|  |  | ||||||
|  |     @Schema(description = "审批状态", example = "1") | ||||||
|  |     private Integer auditStatus; | ||||||
|  |  | ||||||
|     @Schema(description = "产品列表") |     @Schema(description = "产品列表") | ||||||
|     private List<CrmContractProductItem> productItems; |     private List<CrmContractProductItem> productItems; | ||||||
|  |  | ||||||
| @@ -104,7 +107,7 @@ public class CrmContractSaveReqVO { | |||||||
|  |  | ||||||
|         @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") |         @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") | ||||||
|         @NotNull(message = "产品数量不能为空") |         @NotNull(message = "产品数量不能为空") | ||||||
|         private Long count; |         private Integer count; | ||||||
|  |  | ||||||
|         @Schema(description = "产品折扣") |         @Schema(description = "产品折扣") | ||||||
|         private Integer discountPercent; |         private Integer discountPercent; | ||||||
|   | |||||||
| @@ -2,7 +2,9 @@ package cn.iocoder.yudao.module.crm.service.contract; | |||||||
|  |  | ||||||
| import cn.hutool.core.collection.CollUtil; | import cn.hutool.core.collection.CollUtil; | ||||||
| import cn.hutool.core.collection.ListUtil; | 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.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.BeanUtils; | ||||||
| import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; | import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; | ||||||
| import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; | 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.CrmContractSaveReqVO; | ||||||
| import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; | 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.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.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.dal.mysql.contract.CrmContractMapper; | ||||||
| import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum; | 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.common.CrmBizTypeEnum; | ||||||
| import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; | 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.framework.permission.core.annotations.CrmPermission; | ||||||
| import cn.iocoder.yudao.module.crm.service.business.CrmBusinessProductService; | 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.followup.bo.CrmUpdateFollowUpReqBO; | ||||||
| import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; | import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; | ||||||
| import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; | import cn.iocoder.yudao.module.crm.service.permission.bo.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.context.LogRecordContext; | ||||||
| import com.mzt.logapi.service.impl.DiffParseFunction; | import com.mzt.logapi.service.impl.DiffParseFunction; | ||||||
| import com.mzt.logapi.starter.annotation.LogRecord; | import com.mzt.logapi.starter.annotation.LogRecord; | ||||||
| @@ -30,10 +39,14 @@ import org.springframework.validation.annotation.Validated; | |||||||
|  |  | ||||||
| import java.util.Collection; | import java.util.Collection; | ||||||
| import java.util.List; | 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.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.crm.enums.LogRecordConstants.*; | ||||||
|  | import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * CRM 合同 Service 实现类 |  * CRM 合同 Service 实现类 | ||||||
| @@ -53,16 +66,25 @@ public class CrmContractServiceImpl implements CrmContractService { | |||||||
|     private CrmPermissionService crmPermissionService; |     private CrmPermissionService crmPermissionService; | ||||||
|     @Resource |     @Resource | ||||||
|     private CrmBusinessProductService businessProductService; |     private CrmBusinessProductService businessProductService; | ||||||
|  |     @Resource | ||||||
|  |     private CrmProductService productService; | ||||||
|     @Resource |     @Resource | ||||||
|     private BpmProcessInstanceApi bpmProcessInstanceApi; |     private BpmProcessInstanceApi bpmProcessInstanceApi; | ||||||
|  |     @Resource | ||||||
|  |     private CrmCustomerService customerService; | ||||||
|  |     @Resource | ||||||
|  |     private CrmContactService contactService; | ||||||
|  |     @Resource | ||||||
|  |     private CrmBusinessService businessService; | ||||||
|  |     @Resource | ||||||
|  |     private AdminUserApi adminUserApi; | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     @Transactional(rollbackFor = Exception.class) |     @Transactional(rollbackFor = Exception.class) | ||||||
|     @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_CREATE_SUB_TYPE, bizNo = "{{#contract.id}}", |     @LogRecord(type = CRM_CONTRACT_TYPE, subType = CRM_CONTRACT_CREATE_SUB_TYPE, bizNo = "{{#contract.id}}", | ||||||
|             success = CRM_CONTRACT_CREATE_SUCCESS) |             success = CRM_CONTRACT_CREATE_SUCCESS) | ||||||
|     public Long createContract(CrmContractSaveReqVO createReqVO, Long userId) { |     public Long createContract(CrmContractSaveReqVO createReqVO, Long userId) { | ||||||
|         // TODO @合同待定:插入合同商品;需要搞个 BusinessProductDO |         validateRelationDataExists(createReqVO); | ||||||
|         // 插入合同 |         // 插入合同 | ||||||
|         CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class).setId(null); |         CrmContractDO contract = BeanUtils.toBean(createReqVO, CrmContractDO.class).setId(null); | ||||||
|         contractMapper.insert(contract); |         contractMapper.insert(contract); | ||||||
| @@ -71,6 +93,10 @@ public class CrmContractServiceImpl implements CrmContractService { | |||||||
|         crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId) |         crmPermissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(userId) | ||||||
|                 .setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()).setBizId(contract.getId()) |                 .setBizType(CrmBizTypeEnum.CRM_CONTRACT.getType()).setBizId(contract.getId()) | ||||||
|                 .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); |                 .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); | ||||||
|  |  | ||||||
|  |         // 插入商机关联商品 | ||||||
|  |         List<CrmBusinessProductDO> businessProduct = convertBusinessProductList(createReqVO); | ||||||
|  |         businessProductService.insertBatch(businessProduct); | ||||||
|         // 4. 记录操作日志上下文 |         // 4. 记录操作日志上下文 | ||||||
|         LogRecordContext.putVariable("contract", contract); |         LogRecordContext.putVariable("contract", contract); | ||||||
|         return contract.getId(); |         return contract.getId(); | ||||||
| @@ -83,12 +109,21 @@ public class CrmContractServiceImpl implements CrmContractService { | |||||||
|     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) |     @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) | ||||||
|     public void updateContract(CrmContractSaveReqVO updateReqVO) { |     public void updateContract(CrmContractSaveReqVO updateReqVO) { | ||||||
|         // TODO @合同待定:只有草稿、审批中,可以编辑; |         // 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 oldContract = validateContractExists(updateReqVO.getId()); | ||||||
|         // 更新合同 |         // 更新合同 | ||||||
|         CrmContractDO updateObj = BeanUtils.toBean(updateReqVO, CrmContractDO.class); |         CrmContractDO updateObj = BeanUtils.toBean(updateReqVO, CrmContractDO.class); | ||||||
|         contractMapper.updateById(updateObj); |         contractMapper.updateById(updateObj); | ||||||
|         // TODO @合同待定:插入合同商品;需要搞个 BusinessProductDO |  | ||||||
|  |         // TODO puhui999: @芋艿:合同变更关联的商机后商品怎么处理? | ||||||
|  |         //List<CrmBusinessProductDO> businessProduct = convertBusinessProductList(updateReqVO); | ||||||
|  |         //businessProductService.selectListByBusinessId() | ||||||
|  |         //diffList() | ||||||
|  |  | ||||||
|         // 3. 记录操作日志上下文 |         // 3. 记录操作日志上下文 | ||||||
|         LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldContract, CrmContractSaveReqVO.class)); |         LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldContract, CrmContractSaveReqVO.class)); | ||||||
| @@ -97,8 +132,55 @@ public class CrmContractServiceImpl implements CrmContractService { | |||||||
|  |  | ||||||
|     // TODO @合同待定:缺一个取消合同的接口;只有草稿、审批中可以取消;CrmAuditStatusEnum |     // 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 |     @Override | ||||||
|     @Transactional(rollbackFor = Exception.class) |     @Transactional(rollbackFor = Exception.class) | ||||||
| @@ -151,6 +233,7 @@ public class CrmContractServiceImpl implements CrmContractService { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|  |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public void handleApprove(Long id, Long userId) { |     public void handleApprove(Long id, Long userId) { | ||||||
|         // 创建合同审批流程实例 |         // 创建合同审批流程实例 | ||||||
|         String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO() |         String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO() | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| package cn.iocoder.yudao.module.crm.service.contract.listener; | package cn.iocoder.yudao.module.crm.service.contract.listener; | ||||||
|  |  | ||||||
| public class CrmContractResultListener { | public class CrmContractResultListener { | ||||||
|  |     // TODO puhui999: @芋艿: 艿艿写一下这个,没研究明白哈哈 | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 puhui999
					puhui999