Commit 720b54c353cc199d86aae346ecacce7c471070f0

Authored by puhui999
1 parent c3337f21

CRM: 完善回款操作日志

yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java
@@ -15,6 +15,7 @@ public interface ErrorCodeConstants { @@ -15,6 +15,7 @@ public interface ErrorCodeConstants {
15 ErrorCode CONTRACT_SUBMIT_FAIL_NOT_DRAFT = new ErrorCode(1_020_000_002, "合同提交审核失败,原因:合同没处在未提交状态"); 15 ErrorCode CONTRACT_SUBMIT_FAIL_NOT_DRAFT = new ErrorCode(1_020_000_002, "合同提交审核失败,原因:合同没处在未提交状态");
16 ErrorCode CONTRACT_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS = new ErrorCode(1_020_000_003, "更新合同审核状态失败,原因:合同不是审核中状态"); 16 ErrorCode CONTRACT_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS = new ErrorCode(1_020_000_003, "更新合同审核状态失败,原因:合同不是审核中状态");
17 ErrorCode CONTRACT_NO_EXISTS = new ErrorCode(1_020_000_004, "生成合同序列号重复,请重试"); 17 ErrorCode CONTRACT_NO_EXISTS = new ErrorCode(1_020_000_004, "生成合同序列号重复,请重试");
  18 + ErrorCode CONTRACT_DELETE_FAIL = new ErrorCode(1_020_000_005, "删除合同失败,原因:有被回款所使用");
18 19
19 // ========== 线索管理 1-020-001-000 ========== 20 // ========== 线索管理 1-020-001-000 ==========
20 ErrorCode CLUE_NOT_EXISTS = new ErrorCode(1_020_001_000, "线索不存在"); 21 ErrorCode CLUE_NOT_EXISTS = new ErrorCode(1_020_001_000, "线索不存在");
@@ -40,6 +41,7 @@ public interface ErrorCodeConstants { @@ -40,6 +41,7 @@ public interface ErrorCodeConstants {
40 ErrorCode RECEIVABLE_NO_EXISTS = new ErrorCode(1_020_004_005, "生成回款序列号重复,请重试"); 41 ErrorCode RECEIVABLE_NO_EXISTS = new ErrorCode(1_020_004_005, "生成回款序列号重复,请重试");
41 ErrorCode RECEIVABLE_CREATE_FAIL_CONTRACT_NOT_APPROVE = new ErrorCode(1_020_004_006, "创建回款失败,原因:合同不是审核通过状态"); 42 ErrorCode RECEIVABLE_CREATE_FAIL_CONTRACT_NOT_APPROVE = new ErrorCode(1_020_004_006, "创建回款失败,原因:合同不是审核通过状态");
42 ErrorCode RECEIVABLE_CREATE_FAIL_PRICE_EXCEEDS_LIMIT = new ErrorCode(1_020_004_007, "创建回款失败,原因:回款金额超出合同金额,目前剩余可退:{} 元"); 43 ErrorCode RECEIVABLE_CREATE_FAIL_PRICE_EXCEEDS_LIMIT = new ErrorCode(1_020_004_007, "创建回款失败,原因:回款金额超出合同金额,目前剩余可退:{} 元");
  44 + ErrorCode RECEIVABLE_DELETE_FAIL_IS_APPROVE = new ErrorCode(1_020_004_008, "删除回款失败,原因:回款审批已通过");
43 45
44 // ========== 回款计划 1-020-005-000 ========== 46 // ========== 回款计划 1-020-005-000 ==========
45 ErrorCode RECEIVABLE_PLAN_NOT_EXISTS = new ErrorCode(1_020_005_000, "回款计划不存在"); 47 ErrorCode RECEIVABLE_PLAN_NOT_EXISTS = new ErrorCode(1_020_005_000, "回款计划不存在");
yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java
@@ -142,11 +142,11 @@ public interface LogRecordConstants { @@ -142,11 +142,11 @@ public interface LogRecordConstants {
142 142
143 String CRM_RECEIVABLE_TYPE = "CRM 回款"; 143 String CRM_RECEIVABLE_TYPE = "CRM 回款";
144 String CRM_RECEIVABLE_CREATE_SUB_TYPE = "创建回款"; 144 String CRM_RECEIVABLE_CREATE_SUB_TYPE = "创建回款";
145 - String CRM_RECEIVABLE_CREATE_SUCCESS = "创建了合同【{getContractById{#receivable.contractId}}】的第【{{#receivable.period}}】期回款"; 145 + String CRM_RECEIVABLE_CREATE_SUCCESS = "创建了合同【{getContractById{#receivable.contractId}}】的{{#period != null ? '【第'+ #period +'期】' : '编号为【'+ #receivable.no +'】的'}}回款";
146 String CRM_RECEIVABLE_UPDATE_SUB_TYPE = "更新回款"; 146 String CRM_RECEIVABLE_UPDATE_SUB_TYPE = "更新回款";
147 - String CRM_RECEIVABLE_UPDATE_SUCCESS = "更新了合同【{getContractById{#receivable.contractId}}】的第【{{#receivable.period}}】期回款: {_DIFF{#updateReqVO}}"; 147 + String CRM_RECEIVABLE_UPDATE_SUCCESS = "更新了合同【{getContractById{#receivable.contractId}}】的{{#period != null ? '【第'+ #period +'期】' : '编号为【'+ #receivable.no +'】的'}}回款: {_DIFF{#updateReqVO}}";
148 String CRM_RECEIVABLE_DELETE_SUB_TYPE = "删除回款"; 148 String CRM_RECEIVABLE_DELETE_SUB_TYPE = "删除回款";
149 - String CRM_RECEIVABLE_DELETE_SUCCESS = "删除了合同【{getContractById{#receivable.contractId}}】的第【{{#receivable.period}}】期回款"; 149 + String CRM_RECEIVABLE_DELETE_SUCCESS = "删除了合同【{getContractById{#receivable.contractId}}】的{{#period != null ? '【第'+ #period +'期】' : '编号为【'+ #receivable.no +'】的'}}回款";
150 String CRM_RECEIVABLE_SUBMIT_SUB_TYPE = "提交回款审批"; 150 String CRM_RECEIVABLE_SUBMIT_SUB_TYPE = "提交回款审批";
151 String CRM_RECEIVABLE_SUBMIT_SUCCESS = "提交编号为【{{#receivableNo}}】的回款审批成功"; 151 String CRM_RECEIVABLE_SUBMIT_SUCCESS = "提交编号为【{{#receivableNo}}】的回款审批成功";
152 152
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/plan/CrmReceivablePlanRespVO.java
1 package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan; 1 package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan;
2 2
3 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableRespVO; 3 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableRespVO;
  4 +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
4 import com.alibaba.excel.annotation.ExcelProperty; 5 import com.alibaba.excel.annotation.ExcelProperty;
5 import io.swagger.v3.oas.annotations.media.Schema; 6 import io.swagger.v3.oas.annotations.media.Schema;
6 import lombok.Data; 7 import lombok.Data;
@@ -8,53 +9,69 @@ import lombok.Data; @@ -8,53 +9,69 @@ import lombok.Data;
8 import java.math.BigDecimal; 9 import java.math.BigDecimal;
9 import java.time.LocalDateTime; 10 import java.time.LocalDateTime;
10 11
11 -// TODO @puhui999:缺导出  
12 @Schema(description = "管理后台 - CRM 回款计划 Response VO") 12 @Schema(description = "管理后台 - CRM 回款计划 Response VO")
13 @Data 13 @Data
  14 +@ExcelIgnoreUnannotated
14 public class CrmReceivablePlanRespVO { 15 public class CrmReceivablePlanRespVO {
15 16
16 @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 17 @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  18 + @ExcelProperty("编号")
17 private Long id; 19 private Long id;
18 20
19 @Schema(description = "期数", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 21 @Schema(description = "期数", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  22 + @ExcelProperty("期数")
20 private Integer period; 23 private Integer period;
21 24
22 @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 25 @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  26 + @ExcelProperty("客户编号")
23 private Long customerId; 27 private Long customerId;
24 @Schema(description = "客户名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "test") 28 @Schema(description = "客户名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "test")
  29 + @ExcelProperty("客户名字")
25 private String customerName; 30 private String customerName;
26 31
27 @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 32 @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  33 + @ExcelProperty("合同编号")
28 private Long contractId; 34 private Long contractId;
29 @Schema(description = "合同编号", example = "Q110") 35 @Schema(description = "合同编号", example = "Q110")
  36 + @ExcelProperty("合同编号")
30 private String contractNo; 37 private String contractNo;
31 38
32 @Schema(description = "负责人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 39 @Schema(description = "负责人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  40 + @ExcelProperty("负责人编号")
33 private Long ownerUserId; 41 private Long ownerUserId;
34 @Schema(description = "负责人", example = "test") 42 @Schema(description = "负责人", example = "test")
  43 + @ExcelProperty("负责人")
35 private String ownerUserName; 44 private String ownerUserName;
36 45
37 @Schema(description = "计划回款日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02") 46 @Schema(description = "计划回款日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02")
  47 + @ExcelProperty("计划回款日期")
38 private LocalDateTime returnTime; 48 private LocalDateTime returnTime;
39 49
40 @Schema(description = "计划回款方式", example = "1") 50 @Schema(description = "计划回款方式", example = "1")
  51 + @ExcelProperty("计划回款方式")
41 private Integer returnType; 52 private Integer returnType;
42 53
43 @Schema(description = "计划回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "9000") 54 @Schema(description = "计划回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "9000")
  55 + @ExcelProperty("计划回款金额")
44 private BigDecimal price; 56 private BigDecimal price;
45 57
46 @Schema(description = "回款编号", example = "19852") 58 @Schema(description = "回款编号", example = "19852")
  59 + @ExcelProperty("回款编号")
47 private Long receivableId; 60 private Long receivableId;
48 @Schema(description = "回款信息") 61 @Schema(description = "回款信息")
  62 + @ExcelProperty("回款信息")
49 private CrmReceivableRespVO receivable; 63 private CrmReceivableRespVO receivable;
50 64
51 @Schema(description = "提前几天提醒", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 65 @Schema(description = "提前几天提醒", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  66 + @ExcelProperty("提前几天提醒")
52 private Integer remindDays; 67 private Integer remindDays;
53 68
54 @Schema(description = "提醒日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02") 69 @Schema(description = "提醒日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02")
  70 + @ExcelProperty("提醒日期")
55 private LocalDateTime remindTime; 71 private LocalDateTime remindTime;
56 72
57 @Schema(description = "备注", example = "备注") 73 @Schema(description = "备注", example = "备注")
  74 + @ExcelProperty("备注")
58 private String remark; 75 private String remark;
59 76
60 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 77 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/receivable/vo/receivable/CrmReceivableRespVO.java
1 package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable; 1 package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable;
2 2
3 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractRespVO; 3 import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractRespVO;
  4 +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
4 import com.alibaba.excel.annotation.ExcelProperty; 5 import com.alibaba.excel.annotation.ExcelProperty;
5 import io.swagger.v3.oas.annotations.media.Schema; 6 import io.swagger.v3.oas.annotations.media.Schema;
6 import lombok.Data; 7 import lombok.Data;
@@ -8,37 +9,47 @@ import lombok.Data; @@ -8,37 +9,47 @@ import lombok.Data;
8 import java.math.BigDecimal; 9 import java.math.BigDecimal;
9 import java.time.LocalDateTime; 10 import java.time.LocalDateTime;
10 11
11 -// TODO 芋艿:导出的 VO,可以考虑使用 @Excel 注解,实现导出功能  
12 @Schema(description = "管理后台 - CRM 回款 Response VO") 12 @Schema(description = "管理后台 - CRM 回款 Response VO")
13 @Data 13 @Data
  14 +@ExcelIgnoreUnannotated
14 public class CrmReceivableRespVO { 15 public class CrmReceivableRespVO {
15 16
16 @Schema(description = "编号", example = "25787") 17 @Schema(description = "编号", example = "25787")
  18 + @ExcelProperty("编号")
17 private Long id; 19 private Long id;
18 20
19 @Schema(description = "回款编号", example = "31177") 21 @Schema(description = "回款编号", example = "31177")
  22 + @ExcelProperty("回款编号")
20 private String no; 23 private String no;
21 24
22 @Schema(description = "回款计划编号", example = "1024") 25 @Schema(description = "回款计划编号", example = "1024")
  26 + @ExcelProperty("回款计划编号")
23 private Long planId; 27 private Long planId;
24 28
25 @Schema(description = "回款方式", example = "2") 29 @Schema(description = "回款方式", example = "2")
  30 + @ExcelProperty("回款方式")
26 private Integer returnType; 31 private Integer returnType;
27 32
28 @Schema(description = "回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "9000") 33 @Schema(description = "回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "9000")
  34 + @ExcelProperty("回款金额")
29 private BigDecimal price; 35 private BigDecimal price;
30 36
31 @Schema(description = "计划回款日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02") 37 @Schema(description = "计划回款日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02")
  38 + @ExcelProperty("计划回款日期")
32 private LocalDateTime returnTime; 39 private LocalDateTime returnTime;
33 40
34 @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 41 @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  42 + @ExcelProperty("客户编号")
35 private Long customerId; 43 private Long customerId;
36 @Schema(description = "客户名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "test") 44 @Schema(description = "客户名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "test")
  45 + @ExcelProperty("客户名字")
37 private String customerName; 46 private String customerName;
38 47
39 @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") 48 @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  49 + @ExcelProperty("合同编号")
40 private Long contractId; 50 private Long contractId;
41 @Schema(description = "合同信息") 51 @Schema(description = "合同信息")
  52 + @ExcelProperty("合同信息")
42 private CrmContractRespVO contract; 53 private CrmContractRespVO contract;
43 54
44 @Schema(description = "负责人的用户编号", example = "25682") 55 @Schema(description = "负责人的用户编号", example = "25682")
@@ -56,20 +67,26 @@ public class CrmReceivableRespVO { @@ -56,20 +67,26 @@ public class CrmReceivableRespVO {
56 private String processInstanceId; 67 private String processInstanceId;
57 68
58 @Schema(description = "审批状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") 69 @Schema(description = "审批状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  70 + @ExcelProperty("审批状态")
59 private Integer auditStatus; 71 private Integer auditStatus;
60 72
61 - @Schema(description = "备注", example = "备注") 73 + @Schema(description = "工作流编号", example = "备注")
  74 + @ExcelProperty("工作流编号")
62 private String remark; 75 private String remark;
63 76
64 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 77 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  78 + @ExcelProperty("创建时间")
65 private LocalDateTime createTime; 79 private LocalDateTime createTime;
66 80
67 @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED) 81 @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
  82 + @ExcelProperty("更新时间")
68 private LocalDateTime updateTime; 83 private LocalDateTime updateTime;
69 84
70 @Schema(description = "创建人", example = "25682") 85 @Schema(description = "创建人", example = "25682")
  86 + @ExcelProperty("创建人")
71 private String creator; 87 private String creator;
72 @Schema(description = "创建人名字", example = "test") 88 @Schema(description = "创建人名字", example = "test")
  89 + @ExcelProperty("创建人名字")
73 private String creatorName; 90 private String creatorName;
74 91
75 } 92 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java
@@ -30,12 +30,14 @@ import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; @@ -30,12 +30,14 @@ import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
30 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; 30 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
31 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; 31 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
32 import cn.iocoder.yudao.module.crm.service.product.CrmProductService; 32 import cn.iocoder.yudao.module.crm.service.product.CrmProductService;
  33 +import cn.iocoder.yudao.module.crm.service.receivable.CrmReceivableService;
33 import cn.iocoder.yudao.module.system.api.user.AdminUserApi; 34 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
34 import com.mzt.logapi.context.LogRecordContext; 35 import com.mzt.logapi.context.LogRecordContext;
35 import com.mzt.logapi.service.impl.DiffParseFunction; 36 import com.mzt.logapi.service.impl.DiffParseFunction;
36 import com.mzt.logapi.starter.annotation.LogRecord; 37 import com.mzt.logapi.starter.annotation.LogRecord;
37 import jakarta.annotation.Resource; 38 import jakarta.annotation.Resource;
38 import lombok.extern.slf4j.Slf4j; 39 import lombok.extern.slf4j.Slf4j;
  40 +import org.springframework.context.annotation.Lazy;
39 import org.springframework.stereotype.Service; 41 import org.springframework.stereotype.Service;
40 import org.springframework.transaction.annotation.Transactional; 42 import org.springframework.transaction.annotation.Transactional;
41 import org.springframework.validation.annotation.Validated; 43 import org.springframework.validation.annotation.Validated;
@@ -86,7 +88,9 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -86,7 +88,9 @@ public class CrmContractServiceImpl implements CrmContractService {
86 private CrmContactService contactService; 88 private CrmContactService contactService;
87 @Resource 89 @Resource
88 private CrmContractConfigService contractConfigService; 90 private CrmContractConfigService contractConfigService;
89 - 91 + @Resource
  92 + @Lazy // 延迟加载,避免循环依赖
  93 + private CrmReceivableService receivableService;
90 @Resource 94 @Resource
91 private AdminUserApi adminUserApi; 95 private AdminUserApi adminUserApi;
92 @Resource 96 @Resource
@@ -222,9 +226,12 @@ public class CrmContractServiceImpl implements CrmContractService { @@ -222,9 +226,12 @@ public class CrmContractServiceImpl implements CrmContractService {
222 success = CRM_CONTRACT_DELETE_SUCCESS) 226 success = CRM_CONTRACT_DELETE_SUCCESS)
223 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) 227 @CrmPermission(bizType = CrmBizTypeEnum.CRM_CONTRACT, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
224 public void deleteContract(Long id) { 228 public void deleteContract(Long id) {
225 - // TODO @puhui999:如果被 CrmReceivableDO 所使用,则不允许删除  
226 // 校验存在 229 // 校验存在
227 CrmContractDO contract = validateContractExists(id); 230 CrmContractDO contract = validateContractExists(id);
  231 + // 如果被 CrmReceivableDO 所使用,则不允许删除
  232 + if (CollUtil.isNotEmpty(receivableService.getReceivableByContractId(contract.getId()))) {
  233 + throw exception(CONTRACT_DELETE_FAIL);
  234 + }
228 // 删除 235 // 删除
229 contractMapper.deleteById(id); 236 contractMapper.deleteById(id);
230 // 删除数据权限 237 // 删除数据权限
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableService.java
@@ -122,4 +122,12 @@ public interface CrmReceivableService { @@ -122,4 +122,12 @@ public interface CrmReceivableService {
122 */ 122 */
123 Map<Long, BigDecimal> getReceivablePriceMapByContractId(Collection<Long> contractIds); 123 Map<Long, BigDecimal> getReceivablePriceMapByContractId(Collection<Long> contractIds);
124 124
  125 + /**
  126 + * 更具合同编号查询回款列表
  127 + *
  128 + * @param contractId 合同编号
  129 + * @return 回款
  130 + */
  131 + List<CrmReceivableDO> getReceivableByContractId(Long contractId);
  132 +
125 } 133 }
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java
@@ -37,10 +37,7 @@ import org.springframework.transaction.annotation.Transactional; @@ -37,10 +37,7 @@ import org.springframework.transaction.annotation.Transactional;
37 import org.springframework.validation.annotation.Validated; 37 import org.springframework.validation.annotation.Validated;
38 38
39 import java.math.BigDecimal; 39 import java.math.BigDecimal;
40 -import java.util.Arrays;  
41 -import java.util.Collection;  
42 -import java.util.List;  
43 -import java.util.Map; 40 +import java.util.*;
44 41
45 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 42 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
46 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; 43 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
@@ -81,7 +78,6 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { @@ -81,7 +78,6 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
81 @Resource 78 @Resource
82 private BpmProcessInstanceApi bpmProcessInstanceApi; 79 private BpmProcessInstanceApi bpmProcessInstanceApi;
83 80
84 - // TODO @puhui999:操作日志没记录上  
85 @Override 81 @Override
86 @Transactional(rollbackFor = Exception.class) 82 @Transactional(rollbackFor = Exception.class)
87 @LogRecord(type = CRM_RECEIVABLE_TYPE, subType = CRM_RECEIVABLE_CREATE_SUB_TYPE, bizNo = "{{#receivable.id}}", 83 @LogRecord(type = CRM_RECEIVABLE_TYPE, subType = CRM_RECEIVABLE_CREATE_SUB_TYPE, bizNo = "{{#receivable.id}}",
@@ -115,6 +111,7 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { @@ -115,6 +111,7 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
115 111
116 // 5. 记录操作日志上下文 112 // 5. 记录操作日志上下文
117 LogRecordContext.putVariable("receivable", receivable); 113 LogRecordContext.putVariable("receivable", receivable);
  114 + LogRecordContext.putVariable("period", getReceivablePeriod(receivable.getPlanId()));
118 return receivable.getId(); 115 return receivable.getId();
119 } 116 }
120 117
@@ -156,7 +153,6 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { @@ -156,7 +153,6 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
156 } 153 }
157 } 154 }
158 155
159 - // TODO @puhui999:操作日志没记录上  
160 @Override 156 @Override
161 @Transactional(rollbackFor = Exception.class) 157 @Transactional(rollbackFor = Exception.class)
162 @LogRecord(type = CRM_RECEIVABLE_TYPE, subType = CRM_RECEIVABLE_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}", 158 @LogRecord(type = CRM_RECEIVABLE_TYPE, subType = CRM_RECEIVABLE_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}",
@@ -165,10 +161,13 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { @@ -165,10 +161,13 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
165 public void updateReceivable(CrmReceivableSaveReqVO updateReqVO) { 161 public void updateReceivable(CrmReceivableSaveReqVO updateReqVO) {
166 Assert.notNull(updateReqVO.getId(), "回款编号不能为空"); 162 Assert.notNull(updateReqVO.getId(), "回款编号不能为空");
167 updateReqVO.setOwnerUserId(null).setCustomerId(null).setContractId(null).setPlanId(null); // 不允许修改的字段 163 updateReqVO.setOwnerUserId(null).setCustomerId(null).setContractId(null).setPlanId(null); // 不允许修改的字段
168 - // 1.1 校验可回款金额超过上限  
169 - validateReceivablePriceExceedsLimit(updateReqVO);  
170 - // 1.2 校验存在 164 + // 1.1 校验存在
171 CrmReceivableDO receivable = validateReceivableExists(updateReqVO.getId()); 165 CrmReceivableDO receivable = validateReceivableExists(updateReqVO.getId());
  166 + updateReqVO.setOwnerUserId(receivable.getOwnerUserId()).setCustomerId(receivable.getCustomerId())
  167 + .setContractId(receivable.getContractId()).setPlanId(receivable.getPlanId()); // 设置已存在的值
  168 + // 1.2 校验可回款金额超过上限
  169 + validateReceivablePriceExceedsLimit(updateReqVO);
  170 +
172 // 1.3 只有草稿、审批中,可以编辑; 171 // 1.3 只有草稿、审批中,可以编辑;
173 if (!ObjectUtils.equalsAny(receivable.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus(), 172 if (!ObjectUtils.equalsAny(receivable.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus(),
174 CrmAuditStatusEnum.PROCESS.getStatus())) { 173 CrmAuditStatusEnum.PROCESS.getStatus())) {
@@ -180,8 +179,17 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { @@ -180,8 +179,17 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
180 receivableMapper.updateById(updateObj); 179 receivableMapper.updateById(updateObj);
181 180
182 // 3. 记录操作日志上下文 181 // 3. 记录操作日志上下文
183 - LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(receivable, CrmReceivableSaveReqVO.class));  
184 LogRecordContext.putVariable("receivable", receivable); 182 LogRecordContext.putVariable("receivable", receivable);
  183 + LogRecordContext.putVariable("period", getReceivablePeriod(receivable.getPlanId()));
  184 + LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(receivable, CrmReceivableSaveReqVO.class));
  185 + }
  186 +
  187 + private Integer getReceivablePeriod(Long planId) {
  188 + if (Objects.isNull(planId)) {
  189 + return null;
  190 + }
  191 + CrmReceivablePlanDO receivablePlan = receivablePlanService.getReceivablePlan(planId);
  192 + return receivablePlan.getPeriod();
185 } 193 }
186 194
187 @Override 195 @Override
@@ -212,8 +220,10 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { @@ -212,8 +220,10 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
212 if (receivable.getPlanId() != null && receivablePlanService.getReceivablePlan(receivable.getPlanId()) != null) { 220 if (receivable.getPlanId() != null && receivablePlanService.getReceivablePlan(receivable.getPlanId()) != null) {
213 throw exception(RECEIVABLE_DELETE_FAIL); 221 throw exception(RECEIVABLE_DELETE_FAIL);
214 } 222 }
215 - // TODO @puhui999:审批通过时,不允许删除;  
216 - 223 + // 1.3 审批通过时,不允许删除
  224 + if (ObjUtil.equal(receivable.getAuditStatus(), CrmAuditStatusEnum.APPROVE.getStatus())) {
  225 + throw exception(RECEIVABLE_DELETE_FAIL_IS_APPROVE);
  226 + }
217 // 2. 删除 227 // 2. 删除
218 receivableMapper.deleteById(id); 228 receivableMapper.deleteById(id);
219 // 3. 删除数据权限 229 // 3. 删除数据权限
@@ -221,6 +231,7 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { @@ -221,6 +231,7 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
221 231
222 // 4. 记录操作日志上下文 232 // 4. 记录操作日志上下文
223 LogRecordContext.putVariable("receivable", receivable); 233 LogRecordContext.putVariable("receivable", receivable);
  234 + LogRecordContext.putVariable("period", getReceivablePeriod(receivable.getPlanId()));
224 } 235 }
225 236
226 @Override 237 @Override
@@ -289,4 +300,9 @@ public class CrmReceivableServiceImpl implements CrmReceivableService { @@ -289,4 +300,9 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
289 return receivableMapper.selectReceivablePriceMapByContractId(contractIds); 300 return receivableMapper.selectReceivablePriceMapByContractId(contractIds);
290 } 301 }
291 302
  303 + @Override
  304 + public List<CrmReceivableDO> getReceivableByContractId(Long contractId) {
  305 + return receivableMapper.selectList(CrmReceivableDO::getContractId, contractId);
  306 + }
  307 +
292 } 308 }