liu
3 天以前 8ad99e5f72085d14fd56e8faa7aa36701823c8b5
yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/invoice/CrmInvoiceServiceImpl.java
@@ -102,9 +102,7 @@
    @LogRecord(type = CRM_INVOICE_TYPE, subType = CRM_INVOICE_CREATE_SUB_TYPE, bizNo = "{{#invoice.id}}",
            success = CRM_INVOICE_CREATE_SUCCESS)
    public Long createInvoice(CrmInvoiceSaveReqVO createReqVO) {
        // 1.1 校验可开票金额超过上限
        validateInvoicePriceExceedsLimit(createReqVO);
        // 1.2 校验关联数据存在
        // 1.1 校验关联数据存在(开票金额不再受合同金额限制,仅前端提示可开票金额)
        validateRelationDataExists(createReqVO);
        // 1.3 生成开票编号
        String no = noRedisDAO.generate(CrmNoRedisDAO.INVOICE_PREFIX);
@@ -132,22 +130,6 @@
        return invoice.getId();
    }
    private void validateInvoicePriceExceedsLimit(CrmInvoiceSaveReqVO reqVO) {
        // 1. 计算剩余可开票金额,不包括 reqVO 自身(审批中也占用额度,防止累计开票超过合同金额)
        CrmContractDO contract = contractService.validateContract(reqVO.getContractId());
        List<CrmInvoiceDO> invoices = invoiceMapper.selectListByContractIdAndStatus(reqVO.getContractId(),
                List.of(CrmAuditStatusEnum.APPROVE.getStatus(), CrmAuditStatusEnum.PROCESS.getStatus()));
        if (reqVO.getId() != null) {
            invoices.removeIf(invoice -> ObjectUtil.equal(invoice.getId(), reqVO.getId()));
        }
        BigDecimal notInvoicePrice = contract.getTotalPrice().subtract(
                CollectionUtils.getSumValue(invoices, CrmInvoiceDO::getPrice, BigDecimal::add, BigDecimal.ZERO));
        // 2. 校验金额是否超过
        if (reqVO.getPrice().compareTo(notInvoicePrice) > 0) {
            throw exception(INVOICE_CREATE_FAIL_PRICE_EXCEEDS_LIMIT, notInvoicePrice);
        }
    }
    private void validateRelationDataExists(CrmInvoiceSaveReqVO reqVO) {
        if (reqVO.getOwnerUserId() != null) {
            adminUserApi.validateUser(reqVO.getOwnerUserId()); // 校验负责人存在
@@ -173,10 +155,7 @@
        CrmInvoiceDO oldInvoice = validateInvoiceExists(updateReqVO.getId());
        updateReqVO.setOwnerUserId(oldInvoice.getOwnerUserId()).setCustomerId(oldInvoice.getCustomerId())
                .setContractId(oldInvoice.getContractId()); // 设置已存在的值
        // 1.2 校验可开票金额超过上限
        validateInvoicePriceExceedsLimit(updateReqVO);
        // 1.3 只有草稿、审核不通过,可以编辑;
        // 1.2 只有草稿、审核不通过,可以编辑;
        if (!ObjectUtils.equalsAny(oldInvoice.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus(),
                CrmAuditStatusEnum.REJECT.getStatus())) {
            throw exception(INVOICE_UPDATE_FAIL_EDITING_PROHIBITED);
@@ -232,11 +211,7 @@
            throw exception(INVOICE_SUBMIT_FAIL_NOT_EDITABLE);
        }
        // 2. 重新校验可开票金额,防止累计开票超过合同金额(草稿期后可能有其他单进入审批中)
        validateInvoicePriceExceedsLimit(new CrmInvoiceSaveReqVO()
                .setId(invoice.getId()).setContractId(invoice.getContractId()).setPrice(invoice.getPrice()));
        // 3. 校验审批配置已启用且配置了有效审批人(未配置时抛出带明确提示的业务异常)
        // 2. 校验审批配置已启用且配置了有效审批人(未配置时抛出带明确提示的业务异常)
        approvalConfigApi.validateApprovalEnabledAndGetApprovers(INVOICE_APPROVE_BIZ_TYPE);
        // 4. 状态置为审批中,并清空上一轮审核结果,避免残留「审核不通过」的原因