| | |
| | | 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.invoice.CrmInvoiceDO; |
| | | import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum; |
| | | 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.invoice.CrmInvoiceService; |
| | | 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.storage.StorageAttachmentApi; |
| | | 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.enums.storage.StorageRecordTypeEnum; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.io.IOException; |
| | | import java.math.BigDecimal; |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | |
| | | private CrmContractService contractService; |
| | | @Resource |
| | | private CrmCustomerService customerService; |
| | | @Resource |
| | | private CrmReceivableService receivableService; |
| | | |
| | | @Resource |
| | | private AdminUserApi adminUserApi; |
| | |
| | | // 1.3 获得合同列表 |
| | | Map<Long, CrmContractDO> contractMap = contractService.getContractMap( |
| | | convertSet(invoiceList, CrmInvoiceDO::getContractId)); |
| | | // 1.4 获得每张开票已回款金额(草稿 + 审批中 + 审批通过) |
| | | Map<Long, BigDecimal> receivablePriceMap = receivableService.getReceivablePriceMapByInvoiceId( |
| | | convertSet(invoiceList, CrmInvoiceDO::getId)); |
| | | // 2. 拼接结果 |
| | | return BeanUtils.toBean(invoiceList, CrmInvoiceRespVO.class, (invoiceVO) -> { |
| | | // 2.1 拼接客户名称 |
| | |
| | | findAndThen(contractMap, invoiceVO.getContractId(), contract -> |
| | | invoiceVO.setContract(BeanUtils.toBean(contract, CrmContractRespVO.class))); |
| | | // 2.4 拼接发票附件 |
| | | invoiceVO.setAttachmentList(storageAttachmentApi.listAttachments("crm_invoice", invoiceVO.getId())); |
| | | invoiceVO.setAttachmentList(storageAttachmentApi.listAttachments( |
| | | StorageRecordTypeEnum.CRM_INVOICE.getType(), invoiceVO.getId())); |
| | | // 2.5 拼接是否已上传附件 |
| | | invoiceVO.setHasAttachment(CollUtil.isNotEmpty(invoiceVO.getAttachmentList())); |
| | | // 2.6 拼接剩余可回款金额 |
| | | invoiceVO.setRemainingInvoicePrice(invoiceVO.getPrice().subtract( |
| | | receivablePriceMap.getOrDefault(invoiceVO.getId(), BigDecimal.ZERO))); |
| | | }); |
| | | } |
| | | |
| | |
| | | return success(invoiceService.getAuditInvoiceCount(getLoginUserId())); |
| | | } |
| | | |
| | | @GetMapping("/simple-list") |
| | | @Operation(summary = "获得开票精简列表", description = "只包含审核通过且已上传发票附件的开票,主要用于回款创建时选择关联开票") |
| | | @Parameter(name = "contractId", description = "合同编号", required = true) |
| | | @PreAuthorize("@ss.hasPermission('crm:invoice:query')") |
| | | public CommonResult<List<CrmInvoiceRespVO>> getInvoiceSimpleList(@RequestParam("contractId") Long contractId) { |
| | | List<CrmInvoiceDO> invoices = invoiceService.getInvoiceListByContractIdAndStatus(contractId, |
| | | List.of(CrmAuditStatusEnum.APPROVE.getStatus())); |
| | | if (CollUtil.isEmpty(invoices)) { |
| | | return success(Collections.emptyList()); |
| | | } |
| | | // 过滤:已上传发票附件 |
| | | invoices.removeIf(invoice -> CollUtil.isEmpty(storageAttachmentApi.listAttachments( |
| | | StorageRecordTypeEnum.CRM_INVOICE.getType(), invoice.getId()))); |
| | | if (CollUtil.isEmpty(invoices)) { |
| | | return success(Collections.emptyList()); |
| | | } |
| | | // 计算每张开票已回款金额(草稿 + 审批中 + 审批通过,口径与创建回款校验一致) |
| | | Map<Long, BigDecimal> receivablePriceMap = receivableService.getReceivablePriceMapByInvoiceId( |
| | | convertSet(invoices, CrmInvoiceDO::getId)); |
| | | // 过滤:剩余可回款金额 > 0 才可选 |
| | | List<CrmInvoiceRespVO> result = new ArrayList<>(); |
| | | for (CrmInvoiceDO invoice : invoices) { |
| | | BigDecimal remainingPrice = invoice.getPrice() |
| | | .subtract(receivablePriceMap.getOrDefault(invoice.getId(), BigDecimal.ZERO)); |
| | | if (remainingPrice.compareTo(BigDecimal.ZERO) <= 0) { |
| | | continue; |
| | | } |
| | | result.add(new CrmInvoiceRespVO() // 只返回精简字段 |
| | | .setId(invoice.getId()).setNo(invoice.getNo()).setInvoiceNo(invoice.getInvoiceNo()) |
| | | .setInvoiceTitle(invoice.getInvoiceTitle()).setPrice(invoice.getPrice()) |
| | | .setCustomerId(invoice.getCustomerId()).setContractId(invoice.getContractId()) |
| | | .setAuditStatus(invoice.getAuditStatus()).setHasAttachment(true) |
| | | .setRemainingInvoicePrice(remainingPrice)); |
| | | } |
| | | return success(result); |
| | | } |
| | | |
| | | } |