mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-23 07:41:53 +08:00
Merge remote-tracking branch 'yudao/develop' into develop
This commit is contained in:
commit
dc695e3cda
@ -14,5 +14,6 @@ public interface DictTypeConstants {
|
|||||||
String CRM_PRODUCT_UNIT = "crm_product_unit"; // CRM 产品单位
|
String CRM_PRODUCT_UNIT = "crm_product_unit"; // CRM 产品单位
|
||||||
String CRM_PRODUCT_STATUS = "crm_product_status"; // CRM 产品状态
|
String CRM_PRODUCT_STATUS = "crm_product_status"; // CRM 产品状态
|
||||||
String CRM_FOLLOW_UP_TYPE = "crm_follow_up_type"; // CRM 跟进方式
|
String CRM_FOLLOW_UP_TYPE = "crm_follow_up_type"; // CRM 跟进方式
|
||||||
|
String CRM_RECEIVABLE_RETURN_TYPE = "crm_receivable_return_type"; // CRM 回款方式
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,6 @@ public interface ErrorCodeConstants {
|
|||||||
|
|
||||||
// ========== 联系人管理 1-020-003-000 ==========
|
// ========== 联系人管理 1-020-003-000 ==========
|
||||||
ErrorCode CONTACT_NOT_EXISTS = new ErrorCode(1_020_003_000, "联系人不存在");
|
ErrorCode CONTACT_NOT_EXISTS = new ErrorCode(1_020_003_000, "联系人不存在");
|
||||||
ErrorCode CONTACT_BUSINESS_LINK_NOT_EXISTS = new ErrorCode(1_020_003_001, "联系人商机关联不存在");
|
|
||||||
ErrorCode CONTACT_DELETE_FAIL_CONTRACT_LINK_EXISTS = new ErrorCode(1_020_003_002, "联系人已关联合同,不能删除");
|
ErrorCode CONTACT_DELETE_FAIL_CONTRACT_LINK_EXISTS = new ErrorCode(1_020_003_002, "联系人已关联合同,不能删除");
|
||||||
ErrorCode CONTACT_UPDATE_OWNER_USER_FAIL = new ErrorCode(1_020_003_003, "更新联系人负责人失败");
|
ErrorCode CONTACT_UPDATE_OWNER_USER_FAIL = new ErrorCode(1_020_003_003, "更新联系人负责人失败");
|
||||||
|
|
||||||
@ -38,10 +37,13 @@ public interface ErrorCodeConstants {
|
|||||||
ErrorCode RECEIVABLE_DELETE_FAIL = new ErrorCode(1_020_004_002, "删除回款失败,原因: 被回款计划所使用,不允许删除");
|
ErrorCode RECEIVABLE_DELETE_FAIL = new ErrorCode(1_020_004_002, "删除回款失败,原因: 被回款计划所使用,不允许删除");
|
||||||
ErrorCode RECEIVABLE_SUBMIT_FAIL_NOT_DRAFT = new ErrorCode(1_020_004_003, "回款提交审核失败,原因:回款没处在未提交状态");
|
ErrorCode RECEIVABLE_SUBMIT_FAIL_NOT_DRAFT = new ErrorCode(1_020_004_003, "回款提交审核失败,原因:回款没处在未提交状态");
|
||||||
ErrorCode RECEIVABLE_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS = new ErrorCode(1_020_004_004, "更新回款审核状态失败,原因:回款不是审核中状态");
|
ErrorCode RECEIVABLE_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS = new ErrorCode(1_020_004_004, "更新回款审核状态失败,原因:回款不是审核中状态");
|
||||||
|
ErrorCode RECEIVABLE_NO_EXISTS = new ErrorCode(1_020_004_005, "生成回款序列号重复,请重试");
|
||||||
|
ErrorCode RECEIVABLE_CREATE_FAIL_CONTRACT_NOT_APPROVE = new ErrorCode(1_020_004_006, "创建回款失败,原因:合同不是审核通过状态");
|
||||||
|
|
||||||
// ========== 回款计划 1-020-005-000 ==========
|
// ========== 回款计划 1-020-005-000 ==========
|
||||||
ErrorCode RECEIVABLE_PLAN_NOT_EXISTS = new ErrorCode(1_020_005_000, "回款计划不存在");
|
ErrorCode RECEIVABLE_PLAN_NOT_EXISTS = new ErrorCode(1_020_005_000, "回款计划不存在");
|
||||||
ErrorCode RECEIVABLE_PLAN_UPDATE_FAIL = new ErrorCode(1_020_006_000, "更想回款计划失败,原因:{}");
|
ErrorCode RECEIVABLE_PLAN_UPDATE_FAIL = new ErrorCode(1_020_006_000, "更想回款计划失败,原因:已经有对应的还款");
|
||||||
|
ErrorCode RECEIVABLE_PLAN_EXISTS_RECEIVABLE = new ErrorCode(1_020_006_001, "回款计划已经有对应的回款,不能使用");
|
||||||
|
|
||||||
// ========== 客户管理 1_020_006_000 ==========
|
// ========== 客户管理 1_020_006_000 ==========
|
||||||
ErrorCode CUSTOMER_NOT_EXISTS = new ErrorCode(1_020_006_000, "客户不存在");
|
ErrorCode CUSTOMER_NOT_EXISTS = new ErrorCode(1_020_006_000, "客户不存在");
|
||||||
@ -64,10 +66,8 @@ public interface ErrorCodeConstants {
|
|||||||
// ========== 权限管理 1_020_007_000 ==========
|
// ========== 权限管理 1_020_007_000 ==========
|
||||||
ErrorCode CRM_PERMISSION_NOT_EXISTS = new ErrorCode(1_020_007_000, "数据权限不存在");
|
ErrorCode CRM_PERMISSION_NOT_EXISTS = new ErrorCode(1_020_007_000, "数据权限不存在");
|
||||||
ErrorCode CRM_PERMISSION_DENIED = new ErrorCode(1_020_007_001, "{}操作失败,原因:没有权限");
|
ErrorCode CRM_PERMISSION_DENIED = new ErrorCode(1_020_007_001, "{}操作失败,原因:没有权限");
|
||||||
ErrorCode CRM_PERMISSION_MODEL_NOT_EXISTS = new ErrorCode(1_020_007_002, "{}不存在");
|
|
||||||
ErrorCode CRM_PERMISSION_MODEL_TRANSFER_FAIL_OWNER_USER_EXISTS = new ErrorCode(1_020_007_003, "{}操作失败,原因:转移对象已经是该负责人");
|
ErrorCode CRM_PERMISSION_MODEL_TRANSFER_FAIL_OWNER_USER_EXISTS = new ErrorCode(1_020_007_003, "{}操作失败,原因:转移对象已经是该负责人");
|
||||||
ErrorCode CRM_PERMISSION_DELETE_FAIL = new ErrorCode(1_020_007_004, "删除数据权限失败,原因:批量删除权限的时候,只能属于同一个 bizId 下");
|
ErrorCode CRM_PERMISSION_DELETE_FAIL = new ErrorCode(1_020_007_004, "删除数据权限失败,原因:批量删除权限的时候,只能属于同一个 bizId 下");
|
||||||
ErrorCode CRM_PERMISSION_DELETE_FAIL_EXIST_OWNER = new ErrorCode(1_020_007_005, "删除数据权限失败,原因:存在负责人");
|
|
||||||
ErrorCode CRM_PERMISSION_DELETE_DENIED = new ErrorCode(1_020_007_006, "删除数据权限失败,原因:没有权限");
|
ErrorCode CRM_PERMISSION_DELETE_DENIED = new ErrorCode(1_020_007_006, "删除数据权限失败,原因:没有权限");
|
||||||
ErrorCode CRM_PERMISSION_DELETE_SELF_PERMISSION_FAIL_EXIST_OWNER = new ErrorCode(1_020_007_007, "删除数据权限失败,原因:不能删除负责人");
|
ErrorCode CRM_PERMISSION_DELETE_SELF_PERMISSION_FAIL_EXIST_OWNER = new ErrorCode(1_020_007_007, "删除数据权限失败,原因:不能删除负责人");
|
||||||
ErrorCode CRM_PERMISSION_CREATE_FAIL = new ErrorCode(1_020_007_008, "创建数据权限失败,原因:所加用户已有权限");
|
ErrorCode CRM_PERMISSION_CREATE_FAIL = new ErrorCode(1_020_007_008, "创建数据权限失败,原因:所加用户已有权限");
|
||||||
@ -93,7 +93,6 @@ public interface ErrorCodeConstants {
|
|||||||
ErrorCode BUSINESS_STATUS_NOT_EXISTS = new ErrorCode(1_020_010_003, "商机状态不存在");
|
ErrorCode BUSINESS_STATUS_NOT_EXISTS = new ErrorCode(1_020_010_003, "商机状态不存在");
|
||||||
|
|
||||||
// ========== 客户公海规则设置 1_020_012_000 ==========
|
// ========== 客户公海规则设置 1_020_012_000 ==========
|
||||||
ErrorCode CUSTOMER_POOL_CONFIG_NOT_EXISTS_OR_DISABLED = new ErrorCode(1_020_012_000, "客户公海配置不存在或未启用");
|
|
||||||
ErrorCode CUSTOMER_LIMIT_CONFIG_NOT_EXISTS = new ErrorCode(1_020_012_001, "客户限制配置不存在");
|
ErrorCode CUSTOMER_LIMIT_CONFIG_NOT_EXISTS = new ErrorCode(1_020_012_001, "客户限制配置不存在");
|
||||||
|
|
||||||
// ========== 跟进记录 1_020_013_000 ==========
|
// ========== 跟进记录 1_020_013_000 ==========
|
||||||
|
@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.crm.controller.admin.contract;
|
|||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||||
@ -24,6 +25,7 @@ import cn.iocoder.yudao.module.crm.service.contact.CrmContactService;
|
|||||||
import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
|
import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
|
||||||
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
|
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
|
||||||
import cn.iocoder.yudao.module.crm.service.product.CrmProductService;
|
import cn.iocoder.yudao.module.crm.service.product.CrmProductService;
|
||||||
|
import cn.iocoder.yudao.module.crm.service.receivable.CrmReceivableService;
|
||||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||||
@ -39,6 +41,7 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -67,6 +70,8 @@ public class CrmContractController {
|
|||||||
private CrmBusinessService businessService;
|
private CrmBusinessService businessService;
|
||||||
@Resource
|
@Resource
|
||||||
private CrmProductService productService;
|
private CrmProductService productService;
|
||||||
|
@Resource
|
||||||
|
private CrmReceivableService receivableService;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private AdminUserApi adminUserApi;
|
private AdminUserApi adminUserApi;
|
||||||
@ -174,12 +179,6 @@ public class CrmContractController {
|
|||||||
return success(true);
|
return success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建详细的合同结果
|
|
||||||
*
|
|
||||||
* @param contractList 原始合同信息
|
|
||||||
* @return 细的合同结果
|
|
||||||
*/
|
|
||||||
private List<CrmContractRespVO> buildContractDetailList(List<CrmContractDO> contractList) {
|
private List<CrmContractRespVO> buildContractDetailList(List<CrmContractDO> contractList) {
|
||||||
if (CollUtil.isEmpty(contractList)) {
|
if (CollUtil.isEmpty(contractList)) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
@ -197,6 +196,9 @@ public class CrmContractController {
|
|||||||
// 1.4 获取商机
|
// 1.4 获取商机
|
||||||
Map<Long, CrmBusinessDO> businessMap = businessService.getBusinessMap(
|
Map<Long, CrmBusinessDO> businessMap = businessService.getBusinessMap(
|
||||||
convertSet(contractList, CrmContractDO::getBusinessId));
|
convertSet(contractList, CrmContractDO::getBusinessId));
|
||||||
|
// 1.5 获得已回款金额
|
||||||
|
Map<Long, BigDecimal> receivablePriceMap = receivableService.getReceivablePriceMapByContractId(
|
||||||
|
convertSet(contractList, CrmContractDO::getId));
|
||||||
// 2. 拼接数据
|
// 2. 拼接数据
|
||||||
return BeanUtils.toBean(contractList, CrmContractRespVO.class, contractVO -> {
|
return BeanUtils.toBean(contractList, CrmContractRespVO.class, contractVO -> {
|
||||||
// 2.1 设置客户信息
|
// 2.1 设置客户信息
|
||||||
@ -212,6 +214,8 @@ public class CrmContractController {
|
|||||||
findAndThen(contactMap, contractVO.getSignContactId(), contact -> contractVO.setSignContactName(contact.getName()));
|
findAndThen(contactMap, contractVO.getSignContactId(), contact -> contractVO.setSignContactName(contact.getName()));
|
||||||
// 2.4 设置商机信息
|
// 2.4 设置商机信息
|
||||||
findAndThen(businessMap, contractVO.getBusinessId(), business -> contractVO.setBusinessName(business.getName()));
|
findAndThen(businessMap, contractVO.getBusinessId(), business -> contractVO.setBusinessName(business.getName()));
|
||||||
|
// 2.5 设置已回款金额
|
||||||
|
contractVO.setTotalReceivablePrice(receivablePriceMap.getOrDefault(contractVO.getId(), BigDecimal.ZERO));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,13 +233,24 @@ public class CrmContractController {
|
|||||||
return success(contractService.getRemindContractCount(getLoginUserId()));
|
return success(contractService.getRemindContractCount(getLoginUserId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/list-all-simple-by-customer")
|
@GetMapping("/simple-list")
|
||||||
@Operation(summary = "获得合同精简列表", description = "只包含有读权限的客户的合同,主要用于前端的下拉选项")
|
@Operation(summary = "获得合同精简列表", description = "只包含的合同,主要用于前端的下拉选项")
|
||||||
@Parameter(name = "customerId", description = "客户编号", required = true)
|
@Parameter(name = "customerId", description = "客户编号", required = true)
|
||||||
@PreAuthorize("@ss.hasPermission('crm:contract:query')")
|
@PreAuthorize("@ss.hasPermission('crm:contract:query')")
|
||||||
public CommonResult<List<CrmContractRespVO>> getListAllSimpleByCustomer(@RequestParam("customerId") Long customerId) {
|
public CommonResult<List<CrmContractRespVO>> getContractSimpleList(@RequestParam("customerId") Long customerId) {
|
||||||
PageResult<CrmContractDO> result = contractService.getContractPageByCustomerId(new CrmContractPageReqVO().setCustomerId(customerId));
|
CrmContractPageReqVO pageReqVO = new CrmContractPageReqVO().setCustomerId(customerId);
|
||||||
return success(BeanUtils.toBean(result.getList(), CrmContractRespVO.class));
|
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); // 不分页
|
||||||
|
PageResult<CrmContractDO> pageResult = contractService.getContractPageByCustomerId(pageReqVO);
|
||||||
|
if (CollUtil.isEmpty(pageResult.getList())) {
|
||||||
|
return success(Collections.emptyList());
|
||||||
|
}
|
||||||
|
// 拼接数据
|
||||||
|
Map<Long, BigDecimal> receivablePriceMap = receivableService.getReceivablePriceMapByContractId(
|
||||||
|
convertSet(pageResult.getList(), CrmContractDO::getId));
|
||||||
|
return success(convertList(pageResult.getList(), contract -> new CrmContractRespVO() // 只返回 id、name 等精简字段
|
||||||
|
.setId(contract.getId()).setName(contract.getName()).setAuditStatus(contract.getAuditStatus())
|
||||||
|
.setTotalPrice(contract.getTotalPrice())
|
||||||
|
.setTotalReceivablePrice(receivablePriceMap.getOrDefault(contract.getId(), BigDecimal.ZERO))));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -88,6 +88,10 @@ public class CrmContractRespVO {
|
|||||||
@ExcelProperty("合同金额")
|
@ExcelProperty("合同金额")
|
||||||
private BigDecimal totalPrice;
|
private BigDecimal totalPrice;
|
||||||
|
|
||||||
|
@Schema(description = "已回款金额", example = "5617")
|
||||||
|
@ExcelProperty("已回款金额")
|
||||||
|
private BigDecimal totalReceivablePrice;
|
||||||
|
|
||||||
@Schema(description = "客户签约人编号", example = "18546")
|
@Schema(description = "客户签约人编号", example = "18546")
|
||||||
private Long signContactId;
|
private Long signContactId;
|
||||||
@Schema(description = "客户签约人", example = "小豆")
|
@Schema(description = "客户签约人", example = "小豆")
|
||||||
|
@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
|||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
import cn.iocoder.yudao.module.crm.controller.admin.operatelog.vo.CrmOperateLogPageReqVO;
|
import cn.iocoder.yudao.module.crm.controller.admin.operatelog.vo.CrmOperateLogPageReqVO;
|
||||||
import cn.iocoder.yudao.module.crm.controller.admin.operatelog.vo.CrmOperateLogV2RespVO;
|
import cn.iocoder.yudao.module.crm.controller.admin.operatelog.vo.CrmOperateLogRespVO;
|
||||||
import cn.iocoder.yudao.module.crm.enums.LogRecordConstants;
|
import cn.iocoder.yudao.module.crm.enums.LogRecordConstants;
|
||||||
import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
|
import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
|
||||||
import cn.iocoder.yudao.module.system.api.logger.OperateLogApi;
|
import cn.iocoder.yudao.module.system.api.logger.OperateLogApi;
|
||||||
@ -54,11 +54,11 @@ public class CrmOperateLogController {
|
|||||||
@GetMapping("/page")
|
@GetMapping("/page")
|
||||||
@Operation(summary = "获得操作日志")
|
@Operation(summary = "获得操作日志")
|
||||||
@PreAuthorize("@ss.hasPermission('crm:operate-log:query')")
|
@PreAuthorize("@ss.hasPermission('crm:operate-log:query')")
|
||||||
public CommonResult<PageResult<CrmOperateLogV2RespVO>> getCustomerOperateLog(@Valid CrmOperateLogPageReqVO pageReqVO) {
|
public CommonResult<PageResult<CrmOperateLogRespVO>> getCustomerOperateLog(@Valid CrmOperateLogPageReqVO pageReqVO) {
|
||||||
OperateLogV2PageReqDTO reqDTO = new OperateLogV2PageReqDTO();
|
OperateLogV2PageReqDTO reqDTO = new OperateLogV2PageReqDTO();
|
||||||
reqDTO.setPageSize(PAGE_SIZE_NONE); // 默认不分页,需要分页需注释
|
reqDTO.setPageSize(PAGE_SIZE_NONE); // 默认不分页,需要分页需注释
|
||||||
reqDTO.setBizType(BIZ_TYPE_MAP.get(pageReqVO.getBizType())).setBizId(pageReqVO.getBizId());
|
reqDTO.setBizType(BIZ_TYPE_MAP.get(pageReqVO.getBizType())).setBizId(pageReqVO.getBizId());
|
||||||
return success(BeanUtils.toBean(operateLogApi.getOperateLogPage(reqDTO), CrmOperateLogV2RespVO.class));
|
return success(BeanUtils.toBean(operateLogApi.getOperateLogPage(reqDTO), CrmOperateLogRespVO.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,10 @@ import lombok.Data;
|
|||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@Schema(description = "管理后台 - CRM 跟进 Response VO")
|
@Schema(description = "管理后台 - CRM 操作日志 Response VO")
|
||||||
@Data
|
@Data
|
||||||
@ExcelIgnoreUnannotated
|
@ExcelIgnoreUnannotated
|
||||||
public class CrmOperateLogV2RespVO {
|
public class CrmOperateLogRespVO {
|
||||||
|
|
||||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
|
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
|
||||||
private Long id;
|
private Long id;
|
@ -4,20 +4,23 @@ import cn.hutool.core.collection.CollUtil;
|
|||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||||
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
||||||
|
import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractRespVO;
|
||||||
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO;
|
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO;
|
||||||
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableRespVO;
|
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableRespVO;
|
||||||
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableSaveReqVO;
|
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableSaveReqVO;
|
||||||
import cn.iocoder.yudao.module.crm.convert.receivable.CrmReceivableConvert;
|
|
||||||
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.customer.CrmCustomerDO;
|
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
|
||||||
import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO;
|
import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO;
|
||||||
import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
|
import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
|
||||||
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
|
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
|
||||||
import cn.iocoder.yudao.module.crm.service.receivable.CrmReceivableService;
|
import cn.iocoder.yudao.module.crm.service.receivable.CrmReceivableService;
|
||||||
|
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||||
|
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@ -31,14 +34,15 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
|
import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
|
||||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
||||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
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.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||||
|
|
||||||
@ -57,6 +61,8 @@ public class CrmReceivableController {
|
|||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private AdminUserApi adminUserApi;
|
private AdminUserApi adminUserApi;
|
||||||
|
@Resource
|
||||||
|
private DeptApi deptApi;
|
||||||
|
|
||||||
@PostMapping("/create")
|
@PostMapping("/create")
|
||||||
@Operation(summary = "创建回款")
|
@Operation(summary = "创建回款")
|
||||||
@ -88,7 +94,14 @@ public class CrmReceivableController {
|
|||||||
@PreAuthorize("@ss.hasPermission('crm:receivable:query')")
|
@PreAuthorize("@ss.hasPermission('crm:receivable:query')")
|
||||||
public CommonResult<CrmReceivableRespVO> getReceivable(@RequestParam("id") Long id) {
|
public CommonResult<CrmReceivableRespVO> getReceivable(@RequestParam("id") Long id) {
|
||||||
CrmReceivableDO receivable = receivableService.getReceivable(id);
|
CrmReceivableDO receivable = receivableService.getReceivable(id);
|
||||||
return success(BeanUtils.toBean(receivable, CrmReceivableRespVO.class));
|
return success(buildReceivableDetail(receivable));
|
||||||
|
}
|
||||||
|
|
||||||
|
private CrmReceivableRespVO buildReceivableDetail(CrmReceivableDO receivable) {
|
||||||
|
if (receivable == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return buildReceivableDetailList(Collections.singletonList(receivable)).get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/page")
|
@GetMapping("/page")
|
||||||
@ -96,7 +109,7 @@ public class CrmReceivableController {
|
|||||||
@PreAuthorize("@ss.hasPermission('crm:receivable:query')")
|
@PreAuthorize("@ss.hasPermission('crm:receivable:query')")
|
||||||
public CommonResult<PageResult<CrmReceivableRespVO>> getReceivablePage(@Valid CrmReceivablePageReqVO pageReqVO) {
|
public CommonResult<PageResult<CrmReceivableRespVO>> getReceivablePage(@Valid CrmReceivablePageReqVO pageReqVO) {
|
||||||
PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePage(pageReqVO, getLoginUserId());
|
PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePage(pageReqVO, getLoginUserId());
|
||||||
return success(buildReceivableDetailPage(pageResult));
|
return success(new PageResult<>(buildReceivableDetailList(pageResult.getList()), pageResult.getTotal()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/page-by-customer")
|
@GetMapping("/page-by-customer")
|
||||||
@ -104,7 +117,7 @@ public class CrmReceivableController {
|
|||||||
public CommonResult<PageResult<CrmReceivableRespVO>> getReceivablePageByCustomer(@Valid CrmReceivablePageReqVO pageReqVO) {
|
public CommonResult<PageResult<CrmReceivableRespVO>> getReceivablePageByCustomer(@Valid CrmReceivablePageReqVO pageReqVO) {
|
||||||
Assert.notNull(pageReqVO.getCustomerId(), "客户编号不能为空");
|
Assert.notNull(pageReqVO.getCustomerId(), "客户编号不能为空");
|
||||||
PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePageByCustomerId(pageReqVO);
|
PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePageByCustomerId(pageReqVO);
|
||||||
return success(buildReceivableDetailPage(pageResult));
|
return success(new PageResult<>(buildReceivableDetailList(pageResult.getList()), pageResult.getTotal()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/export-excel")
|
@GetMapping("/export-excel")
|
||||||
@ -114,36 +127,43 @@ public class CrmReceivableController {
|
|||||||
public void exportReceivableExcel(@Valid CrmReceivablePageReqVO exportReqVO,
|
public void exportReceivableExcel(@Valid CrmReceivablePageReqVO exportReqVO,
|
||||||
HttpServletResponse response) throws IOException {
|
HttpServletResponse response) throws IOException {
|
||||||
exportReqVO.setPageSize(PAGE_SIZE_NONE);
|
exportReqVO.setPageSize(PAGE_SIZE_NONE);
|
||||||
PageResult<CrmReceivableDO> pageResult = receivableService.getReceivablePage(exportReqVO, getLoginUserId());
|
List<CrmReceivableDO> list = receivableService.getReceivablePage(exportReqVO, getLoginUserId()).getList();
|
||||||
// 导出 Excel
|
// 导出 Excel
|
||||||
ExcelUtils.write(response, "回款.xls", "数据", CrmReceivableRespVO.class,
|
ExcelUtils.write(response, "回款.xls", "数据", CrmReceivableRespVO.class,
|
||||||
buildReceivableDetailPage(pageResult).getList());
|
buildReceivableDetailList(list));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private List<CrmReceivableRespVO> buildReceivableDetailList(List<CrmReceivableDO> receivableList) {
|
||||||
* 构建详细的回款分页结果
|
|
||||||
*
|
|
||||||
* @param pageResult 简单的回款分页结果
|
|
||||||
* @return 详细的回款分页结果
|
|
||||||
*/
|
|
||||||
private PageResult<CrmReceivableRespVO> buildReceivableDetailPage(PageResult<CrmReceivableDO> pageResult) {
|
|
||||||
List<CrmReceivableDO> receivableList = pageResult.getList();
|
|
||||||
if (CollUtil.isEmpty(receivableList)) {
|
if (CollUtil.isEmpty(receivableList)) {
|
||||||
return PageResult.empty(pageResult.getTotal());
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
// 1. 获取客户列表
|
// 1.1 获取客户列表
|
||||||
List<CrmCustomerDO> customerList = customerService.getCustomerList(
|
Map<Long, CrmCustomerDO> customerMap = customerService.getCustomerMap(
|
||||||
convertSet(receivableList, CrmReceivableDO::getCustomerId));
|
convertSet(receivableList, CrmReceivableDO::getCustomerId));
|
||||||
// 2. 获取创建人、负责人列表
|
// 1.2 获取创建人、负责人列表
|
||||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(receivableList,
|
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(receivableList,
|
||||||
contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
|
contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
|
||||||
// 3. 获得合同列表
|
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
|
||||||
List<CrmContractDO> contractList = contractService.getContractList(
|
// 1.3 获得合同列表
|
||||||
|
Map<Long, CrmContractDO> contractMap = contractService.getContractMap(
|
||||||
convertSet(receivableList, CrmReceivableDO::getContractId));
|
convertSet(receivableList, CrmReceivableDO::getContractId));
|
||||||
return CrmReceivableConvert.INSTANCE.convertPage(pageResult, userMap, customerList, contractList);
|
// 2. 拼接结果
|
||||||
|
return BeanUtils.toBean(receivableList, CrmReceivableRespVO.class, (receivableVO) -> {
|
||||||
|
// 2.1 拼接客户名称
|
||||||
|
findAndThen(customerMap, receivableVO.getCustomerId(), customer -> receivableVO.setCustomerName(customer.getName()));
|
||||||
|
// 2.2 拼接负责人、创建人名称
|
||||||
|
MapUtils.findAndThen(userMap, NumberUtils.parseLong(receivableVO.getCreator()),
|
||||||
|
user -> receivableVO.setCreatorName(user.getNickname()));
|
||||||
|
MapUtils.findAndThen(userMap, receivableVO.getOwnerUserId(), user -> {
|
||||||
|
receivableVO.setOwnerUserName(user.getNickname());
|
||||||
|
MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> receivableVO.setOwnerUserDeptName(dept.getName()));
|
||||||
|
});
|
||||||
|
// 2.3 拼接合同信息
|
||||||
|
findAndThen(contractMap, receivableVO.getContractId(), contract ->
|
||||||
|
receivableVO.setContract(BeanUtils.toBean(contract, CrmContractRespVO.class)));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("/check-receivables-count")
|
@GetMapping("/check-receivables-count")
|
||||||
@Operation(summary = "获得待审核回款数量")
|
@Operation(summary = "获得待审核回款数量")
|
||||||
@PreAuthorize("@ss.hasPermission('crm:receivable:query')")
|
@PreAuthorize("@ss.hasPermission('crm:receivable:query')")
|
||||||
|
@ -11,7 +11,7 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
|||||||
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanPageReqVO;
|
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanPageReqVO;
|
||||||
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanRespVO;
|
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanRespVO;
|
||||||
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanSaveReqVO;
|
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanSaveReqVO;
|
||||||
import cn.iocoder.yudao.module.crm.convert.receivable.CrmReceivablePlanConvert;
|
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableRespVO;
|
||||||
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.customer.CrmCustomerDO;
|
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
|
||||||
import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO;
|
import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO;
|
||||||
@ -34,14 +34,15 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
|
import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
|
||||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
||||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
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.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||||
|
|
||||||
@ -93,7 +94,14 @@ public class CrmReceivablePlanController {
|
|||||||
@PreAuthorize("@ss.hasPermission('crm:receivable-plan:query')")
|
@PreAuthorize("@ss.hasPermission('crm:receivable-plan:query')")
|
||||||
public CommonResult<CrmReceivablePlanRespVO> getReceivablePlan(@RequestParam("id") Long id) {
|
public CommonResult<CrmReceivablePlanRespVO> getReceivablePlan(@RequestParam("id") Long id) {
|
||||||
CrmReceivablePlanDO receivablePlan = receivablePlanService.getReceivablePlan(id);
|
CrmReceivablePlanDO receivablePlan = receivablePlanService.getReceivablePlan(id);
|
||||||
return success(BeanUtils.toBean(receivablePlan, CrmReceivablePlanRespVO.class));
|
return success(buildReceivablePlanDetail(receivablePlan));
|
||||||
|
}
|
||||||
|
|
||||||
|
private CrmReceivablePlanRespVO buildReceivablePlanDetail(CrmReceivablePlanDO receivablePlan) {
|
||||||
|
if (receivablePlan == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return buildReceivableDetailList(Collections.singletonList(receivablePlan)).get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/page")
|
@GetMapping("/page")
|
||||||
@ -101,7 +109,7 @@ public class CrmReceivablePlanController {
|
|||||||
@PreAuthorize("@ss.hasPermission('crm:receivable-plan:query')")
|
@PreAuthorize("@ss.hasPermission('crm:receivable-plan:query')")
|
||||||
public CommonResult<PageResult<CrmReceivablePlanRespVO>> getReceivablePlanPage(@Valid CrmReceivablePlanPageReqVO pageReqVO) {
|
public CommonResult<PageResult<CrmReceivablePlanRespVO>> getReceivablePlanPage(@Valid CrmReceivablePlanPageReqVO pageReqVO) {
|
||||||
PageResult<CrmReceivablePlanDO> pageResult = receivablePlanService.getReceivablePlanPage(pageReqVO, getLoginUserId());
|
PageResult<CrmReceivablePlanDO> pageResult = receivablePlanService.getReceivablePlanPage(pageReqVO, getLoginUserId());
|
||||||
return success(convertDetailReceivablePlanPage(pageResult));
|
return success(new PageResult<>(buildReceivableDetailList(pageResult.getList()), pageResult.getTotal()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/page-by-customer")
|
@GetMapping("/page-by-customer")
|
||||||
@ -109,10 +117,9 @@ public class CrmReceivablePlanController {
|
|||||||
public CommonResult<PageResult<CrmReceivablePlanRespVO>> getReceivablePlanPageByCustomer(@Valid CrmReceivablePlanPageReqVO pageReqVO) {
|
public CommonResult<PageResult<CrmReceivablePlanRespVO>> getReceivablePlanPageByCustomer(@Valid CrmReceivablePlanPageReqVO pageReqVO) {
|
||||||
Assert.notNull(pageReqVO.getCustomerId(), "客户编号不能为空");
|
Assert.notNull(pageReqVO.getCustomerId(), "客户编号不能为空");
|
||||||
PageResult<CrmReceivablePlanDO> pageResult = receivablePlanService.getReceivablePlanPageByCustomerId(pageReqVO);
|
PageResult<CrmReceivablePlanDO> pageResult = receivablePlanService.getReceivablePlanPageByCustomerId(pageReqVO);
|
||||||
return success(convertDetailReceivablePlanPage(pageResult));
|
return success(new PageResult<>(buildReceivableDetailList(pageResult.getList()), pageResult.getTotal()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO 芋艿:后面在优化导出
|
|
||||||
@GetMapping("/export-excel")
|
@GetMapping("/export-excel")
|
||||||
@Operation(summary = "导出回款计划 Excel")
|
@Operation(summary = "导出回款计划 Excel")
|
||||||
@PreAuthorize("@ss.hasPermission('crm:receivable-plan:export')")
|
@PreAuthorize("@ss.hasPermission('crm:receivable-plan:export')")
|
||||||
@ -120,39 +127,42 @@ public class CrmReceivablePlanController {
|
|||||||
public void exportReceivablePlanExcel(@Valid CrmReceivablePlanPageReqVO exportReqVO,
|
public void exportReceivablePlanExcel(@Valid CrmReceivablePlanPageReqVO exportReqVO,
|
||||||
HttpServletResponse response) throws IOException {
|
HttpServletResponse response) throws IOException {
|
||||||
exportReqVO.setPageSize(PAGE_SIZE_NONE);
|
exportReqVO.setPageSize(PAGE_SIZE_NONE);
|
||||||
PageResult<CrmReceivablePlanDO> pageResult = receivablePlanService.getReceivablePlanPage(exportReqVO, getLoginUserId());
|
List<CrmReceivablePlanDO> list = receivablePlanService.getReceivablePlanPage(exportReqVO, getLoginUserId()).getList();
|
||||||
// 导出 Excel
|
// 导出 Excel
|
||||||
ExcelUtils.write(response, "回款计划.xls", "数据", CrmReceivablePlanRespVO.class,
|
ExcelUtils.write(response, "回款计划.xls", "数据", CrmReceivablePlanRespVO.class,
|
||||||
convertDetailReceivablePlanPage(pageResult).getList());
|
buildReceivableDetailList(list));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private List<CrmReceivablePlanRespVO> buildReceivableDetailList(List<CrmReceivablePlanDO> receivablePlanList) {
|
||||||
* 构建详细的回款计划分页结果
|
|
||||||
*
|
|
||||||
* @param pageResult 简单的回款计划分页结果
|
|
||||||
* @return 详细的回款计划分页结果
|
|
||||||
*/
|
|
||||||
private PageResult<CrmReceivablePlanRespVO> convertDetailReceivablePlanPage(PageResult<CrmReceivablePlanDO> pageResult) {
|
|
||||||
List<CrmReceivablePlanDO> receivablePlanList = pageResult.getList();
|
|
||||||
if (CollUtil.isEmpty(receivablePlanList)) {
|
if (CollUtil.isEmpty(receivablePlanList)) {
|
||||||
return PageResult.empty(pageResult.getTotal());
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
// 1. 获取客户列表
|
// 1.1 获取客户 Map
|
||||||
List<CrmCustomerDO> customerList = customerService.getCustomerList(
|
Map<Long, CrmCustomerDO> customerMap = customerService.getCustomerMap(
|
||||||
convertSet(receivablePlanList, CrmReceivablePlanDO::getCustomerId));
|
convertSet(receivablePlanList, CrmReceivablePlanDO::getCustomerId));
|
||||||
// 2. 获取创建人、负责人列表
|
// 1.2 获取创建人、负责人列表
|
||||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(receivablePlanList,
|
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(receivablePlanList,
|
||||||
contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
|
contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
|
||||||
// 3. 获得合同列表
|
// 1.3 获得合同 Map
|
||||||
List<CrmContractDO> contractList = contractService.getContractList(
|
Map<Long, CrmContractDO> contractMap = contractService.getContractMap(
|
||||||
convertSet(receivablePlanList, CrmReceivablePlanDO::getContractId));
|
convertSet(receivablePlanList, CrmReceivablePlanDO::getContractId));
|
||||||
// 4. 获得还款列表
|
// 1.4 获得回款 Map
|
||||||
List<CrmReceivableDO> receivableList = receivableService.getReceivableList(
|
Map<Long, CrmReceivableDO> receivableMap = receivableService.getReceivableMap(
|
||||||
convertSet(receivablePlanList, CrmReceivablePlanDO::getReceivableId));
|
convertSet(receivablePlanList, CrmReceivablePlanDO::getReceivableId));
|
||||||
return CrmReceivablePlanConvert.INSTANCE.convertPage(pageResult, userMap, customerList, contractList, receivableList);
|
// 2. 拼接数据
|
||||||
|
return BeanUtils.toBean(receivablePlanList, CrmReceivablePlanRespVO.class, (receivablePlanVO) -> {
|
||||||
|
// 2.1 拼接客户信息
|
||||||
|
findAndThen(customerMap, receivablePlanVO.getCustomerId(), customer -> receivablePlanVO.setCustomerName(customer.getName()));
|
||||||
|
// 2.2 拼接用户信息
|
||||||
|
findAndThen(userMap, receivablePlanVO.getOwnerUserId(), user -> receivablePlanVO.setOwnerUserName(user.getNickname()));
|
||||||
|
findAndThen(userMap, Long.parseLong(receivablePlanVO.getCreator()), user -> receivablePlanVO.setCreatorName(user.getNickname()));
|
||||||
|
// 2.3 拼接合同信息
|
||||||
|
findAndThen(contractMap, receivablePlanVO.getContractId(), contract -> receivablePlanVO.setContractNo(contract.getNo()));
|
||||||
|
// 2.4 拼接回款信息
|
||||||
|
receivablePlanVO.setReceivable(BeanUtils.toBean(receivableMap.get(receivablePlanVO.getReceivableId()), CrmReceivableRespVO.class));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("/remind-receivable-plan-count")
|
@GetMapping("/remind-receivable-plan-count")
|
||||||
@Operation(summary = "获得待回款提醒数量")
|
@Operation(summary = "获得待回款提醒数量")
|
||||||
@PreAuthorize("@ss.hasPermission('crm:receivable-plan:query')")
|
@PreAuthorize("@ss.hasPermission('crm:receivable-plan:query')")
|
||||||
@ -160,18 +170,21 @@ public class CrmReceivablePlanController {
|
|||||||
return success(receivablePlanService.getRemindReceivablePlanCount(getLoginUserId()));
|
return success(receivablePlanService.getRemindReceivablePlanCount(getLoginUserId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/list-all-simple-by-customer")
|
@GetMapping("/simple-list")
|
||||||
@Operation(summary = "获得回款计划精简列表", description = "获得回款计划精简列表,主要用于前端的下拉选项")
|
@Operation(summary = "获得回款计划精简列表", description = "获得回款计划精简列表,主要用于前端的下拉选项")
|
||||||
@Parameters({
|
@Parameters({
|
||||||
@Parameter(name = "customerId", description = "客户编号", required = true),
|
@Parameter(name = "customerId", description = "客户编号", required = true),
|
||||||
@Parameter(name = "contractId", description = "合同编号", required = true)
|
@Parameter(name = "contractId", description = "合同编号", required = true)
|
||||||
})
|
})
|
||||||
@PreAuthorize("@ss.hasPermission('crm:receivable-plan:query')")
|
@PreAuthorize("@ss.hasPermission('crm:receivable-plan:query')")
|
||||||
public CommonResult<List<CrmReceivablePlanRespVO>> getListAllSimpleByCustomer(@RequestParam("customerId") Long customerId,
|
public CommonResult<List<CrmReceivablePlanRespVO>> getReceivablePlanSimpleList(@RequestParam("customerId") Long customerId,
|
||||||
@RequestParam("contractId") Long contractId) {
|
@RequestParam("contractId") Long contractId) {
|
||||||
PageResult<CrmReceivablePlanDO> result = receivablePlanService.getReceivablePlanPageByCustomerId(
|
CrmReceivablePlanPageReqVO pageReqVO = new CrmReceivablePlanPageReqVO().setCustomerId(customerId).setContractId(contractId);
|
||||||
new CrmReceivablePlanPageReqVO().setCustomerId(customerId).setContractId(contractId));
|
pageReqVO.setPageNo(PAGE_SIZE_NONE);
|
||||||
return success(BeanUtils.toBean(result.getList(), CrmReceivablePlanRespVO.class));
|
PageResult<CrmReceivablePlanDO> pageResult = receivablePlanService.getReceivablePlanPageByCustomerId(pageReqVO);
|
||||||
|
return success(convertList(pageResult.getList(), receivablePlan -> new CrmReceivablePlanRespVO() // 只返回 id、period 等信息
|
||||||
|
.setId(receivablePlan.getId()).setPeriod(receivablePlan.getPeriod()).setReceivableId(receivablePlan.getReceivableId())
|
||||||
|
.setPrice(receivablePlan.getPrice()).setReturnType(receivablePlan.getReturnType())));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan;
|
package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableRespVO;
|
||||||
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@ -35,17 +37,16 @@ public class CrmReceivablePlanRespVO {
|
|||||||
@Schema(description = "计划回款日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02")
|
@Schema(description = "计划回款日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02")
|
||||||
private LocalDateTime returnTime;
|
private LocalDateTime returnTime;
|
||||||
|
|
||||||
@Schema(description = "回款方式", example = "1")
|
@Schema(description = "计划回款方式", example = "1")
|
||||||
private Integer returnType; // 来自 Receivable 的 returnType 字段
|
private Integer returnType;
|
||||||
|
|
||||||
@Schema(description = "计划回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "9000")
|
@Schema(description = "计划回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "9000")
|
||||||
private BigDecimal price;
|
private BigDecimal price;
|
||||||
|
|
||||||
@Schema(description = "回款编号", example = "19852")
|
@Schema(description = "回款编号", example = "19852")
|
||||||
private Long receivableId;
|
private Long receivableId;
|
||||||
|
@Schema(description = "回款信息")
|
||||||
@Schema(description = "完成状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
private CrmReceivableRespVO receivable;
|
||||||
private Boolean finishStatus;
|
|
||||||
|
|
||||||
@Schema(description = "提前几天提醒", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
@Schema(description = "提前几天提醒", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
private Integer remindDays;
|
private Integer remindDays;
|
||||||
@ -57,12 +58,18 @@ public class CrmReceivablePlanRespVO {
|
|||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@ExcelProperty("创建时间")
|
||||||
private LocalDateTime createTime;
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
@Schema(description = "创建人", example = "25682")
|
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private String creator;
|
@ExcelProperty("更新时间")
|
||||||
|
private LocalDateTime updateTime;
|
||||||
|
|
||||||
@Schema(description = "创建人名字", example = "test")
|
@Schema(description = "创建人", example = "1024")
|
||||||
|
@ExcelProperty("创建人")
|
||||||
|
private String creator;
|
||||||
|
@Schema(description = "创建人名字", example = "芋道源码")
|
||||||
|
@ExcelProperty("创建人名字")
|
||||||
private String creatorName;
|
private String creatorName;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,9 +14,8 @@ public class CrmReceivablePlanSaveReqVO {
|
|||||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
@Schema(description = "客户编号", hidden = true, example = "2")
|
||||||
@NotNull(message = "客户编号不能为空")
|
private Long customerId; // 该字段不通过前端传递,而是 contractId 查询出来设置进去
|
||||||
private Long customerId;
|
|
||||||
|
|
||||||
@Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
@Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||||
@NotNull(message = "合同编号不能为空")
|
@NotNull(message = "合同编号不能为空")
|
||||||
@ -37,10 +36,6 @@ public class CrmReceivablePlanSaveReqVO {
|
|||||||
@NotNull(message = "计划回款金额不能为空")
|
@NotNull(message = "计划回款金额不能为空")
|
||||||
private BigDecimal price;
|
private BigDecimal price;
|
||||||
|
|
||||||
@Schema(description = "提醒日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
|
||||||
@NotNull(message = "提醒日期不能为空")
|
|
||||||
private LocalDateTime remindTime;
|
|
||||||
|
|
||||||
@Schema(description = "提前几天提醒", example = "1")
|
@Schema(description = "提前几天提醒", example = "1")
|
||||||
private Integer remindDays;
|
private Integer remindDays;
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable;
|
package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractRespVO;
|
||||||
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@ -31,12 +33,30 @@ public class CrmReceivableRespVO {
|
|||||||
|
|
||||||
@Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
@Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||||
private Long customerId;
|
private Long customerId;
|
||||||
|
@Schema(description = "客户名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "test")
|
||||||
|
private String customerName;
|
||||||
|
|
||||||
@Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
@Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||||
private Long contractId;
|
private Long contractId;
|
||||||
|
@Schema(description = "合同信息")
|
||||||
|
private CrmContractRespVO contract;
|
||||||
|
|
||||||
@Schema(description = "负责人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
@Schema(description = "负责人的用户编号", example = "25682")
|
||||||
|
@ExcelProperty("负责人的用户编号")
|
||||||
private Long ownerUserId;
|
private Long ownerUserId;
|
||||||
|
@Schema(description = "负责人名字", example = "25682")
|
||||||
|
@ExcelProperty("负责人名字")
|
||||||
|
private String ownerUserName;
|
||||||
|
@Schema(description = "负责人部门")
|
||||||
|
@ExcelProperty("负责人部门")
|
||||||
|
private String ownerUserDeptName;
|
||||||
|
|
||||||
|
@Schema(description = "工作流编号", example = "1043")
|
||||||
|
@ExcelProperty("工作流编号")
|
||||||
|
private String processInstanceId;
|
||||||
|
|
||||||
|
@Schema(description = "审批状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
||||||
|
private Integer auditStatus;
|
||||||
|
|
||||||
@Schema(description = "备注", example = "备注")
|
@Schema(description = "备注", example = "备注")
|
||||||
private String remark;
|
private String remark;
|
||||||
@ -44,21 +64,11 @@ public class CrmReceivableRespVO {
|
|||||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private LocalDateTime createTime;
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
@Schema(description = "客户名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "test")
|
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private String customerName;
|
private LocalDateTime updateTime;
|
||||||
|
|
||||||
@Schema(description = "审批状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
|
|
||||||
private Integer auditStatus;
|
|
||||||
|
|
||||||
@Schema(description = "合同编号", example = "Q110")
|
|
||||||
private String contractNo;
|
|
||||||
|
|
||||||
@Schema(description = "负责人", example = "test")
|
|
||||||
private String ownerUserName;
|
|
||||||
|
|
||||||
@Schema(description = "创建人", example = "25682")
|
@Schema(description = "创建人", example = "25682")
|
||||||
private String creator;
|
private String creator;
|
||||||
|
|
||||||
@Schema(description = "创建人名字", example = "test")
|
@Schema(description = "创建人名字", example = "test")
|
||||||
private String creatorName;
|
private String creatorName;
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable;
|
|||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||||
import cn.iocoder.yudao.module.crm.enums.receivable.CrmReceivableReturnTypeEnum;
|
import cn.iocoder.yudao.module.crm.enums.receivable.CrmReceivableReturnTypeEnum;
|
||||||
|
import cn.iocoder.yudao.module.crm.framework.operatelog.core.*;
|
||||||
|
import com.mzt.logapi.starter.annotation.DiffLogField;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@ -16,37 +18,41 @@ public class CrmReceivableSaveReqVO {
|
|||||||
@Schema(description = "编号", example = "25787")
|
@Schema(description = "编号", example = "25787")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@Schema(description = "回款编号", example = "31177")
|
@Schema(description = "负责人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||||
private String no;
|
@DiffLogField(name = "负责人", function = SysAdminUserParseFunction.NAME)
|
||||||
|
@NotNull(message = "负责人编号不能为空")
|
||||||
|
private Long ownerUserId;
|
||||||
|
|
||||||
@Schema(description = "回款计划编号", example = "1024")
|
@Schema(description = "客户编号", example = "2")
|
||||||
private Long planId; // 不是通过回款计划创建的回款没有回款计划编号
|
@DiffLogField(name = "客户", function = CrmCustomerParseFunction.NAME)
|
||||||
|
private Long customerId; // 该字段不通过前端传递,而是 contractId 查询出来设置进去
|
||||||
|
|
||||||
|
@Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||||
|
@DiffLogField(name = "合同", function = CrmContractParseFunction.NAME)
|
||||||
|
@NotNull(message = "合同编号不能为空")
|
||||||
|
private Long contractId;
|
||||||
|
|
||||||
|
@Schema(description = "回款计划编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
|
@DiffLogField(name = "合同", function = CrmReceivablePlanParseFunction.NAME)
|
||||||
|
private Long planId;
|
||||||
|
|
||||||
@Schema(description = "回款方式", example = "2")
|
@Schema(description = "回款方式", example = "2")
|
||||||
|
@DiffLogField(name = "回款方式", function = CrmReceivableReturnTypeParseFunction.NAME)
|
||||||
@InEnum(CrmReceivableReturnTypeEnum.class)
|
@InEnum(CrmReceivableReturnTypeEnum.class)
|
||||||
private Integer returnType;
|
private Integer returnType;
|
||||||
|
|
||||||
@Schema(description = "回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "9000")
|
@Schema(description = "回款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "9000")
|
||||||
|
@DiffLogField(name = "回款金额")
|
||||||
@NotNull(message = "回款金额不能为空")
|
@NotNull(message = "回款金额不能为空")
|
||||||
private BigDecimal price;
|
private BigDecimal price;
|
||||||
|
|
||||||
@Schema(description = "计划回款日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02")
|
@Schema(description = "回款日期", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-02-02")
|
||||||
@NotNull(message = "计划回款日期不能为空")
|
@NotNull(message = "回款日期不能为空")
|
||||||
|
@DiffLogField(name = "回款日期")
|
||||||
private LocalDateTime returnTime;
|
private LocalDateTime returnTime;
|
||||||
|
|
||||||
@Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
|
||||||
@NotNull(message = "客户编号不能为空")
|
|
||||||
private Long customerId;
|
|
||||||
|
|
||||||
@Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
|
||||||
@NotNull(message = "合同编号不能为空")
|
|
||||||
private Long contractId;
|
|
||||||
|
|
||||||
@Schema(description = "负责人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
|
||||||
@NotNull(message = "负责人编号不能为空")
|
|
||||||
private Long ownerUserId;
|
|
||||||
|
|
||||||
@Schema(description = "备注", example = "备注")
|
@Schema(description = "备注", example = "备注")
|
||||||
|
@DiffLogField(name = "备注")
|
||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
package cn.iocoder.yudao.module.crm.convert.receivable;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
|
||||||
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableRespVO;
|
|
||||||
import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
|
|
||||||
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
|
|
||||||
import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO;
|
|
||||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
|
||||||
import org.mapstruct.Mapper;
|
|
||||||
import org.mapstruct.factory.Mappers;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 回款 Convert
|
|
||||||
*
|
|
||||||
* @author 赤焰
|
|
||||||
*/
|
|
||||||
@Mapper
|
|
||||||
public interface CrmReceivableConvert {
|
|
||||||
|
|
||||||
CrmReceivableConvert INSTANCE = Mappers.getMapper(CrmReceivableConvert.class);
|
|
||||||
|
|
||||||
default PageResult<CrmReceivableRespVO> convertPage(PageResult<CrmReceivableDO> pageResult, Map<Long, AdminUserRespDTO> userMap,
|
|
||||||
List<CrmCustomerDO> customerList, List<CrmContractDO> contractList) {
|
|
||||||
PageResult<CrmReceivableRespVO> voPageResult = BeanUtils.toBean(pageResult, CrmReceivableRespVO.class);
|
|
||||||
// 拼接关联字段
|
|
||||||
Map<Long, CrmCustomerDO> customerMap = convertMap(customerList, CrmCustomerDO::getId);
|
|
||||||
Map<Long, CrmContractDO> contractMap = convertMap(contractList, CrmContractDO::getId);
|
|
||||||
voPageResult.getList().forEach(receivable -> {
|
|
||||||
findAndThen(userMap, receivable.getOwnerUserId(), user -> receivable.setOwnerUserName(user.getNickname()));
|
|
||||||
findAndThen(userMap, Long.parseLong(receivable.getCreator()), user -> receivable.setCreatorName(user.getNickname()));
|
|
||||||
findAndThen(customerMap, receivable.getCustomerId(), customer -> receivable.setCustomerName(customer.getName()));
|
|
||||||
findAndThen(contractMap, receivable.getContractId(), contract -> receivable.setContractNo(contract.getNo()));
|
|
||||||
});
|
|
||||||
return voPageResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
package cn.iocoder.yudao.module.crm.convert.receivable;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
|
||||||
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanRespVO;
|
|
||||||
import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
|
|
||||||
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
|
|
||||||
import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO;
|
|
||||||
import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO;
|
|
||||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
|
||||||
import org.mapstruct.Mapper;
|
|
||||||
import org.mapstruct.factory.Mappers;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 回款计划 Convert
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@Mapper
|
|
||||||
public interface CrmReceivablePlanConvert {
|
|
||||||
|
|
||||||
CrmReceivablePlanConvert INSTANCE = Mappers.getMapper(CrmReceivablePlanConvert.class);
|
|
||||||
|
|
||||||
default PageResult<CrmReceivablePlanRespVO> convertPage(PageResult<CrmReceivablePlanDO> pageResult, Map<Long, AdminUserRespDTO> userMap,
|
|
||||||
List<CrmCustomerDO> customerList, List<CrmContractDO> contractList,
|
|
||||||
List<CrmReceivableDO> receivableList) {
|
|
||||||
PageResult<CrmReceivablePlanRespVO> voPageResult = BeanUtils.toBean(pageResult, CrmReceivablePlanRespVO.class);
|
|
||||||
// 拼接关联字段
|
|
||||||
Map<Long, CrmCustomerDO> customerMap = convertMap(customerList, CrmCustomerDO::getId);
|
|
||||||
Map<Long, CrmContractDO> contractMap = convertMap(contractList, CrmContractDO::getId);
|
|
||||||
Map<Long, CrmReceivableDO> receivableMap = convertMap(receivableList, CrmReceivableDO::getId);
|
|
||||||
voPageResult.getList().forEach(receivablePlan -> {
|
|
||||||
findAndThen(userMap, receivablePlan.getOwnerUserId(), user -> receivablePlan.setOwnerUserName(user.getNickname()));
|
|
||||||
findAndThen(userMap, Long.parseLong(receivablePlan.getCreator()), user -> receivablePlan.setCreatorName(user.getNickname()));
|
|
||||||
findAndThen(customerMap, receivablePlan.getCustomerId(), customer -> receivablePlan.setCustomerName(customer.getName()));
|
|
||||||
findAndThen(contractMap, receivablePlan.getContractId(), contract -> receivablePlan.setContractNo(contract.getNo()));
|
|
||||||
findAndThen(receivableMap, receivablePlan.getReceivableId(), receivable -> receivablePlan.setReturnType(receivable.getReturnType()));
|
|
||||||
});
|
|
||||||
return voPageResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -39,15 +39,21 @@ public class CrmReceivableDO extends BaseDO {
|
|||||||
*/
|
*/
|
||||||
private String no;
|
private String no;
|
||||||
/**
|
/**
|
||||||
* 回款计划编号,关联 {@link CrmReceivablePlanDO#getId()}
|
* 回款计划编号
|
||||||
|
*
|
||||||
|
* 关联 {@link CrmReceivablePlanDO#getId()},非必须
|
||||||
*/
|
*/
|
||||||
private Long planId;
|
private Long planId;
|
||||||
/**
|
/**
|
||||||
* 客户编号,关联 {@link CrmCustomerDO#getId()}
|
* 客户编号
|
||||||
|
*
|
||||||
|
* 关联 {@link CrmCustomerDO#getId()}
|
||||||
*/
|
*/
|
||||||
private Long customerId;
|
private Long customerId;
|
||||||
/**
|
/**
|
||||||
* 合同编号,关联 {@link CrmContractDO#getId()}
|
* 合同编号
|
||||||
|
*
|
||||||
|
* 关联 {@link CrmContractDO#getId()}
|
||||||
*/
|
*/
|
||||||
private Long contractId;
|
private Long contractId;
|
||||||
/**
|
/**
|
||||||
|
@ -61,7 +61,7 @@ public class CrmReceivablePlanDO extends BaseDO {
|
|||||||
*/
|
*/
|
||||||
private LocalDateTime returnTime;
|
private LocalDateTime returnTime;
|
||||||
/**
|
/**
|
||||||
* 回款类型
|
* 计划回款类型
|
||||||
*
|
*
|
||||||
* 枚举 {@link CrmReceivableReturnTypeEnum}
|
* 枚举 {@link CrmReceivableReturnTypeEnum}
|
||||||
*/
|
*/
|
||||||
@ -75,10 +75,6 @@ public class CrmReceivablePlanDO extends BaseDO {
|
|||||||
* 回款编号,关联 {@link CrmReceivableDO#getId()}
|
* 回款编号,关联 {@link CrmReceivableDO#getId()}
|
||||||
*/
|
*/
|
||||||
private Long receivableId;
|
private Long receivableId;
|
||||||
/**
|
|
||||||
* 完成状态
|
|
||||||
*/
|
|
||||||
private Boolean finishStatus;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 提前几天提醒
|
* 提前几天提醒
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
/**
|
|
||||||
* 回款
|
|
||||||
*/
|
|
||||||
package cn.iocoder.yudao.module.crm.dal.dataobject.receivable;
|
|
@ -1,5 +1,6 @@
|
|||||||
package cn.iocoder.yudao.module.crm.dal.mysql.receivable;
|
package cn.iocoder.yudao.module.crm.dal.mysql.receivable;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
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.LambdaQueryWrapperX;
|
||||||
@ -11,10 +12,16 @@ 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.common.CrmSceneTypeEnum;
|
import cn.iocoder.yudao.module.crm.enums.common.CrmSceneTypeEnum;
|
||||||
import cn.iocoder.yudao.module.crm.util.CrmPermissionUtils;
|
import cn.iocoder.yudao.module.crm.util.CrmPermissionUtils;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 回款 Mapper
|
* 回款 Mapper
|
||||||
@ -24,6 +31,10 @@ import java.util.List;
|
|||||||
@Mapper
|
@Mapper
|
||||||
public interface CrmReceivableMapper extends BaseMapperX<CrmReceivableDO> {
|
public interface CrmReceivableMapper extends BaseMapperX<CrmReceivableDO> {
|
||||||
|
|
||||||
|
default CrmReceivableDO selectByNo(String no) {
|
||||||
|
return selectOne(CrmReceivableDO::getNo, no);
|
||||||
|
}
|
||||||
|
|
||||||
default PageResult<CrmReceivableDO> selectPageByCustomerId(CrmReceivablePageReqVO reqVO) {
|
default PageResult<CrmReceivableDO> selectPageByCustomerId(CrmReceivablePageReqVO reqVO) {
|
||||||
return selectPage(reqVO, new LambdaQueryWrapperX<CrmReceivableDO>()
|
return selectPage(reqVO, new LambdaQueryWrapperX<CrmReceivableDO>()
|
||||||
.eq(CrmReceivableDO::getCustomerId, reqVO.getCustomerId()) // 必须传递
|
.eq(CrmReceivableDO::getCustomerId, reqVO.getCustomerId()) // 必须传递
|
||||||
@ -67,4 +78,18 @@ public interface CrmReceivableMapper extends BaseMapperX<CrmReceivableDO> {
|
|||||||
return selectCount(query);
|
return selectCount(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default Map<Long, BigDecimal> selectReceivablePriceMapByContractId(Collection<Long> contractIds) {
|
||||||
|
if (CollUtil.isEmpty(contractIds)) {
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
// SQL sum 查询
|
||||||
|
List<Map<String, Object>> result = selectMaps(new QueryWrapper<CrmReceivableDO>()
|
||||||
|
.select("contract_id, SUM(price) AS total_price")
|
||||||
|
.eq("audit_status", CrmAuditStatusEnum.APPROVE.getStatus())
|
||||||
|
.groupBy("contract_id")
|
||||||
|
.in("contract_id", contractIds));
|
||||||
|
// 获得金额
|
||||||
|
return convertMap(result, obj -> (Long) obj.get("contract_id"), obj -> (BigDecimal) obj.get("total_price"));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,13 @@ import java.util.Objects;
|
|||||||
@Mapper
|
@Mapper
|
||||||
public interface CrmReceivablePlanMapper extends BaseMapperX<CrmReceivablePlanDO> {
|
public interface CrmReceivablePlanMapper extends BaseMapperX<CrmReceivablePlanDO> {
|
||||||
|
|
||||||
|
default CrmReceivablePlanDO selectMaxPeriodByContractId(Long contractId) {
|
||||||
|
return selectOne(new MPJLambdaWrapperX<CrmReceivablePlanDO>()
|
||||||
|
.eq(CrmReceivablePlanDO::getContractId, contractId)
|
||||||
|
.orderByDesc(CrmReceivablePlanDO::getPeriod)
|
||||||
|
.last("LIMIT 1"));
|
||||||
|
}
|
||||||
|
|
||||||
default PageResult<CrmReceivablePlanDO> selectPageByCustomerId(CrmReceivablePlanPageReqVO reqVO) {
|
default PageResult<CrmReceivablePlanDO> selectPageByCustomerId(CrmReceivablePlanPageReqVO reqVO) {
|
||||||
MPJLambdaWrapperX<CrmReceivablePlanDO> query = new MPJLambdaWrapperX<>();
|
MPJLambdaWrapperX<CrmReceivablePlanDO> query = new MPJLambdaWrapperX<>();
|
||||||
if (Objects.nonNull(reqVO.getContractNo())) { // 根据合同编号检索
|
if (Objects.nonNull(reqVO.getContractNo())) { // 根据合同编号检索
|
||||||
@ -47,7 +54,6 @@ public interface CrmReceivablePlanMapper extends BaseMapperX<CrmReceivablePlanDO
|
|||||||
.eqIfPresent(CrmReceivablePlanDO::getCustomerId, pageReqVO.getCustomerId())
|
.eqIfPresent(CrmReceivablePlanDO::getCustomerId, pageReqVO.getCustomerId())
|
||||||
.eqIfPresent(CrmReceivablePlanDO::getContractId, pageReqVO.getContractId())
|
.eqIfPresent(CrmReceivablePlanDO::getContractId, pageReqVO.getContractId())
|
||||||
.orderByDesc(CrmReceivablePlanDO::getPeriod);
|
.orderByDesc(CrmReceivablePlanDO::getPeriod);
|
||||||
|
|
||||||
if (Objects.nonNull(pageReqVO.getContractNo())) { // 根据合同编号检索
|
if (Objects.nonNull(pageReqVO.getContractNo())) { // 根据合同编号检索
|
||||||
query.innerJoin(CrmContractDO.class, on -> on.like(CrmContractDO::getNo, pageReqVO.getContractNo())
|
query.innerJoin(CrmContractDO.class, on -> on.like(CrmContractDO::getNo, pageReqVO.getContractNo())
|
||||||
.eq(CrmContractDO::getId, CrmReceivablePlanDO::getContractId));
|
.eq(CrmContractDO::getId, CrmReceivablePlanDO::getContractId));
|
||||||
@ -67,9 +73,7 @@ public interface CrmReceivablePlanMapper extends BaseMapperX<CrmReceivablePlanDO
|
|||||||
} else if (CrmReceivablePlanPageReqVO.REMIND_TYPE_RECEIVED.equals(pageReqVO.getRemindType())) { // 已回款
|
} else if (CrmReceivablePlanPageReqVO.REMIND_TYPE_RECEIVED.equals(pageReqVO.getRemindType())) { // 已回款
|
||||||
query.isNotNull(CrmReceivablePlanDO::getReceivableId)
|
query.isNotNull(CrmReceivablePlanDO::getReceivableId)
|
||||||
.between(CrmReceivablePlanDO::getReturnTime, beginOfToday, endOfToday.plusDays(REMIND_DAYS));
|
.between(CrmReceivablePlanDO::getReturnTime, beginOfToday, endOfToday.plusDays(REMIND_DAYS));
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return selectJoinPage(pageReqVO, CrmReceivablePlanDO.class, query);
|
return selectJoinPage(pageReqVO, CrmReceivablePlanDO.class, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,6 +97,9 @@ public interface CrmReceivablePlanMapper extends BaseMapperX<CrmReceivablePlanDO
|
|||||||
LocalDateTime endOfToday = LocalDateTimeUtil.endOfDay(LocalDateTime.now());
|
LocalDateTime endOfToday = LocalDateTimeUtil.endOfDay(LocalDateTime.now());
|
||||||
query.isNull(CrmReceivablePlanDO::getReceivableId)
|
query.isNull(CrmReceivablePlanDO::getReceivableId)
|
||||||
.between(CrmReceivablePlanDO::getReturnTime, beginOfToday, endOfToday.plusDays(REMIND_DAYS));
|
.between(CrmReceivablePlanDO::getReturnTime, beginOfToday, endOfToday.plusDays(REMIND_DAYS));
|
||||||
|
// TODO return_time 小于现在;
|
||||||
|
// TODO 未回款
|
||||||
|
// TODO remind_time 大于现在;
|
||||||
return selectCount(query);
|
return selectCount(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ public class CrmNoRedisDAO {
|
|||||||
public static final String CONTRACT_NO_PREFIX = "HT";
|
public static final String CONTRACT_NO_PREFIX = "HT";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 还款 {@link cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO}
|
* 回款 {@link cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO}
|
||||||
*/
|
*/
|
||||||
public static final String RECEIVABLE_PREFIX = "HK";
|
public static final String RECEIVABLE_PREFIX = "HK";
|
||||||
|
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
package cn.iocoder.yudao.module.crm.framework.operatelog.core;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO;
|
||||||
|
import cn.iocoder.yudao.module.crm.service.receivable.CrmReceivablePlanService;
|
||||||
|
import com.mzt.logapi.service.IParseFunction;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CRM 回款计划的 {@link IParseFunction} 实现类
|
||||||
|
*
|
||||||
|
* @author HUIHUI
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class CrmReceivablePlanParseFunction implements IParseFunction {
|
||||||
|
|
||||||
|
public static final String NAME = "getReceivablePlanServiceById";
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CrmReceivablePlanService receivablePlanService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean executeBefore() {
|
||||||
|
return true; // 先转换值后对比
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String functionName() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apply(Object value) {
|
||||||
|
if (StrUtil.isEmptyIfStr(value)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
CrmReceivablePlanDO receivablePlan = receivablePlanService.getReceivablePlan(Long.parseLong(value.toString()));
|
||||||
|
return receivablePlan == null ? "" : receivablePlan.getPeriod().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package cn.iocoder.yudao.module.crm.framework.operatelog.core;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
|
||||||
|
import com.mzt.logapi.service.IParseFunction;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_RECEIVABLE_RETURN_TYPE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CRM 回款方式的 {@link IParseFunction} 实现类
|
||||||
|
*
|
||||||
|
* @author HUIHUI
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class CrmReceivableReturnTypeParseFunction implements IParseFunction {
|
||||||
|
|
||||||
|
public static final String NAME = "getReceivableReturnType";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean executeBefore() {
|
||||||
|
return true; // 先转换值后对比
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String functionName() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apply(Object value) {
|
||||||
|
if (StrUtil.isEmptyIfStr(value)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return DictFrameworkUtils.getDictDataLabel(CRM_RECEIVABLE_RETURN_TYPE, value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -13,6 +13,9 @@ import jakarta.validation.Valid;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CRM 合同 Service 接口
|
* CRM 合同 Service 接口
|
||||||
@ -85,6 +88,14 @@ public interface CrmContractService {
|
|||||||
*/
|
*/
|
||||||
CrmContractDO getContract(Long id);
|
CrmContractDO getContract(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验合同是否合法
|
||||||
|
*
|
||||||
|
* @param id 编号
|
||||||
|
* @return 合同
|
||||||
|
*/
|
||||||
|
CrmContractDO validateContract(Long id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得合同列表
|
* 获得合同列表
|
||||||
*
|
*
|
||||||
@ -93,6 +104,16 @@ public interface CrmContractService {
|
|||||||
*/
|
*/
|
||||||
List<CrmContractDO> getContractList(Collection<Long> ids);
|
List<CrmContractDO> getContractList(Collection<Long> ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得合同 Map
|
||||||
|
*
|
||||||
|
* @param ids 编号
|
||||||
|
* @return 合同 Map
|
||||||
|
*/
|
||||||
|
default Map<Long, CrmContractDO> getContractMap(Collection<Long> ids) {
|
||||||
|
return convertMap(getContractList(ids), CrmContractDO::getId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得合同分页
|
* 获得合同分页
|
||||||
*
|
*
|
||||||
|
@ -323,6 +323,11 @@ public class CrmContractServiceImpl implements CrmContractService {
|
|||||||
return contractMapper.selectById(id);
|
return contractMapper.selectById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CrmContractDO validateContract(Long id) {
|
||||||
|
return validateContractExists(id);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<CrmContractDO> getContractList(Collection<Long> ids) {
|
public List<CrmContractDO> getContractList(Collection<Long> ids) {
|
||||||
if (CollUtil.isEmpty(ids)) {
|
if (CollUtil.isEmpty(ids)) {
|
||||||
|
@ -38,7 +38,7 @@ public interface CrmReceivablePlanService {
|
|||||||
* @param id 编号
|
* @param id 编号
|
||||||
* @param receivableId 回款编号
|
* @param receivableId 回款编号
|
||||||
*/
|
*/
|
||||||
void updateReceivableId(Long id, Long receivableId);
|
void updateReceivablePlanReceivableId(Long id, Long receivableId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除回款计划
|
* 删除回款计划
|
||||||
|
@ -2,20 +2,17 @@ package cn.iocoder.yudao.module.crm.service.receivable;
|
|||||||
|
|
||||||
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.ObjectUtil;
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanPageReqVO;
|
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanPageReqVO;
|
||||||
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanSaveReqVO;
|
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.plan.CrmReceivablePlanSaveReqVO;
|
||||||
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.customer.CrmCustomerDO;
|
|
||||||
import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO;
|
import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO;
|
||||||
import cn.iocoder.yudao.module.crm.dal.mysql.receivable.CrmReceivablePlanMapper;
|
import cn.iocoder.yudao.module.crm.dal.mysql.receivable.CrmReceivablePlanMapper;
|
||||||
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.contract.CrmContractService;
|
import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
|
||||||
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
|
|
||||||
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.system.api.user.AdminUserApi;
|
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||||
@ -33,7 +30,8 @@ import java.util.List;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
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.*;
|
import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.RECEIVABLE_PLAN_NOT_EXISTS;
|
||||||
|
import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.RECEIVABLE_PLAN_UPDATE_FAIL;
|
||||||
import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
|
import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,8 +52,6 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService {
|
|||||||
@Resource
|
@Resource
|
||||||
private CrmContractService contractService;
|
private CrmContractService contractService;
|
||||||
@Resource
|
@Resource
|
||||||
private CrmCustomerService customerService;
|
|
||||||
@Resource
|
|
||||||
private CrmPermissionService permissionService;
|
private CrmPermissionService permissionService;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
@ -66,15 +62,16 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService {
|
|||||||
@LogRecord(type = CRM_RECEIVABLE_PLAN_TYPE, subType = CRM_RECEIVABLE_PLAN_CREATE_SUB_TYPE, bizNo = "{{#receivablePlan.id}}",
|
@LogRecord(type = CRM_RECEIVABLE_PLAN_TYPE, subType = CRM_RECEIVABLE_PLAN_CREATE_SUB_TYPE, bizNo = "{{#receivablePlan.id}}",
|
||||||
success = CRM_RECEIVABLE_PLAN_CREATE_SUCCESS)
|
success = CRM_RECEIVABLE_PLAN_CREATE_SUCCESS)
|
||||||
public Long createReceivablePlan(CrmReceivablePlanSaveReqVO createReqVO) {
|
public Long createReceivablePlan(CrmReceivablePlanSaveReqVO createReqVO) {
|
||||||
// 1.1 校验关联数据是否存在
|
// 1. 校验关联数据是否存在
|
||||||
validateRelationDataExists(createReqVO);
|
validateRelationDataExists(createReqVO);
|
||||||
// 1.2 查验关联合同回款数量
|
|
||||||
Long count = receivableService.getReceivableCountByContractId(createReqVO.getContractId());
|
|
||||||
int period = (int) (count + 1);
|
|
||||||
|
|
||||||
// 2. 插入还款计划
|
// 2. 插入回款计划
|
||||||
CrmReceivablePlanDO receivablePlan = BeanUtils.toBean(createReqVO, CrmReceivablePlanDO.class)
|
CrmReceivablePlanDO maxPeriodReceivablePlan = receivablePlanMapper.selectMaxPeriodByContractId(createReqVO.getContractId());
|
||||||
.setPeriod(period).setFinishStatus(false);
|
int period = maxPeriodReceivablePlan == null ? 1 : maxPeriodReceivablePlan.getPeriod() + 1;
|
||||||
|
CrmReceivablePlanDO receivablePlan = BeanUtils.toBean(createReqVO, CrmReceivablePlanDO.class).setPeriod(period);
|
||||||
|
if (createReqVO.getReturnTime() != null && createReqVO.getRemindDays() != null) {
|
||||||
|
receivablePlan.setRemindTime(createReqVO.getReturnTime().minusDays(createReqVO.getRemindDays()));
|
||||||
|
}
|
||||||
receivablePlanMapper.insert(receivablePlan);
|
receivablePlanMapper.insert(receivablePlan);
|
||||||
|
|
||||||
// 3. 创建数据权限
|
// 3. 创建数据权限
|
||||||
@ -93,15 +90,21 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService {
|
|||||||
success = CRM_RECEIVABLE_PLAN_UPDATE_SUCCESS)
|
success = CRM_RECEIVABLE_PLAN_UPDATE_SUCCESS)
|
||||||
@CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE_PLAN, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
|
@CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE_PLAN, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
|
||||||
public void updateReceivablePlan(CrmReceivablePlanSaveReqVO updateReqVO) {
|
public void updateReceivablePlan(CrmReceivablePlanSaveReqVO updateReqVO) {
|
||||||
// 1. 校验存在
|
updateReqVO.setOwnerUserId(null).setCustomerId(null).setContractId(null); // 防止修改这些字段
|
||||||
|
// 1.1 校验存在
|
||||||
validateRelationDataExists(updateReqVO);
|
validateRelationDataExists(updateReqVO);
|
||||||
|
// 1.2 校验关联数据是否存在
|
||||||
CrmReceivablePlanDO oldReceivablePlan = validateReceivablePlanExists(updateReqVO.getId());
|
CrmReceivablePlanDO oldReceivablePlan = validateReceivablePlanExists(updateReqVO.getId());
|
||||||
if (Objects.nonNull(oldReceivablePlan.getReceivableId())) { // 如果已经有对应的还款,则不允许编辑;
|
// 1.3 如果已经有对应的回款,则不允许编辑
|
||||||
throw exception(RECEIVABLE_PLAN_UPDATE_FAIL, "已经有对应的还款");
|
if (Objects.nonNull(oldReceivablePlan.getReceivableId())) {
|
||||||
|
throw exception(RECEIVABLE_PLAN_UPDATE_FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 更新
|
// 2. 更新回款计划
|
||||||
CrmReceivablePlanDO updateObj = BeanUtils.toBean(updateReqVO, CrmReceivablePlanDO.class);
|
CrmReceivablePlanDO updateObj = BeanUtils.toBean(updateReqVO, CrmReceivablePlanDO.class);
|
||||||
|
if (updateReqVO.getReturnTime() != null && updateReqVO.getRemindDays() != null) {
|
||||||
|
updateObj.setRemindTime(updateReqVO.getReturnTime().minusDays(updateReqVO.getRemindDays()));
|
||||||
|
}
|
||||||
receivablePlanMapper.updateById(updateObj);
|
receivablePlanMapper.updateById(updateObj);
|
||||||
|
|
||||||
// 3. 记录操作日志上下文
|
// 3. 记录操作日志上下文
|
||||||
@ -109,24 +112,24 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService {
|
|||||||
LogRecordContext.putVariable("receivablePlan", oldReceivablePlan);
|
LogRecordContext.putVariable("receivablePlan", oldReceivablePlan);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validateRelationDataExists(CrmReceivablePlanSaveReqVO reqVO) {
|
||||||
|
// 校验负责人存在
|
||||||
|
if (reqVO.getOwnerUserId() != null) {
|
||||||
|
adminUserApi.validateUser(reqVO.getOwnerUserId());
|
||||||
|
}
|
||||||
|
// 校验合同存在
|
||||||
|
if (reqVO.getContractId() != null) {
|
||||||
|
CrmContractDO contract = contractService.getContract(reqVO.getContractId());
|
||||||
|
reqVO.setCustomerId(contract.getCustomerId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateReceivableId(Long id, Long receivableId) {
|
public void updateReceivablePlanReceivableId(Long id, Long receivableId) {
|
||||||
// 校验存在
|
// 校验存在
|
||||||
validateReceivablePlanExists(id);
|
validateReceivablePlanExists(id);
|
||||||
// 更新回款计划
|
// 更新回款计划
|
||||||
receivablePlanMapper.updateById(new CrmReceivablePlanDO().setReceivableId(receivableId).setFinishStatus(true));
|
receivablePlanMapper.updateById(new CrmReceivablePlanDO().setId(id).setReceivableId(receivableId));
|
||||||
}
|
|
||||||
|
|
||||||
private void validateRelationDataExists(CrmReceivablePlanSaveReqVO reqVO) {
|
|
||||||
adminUserApi.validateUser(reqVO.getOwnerUserId()); // 校验负责人存在
|
|
||||||
CrmContractDO contract = contractService.getContract(reqVO.getContractId());
|
|
||||||
if (ObjectUtil.isNull(contract)) { // 合同不存在
|
|
||||||
throw exception(CONTRACT_NOT_EXISTS);
|
|
||||||
}
|
|
||||||
CrmCustomerDO customer = customerService.getCustomer(reqVO.getCustomerId());
|
|
||||||
if (ObjectUtil.isNull(customer)) { // 客户不存在
|
|
||||||
throw exception(CUSTOMER_NOT_EXISTS);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -135,13 +138,15 @@ public class CrmReceivablePlanServiceImpl implements CrmReceivablePlanService {
|
|||||||
success = CRM_RECEIVABLE_PLAN_DELETE_SUCCESS)
|
success = CRM_RECEIVABLE_PLAN_DELETE_SUCCESS)
|
||||||
@CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE_PLAN, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
|
@CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE_PLAN, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
|
||||||
public void deleteReceivablePlan(Long id) {
|
public void deleteReceivablePlan(Long id) {
|
||||||
// 校验存在
|
// 1. 校验存在
|
||||||
CrmReceivablePlanDO receivablePlan = validateReceivablePlanExists(id);
|
CrmReceivablePlanDO receivablePlan = validateReceivablePlanExists(id);
|
||||||
// 删除
|
|
||||||
|
// 2. 删除
|
||||||
receivablePlanMapper.deleteById(id);
|
receivablePlanMapper.deleteById(id);
|
||||||
// 删除数据权限
|
// 3. 删除数据权限
|
||||||
permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), id);
|
permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), id);
|
||||||
// 记录操作日志上下文
|
|
||||||
|
// 4. 记录操作日志上下文
|
||||||
LogRecordContext.putVariable("receivablePlan", receivablePlan);
|
LogRecordContext.putVariable("receivablePlan", receivablePlan);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,8 +7,12 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
|
|||||||
import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO;
|
import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CRM 回款 Service 接口
|
* CRM 回款 Service 接口
|
||||||
@ -71,6 +75,16 @@ public interface CrmReceivableService {
|
|||||||
*/
|
*/
|
||||||
List<CrmReceivableDO> getReceivableList(Collection<Long> ids);
|
List<CrmReceivableDO> getReceivableList(Collection<Long> ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得回款 Map
|
||||||
|
*
|
||||||
|
* @param ids 编号
|
||||||
|
* @return 回款 Map
|
||||||
|
*/
|
||||||
|
default Map<Long, CrmReceivableDO> getReceivableMap(Collection<Long> ids) {
|
||||||
|
return convertMap(getReceivableList(ids), CrmReceivableDO::getId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得回款分页
|
* 获得回款分页
|
||||||
*
|
*
|
||||||
@ -101,11 +115,11 @@ public interface CrmReceivableService {
|
|||||||
Long getCheckReceivablesCount(Long userId);
|
Long getCheckReceivablesCount(Long userId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据合同编号,获取合同关联的回款数量
|
* 获得合同已回款金额 Map
|
||||||
*
|
*
|
||||||
* @param contractId 合同编号
|
* @param contractIds 合同编号
|
||||||
* @return 数量
|
* @return 回款金额 Map
|
||||||
*/
|
*/
|
||||||
Long getReceivableCountByContractId(Long contractId);
|
Map<Long, BigDecimal> getReceivablePriceMapByContractId(Collection<Long> contractIds);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,16 +13,15 @@ import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
|
|||||||
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO;
|
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO;
|
||||||
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableSaveReqVO;
|
import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableSaveReqVO;
|
||||||
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.customer.CrmCustomerDO;
|
|
||||||
import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO;
|
import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivableDO;
|
||||||
import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO;
|
import cn.iocoder.yudao.module.crm.dal.dataobject.receivable.CrmReceivablePlanDO;
|
||||||
import cn.iocoder.yudao.module.crm.dal.mysql.receivable.CrmReceivableMapper;
|
import cn.iocoder.yudao.module.crm.dal.mysql.receivable.CrmReceivableMapper;
|
||||||
|
import cn.iocoder.yudao.module.crm.dal.redis.no.CrmNoRedisDAO;
|
||||||
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.contract.CrmContractService;
|
import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
|
||||||
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
|
|
||||||
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.system.api.user.AdminUserApi;
|
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||||
@ -36,9 +35,10 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Map;
|
||||||
|
|
||||||
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.*;
|
import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
|
||||||
@ -56,17 +56,18 @@ import static cn.iocoder.yudao.module.crm.util.CrmAuditStatusUtils.convertBpmRes
|
|||||||
public class CrmReceivableServiceImpl implements CrmReceivableService {
|
public class CrmReceivableServiceImpl implements CrmReceivableService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BPM 回款审批流程标识
|
* BPM 合同审批流程标识
|
||||||
*/
|
*/
|
||||||
public static final String RECEIVABLE_APPROVE = "receivable-approve";
|
public static final String BPM_PROCESS_DEFINITION_KEY = "crm-receivable-audit";
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private CrmReceivableMapper receivableMapper;
|
private CrmReceivableMapper receivableMapper;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private CrmContractService contractService;
|
private CrmNoRedisDAO noRedisDAO;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private CrmCustomerService customerService;
|
private CrmContractService contractService;
|
||||||
@Resource
|
@Resource
|
||||||
@Lazy // 延迟加载,避免循环依赖
|
@Lazy // 延迟加载,避免循环依赖
|
||||||
private CrmReceivablePlanService receivablePlanService;
|
private CrmReceivablePlanService receivablePlanService;
|
||||||
@ -78,48 +79,63 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
|
|||||||
@Resource
|
@Resource
|
||||||
private BpmProcessInstanceApi bpmProcessInstanceApi;
|
private BpmProcessInstanceApi bpmProcessInstanceApi;
|
||||||
|
|
||||||
|
// TODO @puhui999:操作日志没记录上
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
@LogRecord(type = CRM_RECEIVABLE_TYPE, subType = CRM_RECEIVABLE_CREATE_SUB_TYPE, bizNo = "{{#receivable.id}}",
|
@LogRecord(type = CRM_RECEIVABLE_TYPE, subType = CRM_RECEIVABLE_CREATE_SUB_TYPE, bizNo = "{{#receivable.id}}",
|
||||||
success = CRM_RECEIVABLE_CREATE_SUCCESS)
|
success = CRM_RECEIVABLE_CREATE_SUCCESS)
|
||||||
public Long createReceivable(CrmReceivableSaveReqVO createReqVO) {
|
public Long createReceivable(CrmReceivableSaveReqVO createReqVO) {
|
||||||
// 1. 校验关联数据存在
|
// 1.1 校验关联数据存在
|
||||||
validateRelationDataExists(createReqVO);
|
validateRelationDataExists(createReqVO);
|
||||||
// 2. 插入还款
|
// 1.2 生成回款编号
|
||||||
CrmReceivableDO receivable = BeanUtils.toBean(createReqVO, CrmReceivableDO.class).setAuditStatus(CrmAuditStatusEnum.DRAFT.getStatus());
|
String no = noRedisDAO.generate(CrmNoRedisDAO.RECEIVABLE_PREFIX);
|
||||||
|
if (receivableMapper.selectByNo(no) != null) {
|
||||||
|
throw exception(RECEIVABLE_NO_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 插入回款
|
||||||
|
CrmReceivableDO receivable = BeanUtils.toBean(createReqVO, CrmReceivableDO.class)
|
||||||
|
.setNo(no).setAuditStatus(CrmAuditStatusEnum.DRAFT.getStatus());
|
||||||
receivableMapper.insert(receivable);
|
receivableMapper.insert(receivable);
|
||||||
|
|
||||||
// 3. 创建数据权限
|
// 3. 创建数据权限
|
||||||
permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_RECEIVABLE.getType())
|
permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_RECEIVABLE.getType())
|
||||||
.setBizId(receivable.getId()).setUserId(createReqVO.getOwnerUserId()).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人
|
.setBizId(receivable.getId()).setUserId(createReqVO.getOwnerUserId())
|
||||||
|
.setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人
|
||||||
|
|
||||||
// 4. 更新关联的回款计划
|
// 4. 更新关联的回款计划
|
||||||
if (Objects.nonNull(createReqVO.getPlanId())) {
|
if (createReqVO.getPlanId() != null) {
|
||||||
receivablePlanService.updateReceivableId(receivable.getPlanId(), receivable.getId());
|
receivablePlanService.updateReceivablePlanReceivableId(receivable.getPlanId(), receivable.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. 记录操作日志上下文
|
// 5. 记录操作日志上下文
|
||||||
LogRecordContext.putVariable("receivable", receivable);
|
LogRecordContext.putVariable("receivable", receivable);
|
||||||
return receivable.getId();
|
return receivable.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateRelationDataExists(CrmReceivableSaveReqVO reqVO) {
|
private void validateRelationDataExists(CrmReceivableSaveReqVO reqVO) {
|
||||||
|
if (reqVO.getOwnerUserId() != null) {
|
||||||
adminUserApi.validateUser(reqVO.getOwnerUserId()); // 校验负责人存在
|
adminUserApi.validateUser(reqVO.getOwnerUserId()); // 校验负责人存在
|
||||||
CrmContractDO contract = contractService.getContract(reqVO.getContractId());
|
|
||||||
if (ObjectUtil.isNull(contract)) {
|
|
||||||
throw exception(CONTRACT_NOT_EXISTS);
|
|
||||||
}
|
}
|
||||||
CrmCustomerDO customer = customerService.getCustomer(reqVO.getCustomerId());
|
if (reqVO.getContractId() != null) {
|
||||||
if (ObjectUtil.isNull(customer)) {
|
CrmContractDO contract = contractService.validateContract(reqVO.getContractId());
|
||||||
throw exception(CUSTOMER_NOT_EXISTS);
|
if (ObjectUtil.notEqual(contract.getAuditStatus(), CrmAuditStatusEnum.APPROVE.getStatus())) {
|
||||||
|
throw exception(RECEIVABLE_CREATE_FAIL_CONTRACT_NOT_APPROVE);
|
||||||
}
|
}
|
||||||
if (Objects.isNull(reqVO.getPlanId())) { // 没有回款计划编号则不校验
|
reqVO.setCustomerId(contract.getCustomerId()); // 设置客户编号
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
if (reqVO.getPlanId() != null) {
|
||||||
CrmReceivablePlanDO receivablePlan = receivablePlanService.getReceivablePlan(reqVO.getPlanId());
|
CrmReceivablePlanDO receivablePlan = receivablePlanService.getReceivablePlan(reqVO.getPlanId());
|
||||||
if (ObjectUtil.isNull(receivablePlan)) {
|
if (receivablePlan == null) {
|
||||||
throw exception(RECEIVABLE_PLAN_NOT_EXISTS);
|
throw exception(RECEIVABLE_PLAN_NOT_EXISTS);
|
||||||
}
|
}
|
||||||
|
if (receivablePlan.getReceivableId() != null) {
|
||||||
|
throw exception(RECEIVABLE_PLAN_EXISTS_RECEIVABLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO @puhui999:操作日志没记录上
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
@LogRecord(type = CRM_RECEIVABLE_TYPE, subType = CRM_RECEIVABLE_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}",
|
@LogRecord(type = CRM_RECEIVABLE_TYPE, subType = CRM_RECEIVABLE_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}",
|
||||||
@ -127,6 +143,7 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
|
|||||||
@CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
|
@CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
|
||||||
public void updateReceivable(CrmReceivableSaveReqVO updateReqVO) {
|
public void updateReceivable(CrmReceivableSaveReqVO updateReqVO) {
|
||||||
Assert.notNull(updateReqVO.getId(), "回款编号不能为空");
|
Assert.notNull(updateReqVO.getId(), "回款编号不能为空");
|
||||||
|
updateReqVO.setOwnerUserId(null).setCustomerId(null).setContractId(null).setPlanId(null); // 不允许修改的字段
|
||||||
// 1.1 校验存在
|
// 1.1 校验存在
|
||||||
CrmReceivableDO receivable = validateReceivableExists(updateReqVO.getId());
|
CrmReceivableDO receivable = validateReceivableExists(updateReqVO.getId());
|
||||||
// 1.2 只有草稿、审批中,可以编辑;
|
// 1.2 只有草稿、审批中,可以编辑;
|
||||||
@ -135,7 +152,7 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
|
|||||||
throw exception(RECEIVABLE_UPDATE_FAIL_EDITING_PROHIBITED);
|
throw exception(RECEIVABLE_UPDATE_FAIL_EDITING_PROHIBITED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 更新还款
|
// 2. 更新回款
|
||||||
CrmReceivableDO updateObj = BeanUtils.toBean(updateReqVO, CrmReceivableDO.class);
|
CrmReceivableDO updateObj = BeanUtils.toBean(updateReqVO, CrmReceivableDO.class);
|
||||||
receivableMapper.updateById(updateObj);
|
receivableMapper.updateById(updateObj);
|
||||||
|
|
||||||
@ -160,27 +177,25 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
|
|||||||
receivableMapper.updateById(new CrmReceivableDO().setId(id).setAuditStatus(auditStatus));
|
receivableMapper.updateById(new CrmReceivableDO().setId(id).setAuditStatus(auditStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO @liuhongfeng:缺一个取消回款的接口;只有草稿、审批中可以取消;CrmAuditStatusEnum
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
@LogRecord(type = CRM_RECEIVABLE_TYPE, subType = CRM_RECEIVABLE_DELETE_SUB_TYPE, bizNo = "{{#id}}",
|
@LogRecord(type = CRM_RECEIVABLE_TYPE, subType = CRM_RECEIVABLE_DELETE_SUB_TYPE, bizNo = "{{#id}}",
|
||||||
success = CRM_RECEIVABLE_DELETE_SUCCESS)
|
success = CRM_RECEIVABLE_DELETE_SUCCESS)
|
||||||
@CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
|
@CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
|
||||||
public void deleteReceivable(Long id) {
|
public void deleteReceivable(Long id) {
|
||||||
// 校验存在
|
// 1.1 校验存在
|
||||||
CrmReceivableDO receivable = validateReceivableExists(id);
|
CrmReceivableDO receivable = validateReceivableExists(id);
|
||||||
// 如果被 CrmReceivablePlanDO 所使用,则不允许删除
|
// 1.2 如果被 CrmReceivablePlanDO 所使用,则不允许删除
|
||||||
if (Objects.nonNull(receivable.getPlanId()) && receivablePlanService.getReceivablePlan(receivable.getPlanId()) != null) {
|
if (receivable.getPlanId() != null && receivablePlanService.getReceivablePlan(receivable.getPlanId()) != null) {
|
||||||
throw exception(RECEIVABLE_DELETE_FAIL);
|
throw exception(RECEIVABLE_DELETE_FAIL);
|
||||||
}
|
}
|
||||||
// 删除
|
|
||||||
receivableMapper.deleteById(id);
|
|
||||||
|
|
||||||
// 删除数据权限
|
// 2. 删除
|
||||||
|
receivableMapper.deleteById(id);
|
||||||
|
// 3. 删除数据权限
|
||||||
permissionService.deletePermission(CrmBizTypeEnum.CRM_RECEIVABLE.getType(), id);
|
permissionService.deletePermission(CrmBizTypeEnum.CRM_RECEIVABLE.getType(), id);
|
||||||
|
|
||||||
// 记录操作日志上下文
|
// 4. 记录操作日志上下文
|
||||||
LogRecordContext.putVariable("receivable", receivable);
|
LogRecordContext.putVariable("receivable", receivable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +212,7 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
|
|||||||
|
|
||||||
// 2. 创建回款审批流程实例
|
// 2. 创建回款审批流程实例
|
||||||
String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO()
|
String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO()
|
||||||
.setProcessDefinitionKey(RECEIVABLE_APPROVE).setBusinessKey(String.valueOf(id)));
|
.setProcessDefinitionKey(BPM_PROCESS_DEFINITION_KEY).setBusinessKey(String.valueOf(id)));
|
||||||
|
|
||||||
// 3. 更新回款工作流编号
|
// 3. 更新回款工作流编号
|
||||||
receivableMapper.updateById(new CrmReceivableDO().setId(id).setProcessInstanceId(processInstanceId)
|
receivableMapper.updateById(new CrmReceivableDO().setId(id).setProcessInstanceId(processInstanceId)
|
||||||
@ -246,8 +261,8 @@ public class CrmReceivableServiceImpl implements CrmReceivableService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long getReceivableCountByContractId(Long contractId) {
|
public Map<Long, BigDecimal> getReceivablePriceMapByContractId(Collection<Long> contractIds) {
|
||||||
return receivableMapper.selectCount(CrmReceivableDO::getContractId, contractId);
|
return receivableMapper.selectReceivablePriceMapByContractId(contractIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ public class CrmReceivableResultListener extends BpmProcessInstanceResultEventLi
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getProcessDefinitionKey() {
|
public String getProcessDefinitionKey() {
|
||||||
return CrmReceivableServiceImpl.RECEIVABLE_APPROVE;
|
return CrmReceivableServiceImpl.BPM_PROCESS_DEFINITION_KEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user