diff --git a/yudao-module-pms/yudao-module-pms-api/src/main/java/cn/iocoder/yudao/module/pms/enums/ErrorCodeConstants.java b/yudao-module-pms/yudao-module-pms-api/src/main/java/cn/iocoder/yudao/module/pms/enums/ErrorCodeConstants.java index eccb301ae..acdd258c6 100644 --- a/yudao-module-pms/yudao-module-pms-api/src/main/java/cn/iocoder/yudao/module/pms/enums/ErrorCodeConstants.java +++ b/yudao-module-pms/yudao-module-pms-api/src/main/java/cn/iocoder/yudao/module/pms/enums/ErrorCodeConstants.java @@ -33,4 +33,8 @@ public interface ErrorCodeConstants { ErrorCode BUDGET_ALREADY_EXISTS = new ErrorCode(1_024_003_000, "该预算已经创建"); ErrorCode PROFIT_MARGIN_ERROR = new ErrorCode(1_024_004_000, "利润率计算错误"); + + ErrorCode RECEIVABLES_ALREADY_EXISTS = new ErrorCode(1_024_005_000, "该应收款已经创建"); + + ErrorCode RECEIVABLES_CALCULATION_ERROR = new ErrorCode(1_024_006_000, "合同应收款计算错误"); } diff --git a/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/receivables/ReceivablesController.java b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/receivables/ReceivablesController.java index 4a4f903cc..206a04384 100644 --- a/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/receivables/ReceivablesController.java +++ b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/receivables/ReceivablesController.java @@ -24,6 +24,7 @@ import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; import cn.iocoder.yudao.module.pms.controller.admin.receivables.vo.*; import cn.iocoder.yudao.module.pms.dal.dataobject.receivables.ReceivablesDO; @@ -42,14 +43,14 @@ public class ReceivablesController { @Operation(summary = "创建应收款管理") @PreAuthorize("@ss.hasPermission('pms:receivables:create')") public CommonResult createReceivables(@Valid @RequestBody ReceivablesSaveReqVO createReqVO) { - return success(receivablesService.createReceivables(createReqVO)); + return success(receivablesService.createReceivables(getLoginUserId(), createReqVO)); } @PutMapping("/update") @Operation(summary = "更新应收款管理") @PreAuthorize("@ss.hasPermission('pms:receivables:update')") public CommonResult updateReceivables(@Valid @RequestBody ReceivablesSaveReqVO updateReqVO) { - receivablesService.updateReceivables(updateReqVO); + receivablesService.updateReceivables(getLoginUserId(), updateReqVO); return success(true); } @@ -67,16 +68,16 @@ public class ReceivablesController { @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('pms:receivables:query')") public CommonResult getReceivables(@RequestParam("id") Long id) { - ReceivablesDO receivables = receivablesService.getReceivables(id); - return success(BeanUtils.toBean(receivables, ReceivablesRespVO.class)); + ReceivablesRespVO receivables = receivablesService.getReceivables(id); + return success(receivables); } @GetMapping("/page") @Operation(summary = "获得应收款管理分页") @PreAuthorize("@ss.hasPermission('pms:receivables:query')") public CommonResult> getReceivablesPage(@Valid ReceivablesPageReqVO pageReqVO) { - PageResult pageResult = receivablesService.getReceivablesPage(pageReqVO); - return success(BeanUtils.toBean(pageResult, ReceivablesRespVO.class)); + PageResult pageResult = receivablesService.getReceivablesPage(pageReqVO); + return success(pageResult); } @GetMapping("/export-excel") @@ -86,7 +87,7 @@ public class ReceivablesController { public void exportReceivablesExcel(@Valid ReceivablesPageReqVO pageReqVO, HttpServletResponse response) throws IOException { pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = receivablesService.getReceivablesPage(pageReqVO).getList(); + List list = receivablesService.getReceivablesPage(pageReqVO).getList(); // 导出 Excel ExcelUtils.write(response, "应收款管理.xls", "数据", ReceivablesRespVO.class, BeanUtils.toBean(list, ReceivablesRespVO.class)); diff --git a/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/receivables/vo/ReceivablesRespVO.java b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/receivables/vo/ReceivablesRespVO.java index c541f3fdb..92a7d419b 100644 --- a/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/receivables/vo/ReceivablesRespVO.java +++ b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/receivables/vo/ReceivablesRespVO.java @@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.pms.controller.admin.receivables.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; + +import java.math.BigDecimal; import java.util.*; import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDateTime; @@ -12,6 +14,39 @@ import com.alibaba.excel.annotation.*; @ExcelIgnoreUnannotated public class ReceivablesRespVO { + @Schema(description = "项目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "SJ24001") + @ExcelProperty("项目编号") + private String projectCode; + + @Schema(description = "合同名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "规划一路道路工程勘察设计合同") + @ExcelProperty("合同名称") + private String contractName; + + @Schema(description = "签订合同总额", requiredMode = Schema.RequiredMode.REQUIRED, example = "80.0000") + @ExcelProperty("签订合同总额") + private BigDecimal signedAmount; + + @Schema(description = "包干/审定金额", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("包干/审定金额") + private BigDecimal approvedAmount; + + @Schema(description = "已完成设计阶段", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("已完成设计阶段") + private String completedDesignStage; + + @Schema(description = "应收款取数", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("应收款取数") + private BigDecimal receivableAccount; + + @Schema(description = "合同应收款", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("合同应收款") + private BigDecimal contractualReceivables; + + @Schema(description = "应收款差额", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("应收款差额") + private BigDecimal receivableDifference; + + @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED) @ExcelProperty("主键") private Long id; diff --git a/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/receivables/vo/ReceivablesSaveReqVO.java b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/receivables/vo/ReceivablesSaveReqVO.java index 603b926db..b6329c2a6 100644 --- a/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/receivables/vo/ReceivablesSaveReqVO.java +++ b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/receivables/vo/ReceivablesSaveReqVO.java @@ -1,7 +1,10 @@ package cn.iocoder.yudao.module.pms.controller.admin.receivables.vo; +import com.alibaba.excel.annotation.ExcelProperty; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; + +import java.math.BigDecimal; import java.util.*; import jakarta.validation.constraints.*; @@ -9,6 +12,39 @@ import jakarta.validation.constraints.*; @Data public class ReceivablesSaveReqVO { + @Schema(description = "项目编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "SJ24001") + @ExcelProperty("项目编号") + private String projectCode; + + @Schema(description = "合同名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "规划一路道路工程勘察设计合同") + @ExcelProperty("合同名称") + private String contractName; + + @Schema(description = "签订合同总额", requiredMode = Schema.RequiredMode.REQUIRED, example = "80.0000") + @ExcelProperty("签订合同总额") + private BigDecimal signedAmount; + + @Schema(description = "包干/审定金额", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("包干/审定金额") + private BigDecimal approvedAmount; + + @Schema(description = "已完成设计阶段", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("已完成设计阶段") + private String completedDesignStage; + + @Schema(description = "应收款取数", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("应收款取数") + private BigDecimal receivableAccount; + + @Schema(description = "合同应收款", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("合同应收款") + private BigDecimal contractualReceivables; + + @Schema(description = "应收款差额", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("应收款差额") + private BigDecimal receivableDifference; + + @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED) private Long id; diff --git a/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/receivables/ReceivablesService.java b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/receivables/ReceivablesService.java index 408e30b7e..94e0ab438 100644 --- a/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/receivables/ReceivablesService.java +++ b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/receivables/ReceivablesService.java @@ -20,14 +20,14 @@ public interface ReceivablesService { * @param createReqVO 创建信息 * @return 编号 */ - Long createReceivables(@Valid ReceivablesSaveReqVO createReqVO); + Long createReceivables(Long loginUserId, @Valid ReceivablesSaveReqVO createReqVO); /** * 更新应收款管理 * * @param updateReqVO 更新信息 */ - void updateReceivables(@Valid ReceivablesSaveReqVO updateReqVO); + void updateReceivables(Long loginUserId, @Valid ReceivablesSaveReqVO updateReqVO); /** * 删除应收款管理 @@ -42,7 +42,7 @@ public interface ReceivablesService { * @param id 编号 * @return 应收款管理 */ - ReceivablesDO getReceivables(Long id); + ReceivablesRespVO getReceivables(Long id); /** * 获得应收款管理分页 @@ -50,6 +50,6 @@ public interface ReceivablesService { * @param pageReqVO 分页查询 * @return 应收款管理分页 */ - PageResult getReceivablesPage(ReceivablesPageReqVO pageReqVO); + PageResult getReceivablesPage(ReceivablesPageReqVO pageReqVO); } \ No newline at end of file diff --git a/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/receivables/ReceivablesServiceImpl.java b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/receivables/ReceivablesServiceImpl.java index 9873de254..61ba11e70 100644 --- a/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/receivables/ReceivablesServiceImpl.java +++ b/yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/receivables/ReceivablesServiceImpl.java @@ -1,21 +1,33 @@ package cn.iocoder.yudao.module.pms.service.receivables; +import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; +import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; +import cn.iocoder.yudao.module.cms.api.contract.ContractApi; +import cn.iocoder.yudao.module.cms.api.contract.dto.ContractRespDTO; +import cn.iocoder.yudao.module.pms.api.project.ProjectApi; +import cn.iocoder.yudao.module.pms.api.project.dto.ProjectRespDTO; +import cn.iocoder.yudao.module.pms.dal.dataobject.projectschedule.ProjectScheduleDO; +import cn.iocoder.yudao.module.pms.dal.dataobject.receivableshistory.ReceivablesHistoryDO; +import cn.iocoder.yudao.module.pms.dal.mysql.receivableshistory.ReceivablesHistoryMapper; +import cn.iocoder.yudao.module.pms.service.projectschedule.ProjectScheduleService; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import org.springframework.stereotype.Service; import jakarta.annotation.Resource; import org.springframework.validation.annotation.Validated; -import org.springframework.transaction.annotation.Transactional; +import java.math.BigDecimal; import java.util.*; import cn.iocoder.yudao.module.pms.controller.admin.receivables.vo.*; import cn.iocoder.yudao.module.pms.dal.dataobject.receivables.ReceivablesDO; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.pms.dal.mysql.receivables.ReceivablesMapper; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.cms.enums.ErrorCodeConstants.CONTRACT_NOT_EXISTS; import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS; /** * 应收款管理 Service 实现类 @@ -26,27 +38,157 @@ import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstants.*; @Validated public class ReceivablesServiceImpl implements ReceivablesService { + /** + * 应收款管理流程定义 + */ + public static final String PROCESS_KEY = "receivables_init"; + + /** + * 版本 + */ + public static String VERSION = "1"; + + @Resource + private ProjectApi projectApi; + + @Resource + private ContractApi contractApi; + + @Resource + private ProjectScheduleService projectScheduleService; + + @Resource + private AdminUserApi adminUserApi; + + @Resource + private BpmProcessInstanceApi processInstanceApi; + @Resource private ReceivablesMapper receivablesMapper; + @Resource + private ReceivablesHistoryMapper receivablesHistoryMapper; + @Override - public Long createReceivables(ReceivablesSaveReqVO createReqVO) { + public Long createReceivables(Long loginUserId, ReceivablesSaveReqVO createReqVO) { + + // 校验 用户是否存在 + if (loginUserId == null) { + throw exception(PARAM_NOT_EXISTS); + } + if (createReqVO == null) { + throw exception(PARAM_NOT_EXISTS); + } + String userName = adminUserApi.getUser(loginUserId).getNickname(); + if (userName == null) { + throw exception(USER_NOT_EXISTS); + } + // 校验 对应项目汉语合同是否存在 + Long projectId = createReqVO.getProjectId(); + Long contractId = createReqVO.getContractId(); + projectApi.validProjectExist(projectId); + contractApi.vaildContractExist(contractId); + + // 获取实例 + ContractRespDTO contract = contractApi.getContract(contractId); + ProjectRespDTO project = projectApi.getProject(projectId); + ProjectScheduleDO projectSchedule = projectScheduleService.getProjectSchedule(projectId); + + // 检验联表的字段是否与联系表的字段相同 + + /** + * 1. 项目编号 + * 2. 合同名称 + * 3. 签订合同总额 + * 4. 包干/审定金额 + * 5. 已完成设计阶段 + */ + + String projectCode = createReqVO.getProjectCode(); + String contractName = createReqVO.getContractName(); + BigDecimal signedAmount = createReqVO.getSignedAmount(); + BigDecimal approvedAmount = createReqVO.getApprovedAmount(); + String completedDesignStage = createReqVO.getCompletedDesignStage(); + + if (!project.getCode().equals(projectCode)) { + throw exception(PARAM_ERROR); + } + if (!contract.getName().equals(contractName)) { + throw exception(PARAM_ERROR); + } + if (!Objects.equals(contract.getAmount(),signedAmount)) { + throw exception(PARAM_ERROR); + } + if (!Objects.equals(contract.getApprovedAmount(), approvedAmount)) { + throw exception(PARAM_ERROR); + } + if (!projectSchedule.getStage().equals(completedDesignStage)) { + throw exception(PARAM_ERROR); + } + // 插入 ReceivablesDO receivables = BeanUtils.toBean(createReqVO, ReceivablesDO.class); + ReceivablesRespVO receivablesResp = BeanUtils.toBean(receivables, ReceivablesRespVO.class); + receivables.setCreator(userName); + receivables.setUpdater(userName); + + // 判断应收款是否已存在 + // 获得所有应收款后,逐个比较各个字段是否完全一致 + // 查receivables通过pms项目id查 + List receivablesDOList = receivablesMapper.selectList("project_id", projectId); + List receivablesRespVOList = BeanUtils.toBean(receivablesDOList, ReceivablesRespVO.class); + for (ReceivablesRespVO respVO : receivablesRespVOList) { + if (respVO.equals(receivablesResp)) { + throw exception(RECEIVABLES_ALREADY_EXISTS); + } + } + // 插入应收款 receivablesMapper.insert(receivables); + + // 启动流程,同时写入历史应收款 + Long receivablesId = receivables.getId(); + ReceivablesHistoryDO receivablesHistory = BeanUtils.toBean(receivables, ReceivablesHistoryDO.class); + if (createReqVO.getId() == null) { + String processInstanceId = processInstanceApi.createProcessInstance(loginUserId, + new BpmProcessInstanceCreateReqDTO() + .setProcessDefinitionKey(PROCESS_KEY).setBusinessKey(String.valueOf(receivablesId))); + + // 写入工作流编号 + receivablesHistory.setProcessInstanceId(processInstanceId); + receivablesHistory.setReceivableId(receivablesId); + + Long count = receivablesHistoryMapper.selectCount("project_id", projectId); + if (count < 1) { + receivablesHistory.setVersion(VERSION); + } else { + receivablesHistory.setVersion(String.valueOf(count+1)); + } + receivablesHistory.setProcessStatus("0"); + receivablesHistoryMapper.insert(receivablesHistory); + } + // 返回 return receivables.getId(); } @Override - public void updateReceivables(ReceivablesSaveReqVO updateReqVO) { + public void updateReceivables(Long loginUserId, ReceivablesSaveReqVO updateReqVO) { // 校验存在 validateReceivablesExists(updateReqVO.getId()); + projectApi.validProjectExist(updateReqVO.getProjectId()); + contractApi.vaildContractExist(updateReqVO.getContractId()); + // 更新 ReceivablesDO updateObj = BeanUtils.toBean(updateReqVO, ReceivablesDO.class); + String userName = adminUserApi.getUser(loginUserId).getNickname(); + if (userName == null) { + throw exception(USER_NOT_EXISTS); + } + updateObj.setUpdater(userName); receivablesMapper.updateById(updateObj); } + @Override public void deleteReceivables(Long id) { // 校验存在 @@ -62,13 +204,134 @@ public class ReceivablesServiceImpl implements ReceivablesService { } @Override - public ReceivablesDO getReceivables(Long id) { - return receivablesMapper.selectById(id); + public ReceivablesRespVO getReceivables(Long id) { + + // 校验 + if (id == null) { + throw exception(RECEIVABLES_NOT_EXISTS); + } + ReceivablesDO receivablesDO = receivablesMapper.selectById(id); + if (receivablesDO == null) { + throw exception(RECEIVABLES_NOT_EXISTS); + } + + Long projectId = receivablesDO.getProjectId(); + if (projectId == null) { + throw exception(RECEIVABLES_NOT_EXISTS); + } + Long contractId = receivablesDO.getContractId(); + if (contractId == null) { + throw exception(RECEIVABLES_NOT_EXISTS); + } + + ReceivablesRespVO receivablesRespVO = BeanUtils.toBean(receivablesDO, ReceivablesRespVO.class); + + /** + * 1. 项目编号 √ + * 2. 合同名称 √ + * 3. 签订合同总额 √ + * 4. 包干/审定金额 √ + * 5. 已完成设计阶段 √ + * 6. 应收款取数 √ + * 7. 合同应收款 √ + * 8. 应收款差额 √ + */ + + ProjectRespDTO project = projectApi.getProject(projectId); + ContractRespDTO contract = contractApi.getContract(contractId); + ProjectScheduleDO projectSchedule = projectScheduleService.getProjectSchedule(projectId); + + receivablesRespVO.setProjectCode(project.getCode()); // 项目编号 + receivablesRespVO.setContractName(contract.getName()); // 合同名称 + receivablesRespVO.setSignedAmount(contract.getAmount()); // 签订合同总额 + receivablesRespVO.setApprovedAmount(contract.getApprovedAmount()); // 包干/审定金额 + receivablesRespVO.setCompletedDesignStage(projectSchedule.getStage()); // 已完成设计阶段 + + BigDecimal receivableAccount = (contract.getApprovedAmount() == null) ? contract.getAmount() : contract.getApprovedAmount(); + receivablesRespVO.setReceivableAccount(receivableAccount); // 应收款取数 + + if (receivableAccount == null) { + throw exception(RECEIVABLES_CALCULATION_ERROR); + } + + // 根据设计阶段计算合同应收款 + BigDecimal amount = BigDecimal.ZERO; + BigDecimal planStage = parseRate(receivablesDO.getPlanStage()); // 方案阶段收款比例 + BigDecimal initialDesignStage = parseRate(receivablesDO.getInitialDesignStage()); // 初设阶段收款比例 + BigDecimal constructionDrawingStage = parseRate(receivablesDO.getConstructionDrawingStage()); // 施工图阶段比例 + BigDecimal constructionStage = parseRate(receivablesDO.getConstructionStage()); // 施工配合收款比例 + BigDecimal approveStage = parseRate(receivablesDO.getApproveStage()); // 审定阶段 + + switch (projectSchedule.getStage()) { + case "方案设计": + amount = receivableAccount.multiply(planStage); + break; + case "初步设计": + amount = receivableAccount.multiply(initialDesignStage); + break; + case "施工图": + amount = receivableAccount.multiply(constructionDrawingStage); + break; + case "施工配合": + amount = receivableAccount.multiply(constructionStage); + break; + case "竣工": + amount = receivableAccount.multiply(approveStage); + break; + default: + amount = BigDecimal.ZERO; + break; + } + receivablesRespVO.setContractualReceivables(amount); // 合同应收款 + + BigDecimal collectionAmount = parseRate(receivablesDO.getCollectionSituation()); + BigDecimal differenceAmount = amount.subtract(collectionAmount); + receivablesRespVO.setReceivableDifference(differenceAmount); // 应收款差额 + + return receivablesRespVO; } @Override - public PageResult getReceivablesPage(ReceivablesPageReqVO pageReqVO) { - return receivablesMapper.selectPage(pageReqVO); + public PageResult getReceivablesPage(ReceivablesPageReqVO pageReqVO) { + // 校验 + if (pageReqVO == null) { + throw exception(PARAM_NOT_EXISTS); + } + Long projectId = pageReqVO.getProjectId(); + ProjectRespDTO project = projectApi.getProject(projectId); + Long contractId = pageReqVO.getContractId(); + ContractRespDTO contract = contractApi.getContract(contractId); + if (project == null) { + throw exception(PROJECT_NOT_EXISTS); + } + if (contract == null) { + throw exception(CONTRACT_NOT_EXISTS); + } + + PageResult receivablesDOPageResult = receivablesMapper.selectPage(pageReqVO); + List receivablesDOList = receivablesDOPageResult.getList(); + List receivablesRespVOList = new ArrayList<>(); + + for (ReceivablesDO receivablesDO : receivablesDOList) { + Long id = receivablesDO.getId(); + ReceivablesRespVO receivables = getReceivables(id); + receivablesRespVOList.add(receivables); + } + + PageResult pageResult = new PageResult<>(); + pageResult.setList(receivablesRespVOList); + + return pageResult; + } + + private BigDecimal parseRate(String rateStr) { + // 将字符串转换为 BigDecimal,处理可能的 null 和格式错误 + try { + return (rateStr == null || rateStr.trim().isEmpty()) ? BigDecimal.ZERO : new BigDecimal(rateStr); + } catch (NumberFormatException e) { + // 如果字符串格式错误,返回零 + return BigDecimal.ZERO; + } } } \ No newline at end of file