gaoluyang
5 天以前 25a40b9c4e6a1b650610b8b13088d486699532ce
yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseInvoiceController.java
@@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.erp.controller.admin.purchase;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
@@ -9,11 +10,13 @@
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.invoice.ErpPurchaseInvoiceOrderRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.invoice.ErpPurchaseInvoicePageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.invoice.ErpPurchaseInvoiceRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.invoice.ErpPurchaseInvoiceSaveReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderRespVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInvoiceDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInvoiceOrderDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO;
import cn.iocoder.yudao.module.erp.service.finance.ErpFinancePaymentService;
import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseInvoiceService;
@@ -38,14 +41,17 @@
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
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.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
@@ -138,10 +144,33 @@
        Map<Long, SrmSupplierRespDTO> supplierMap = srmSupplierApi.getSupplierList(
                convertSet(invoiceList, ErpPurchaseInvoiceDO::getSupplierId)).getCheckedData().stream()
                .collect(java.util.stream.Collectors.toMap(SrmSupplierRespDTO::getId, v -> v, (a, b) -> a));
        // 1.2 获取采购订单列表
        // 1.2 获取采购订单分摊明细(一张来票可关联多张订单)
        Map<Long, List<ErpPurchaseInvoiceOrderDO>> allocationMap = convertMultiMap(
                invoiceService.getPurchaseInvoiceOrderListByInvoiceIds(
                        convertSet(invoiceList, ErpPurchaseInvoiceDO::getId)),
                ErpPurchaseInvoiceOrderDO::getInvoiceId);
        // 1.2.1 兼容历史数据:没有分摊明细的来票,按主订单 + 来票金额视为一条分摊
        for (ErpPurchaseInvoiceDO invoice : invoiceList) {
            if (!allocationMap.containsKey(invoice.getId()) && invoice.getPurchaseOrderId() != null) {
                allocationMap.put(invoice.getId(), Collections.singletonList(
                        ErpPurchaseInvoiceOrderDO.builder().invoiceId(invoice.getId())
                                .purchaseOrderId(invoice.getPurchaseOrderId()).price(invoice.getPrice()).sort(0).build()));
            }
        }
        // 1.2.2 这些订单的全部分摊明细,用于计算每张订单「其他来票已占用金额」
        Set<Long> orderIds = convertSet(allocationMap.values().stream().flatMap(List::stream).toList(),
                ErpPurchaseInvoiceOrderDO::getPurchaseOrderId);
        List<ErpPurchaseInvoiceOrderDO> orderAllocations = invoiceService.getPurchaseInvoiceOrderListByPurchaseOrderIds(orderIds);
        // 1.2.3 获取采购订单列表(含主订单,兼容历史数据)
        Set<Long> orderIdsAll = new HashSet<>(orderIds);
        invoiceList.stream().map(ErpPurchaseInvoiceDO::getPurchaseOrderId)
                .filter(java.util.Objects::nonNull).forEach(orderIdsAll::add);
        Map<Long, ErpPurchaseOrderDO> orderMap = convertMap(
                purchaseOrderService.getPurchaseOrderList(convertList(invoiceList, ErpPurchaseInvoiceDO::getPurchaseOrderId)),
                ErpPurchaseOrderDO::getId);
                purchaseOrderService.getPurchaseOrderList(new ArrayList<>(orderIdsAll)), ErpPurchaseOrderDO::getId);
        // 1.2.4 获取分摊订单的供应商列表(一张来票可能涉及多个供应商)
        Map<Long, SrmSupplierRespDTO> orderSupplierMap = srmSupplierApi.getSupplierList(
                        convertSet(orderMap.values(), ErpPurchaseOrderDO::getSupplierId)).getCheckedData().stream()
                .collect(java.util.stream.Collectors.toMap(SrmSupplierRespDTO::getId, v -> v, (a, b) -> a));
        // 1.3 获取创建人列表
        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
                convertSet(invoiceList, invoice -> NumberUtils.parseLong(invoice.getCreator())));
@@ -152,9 +181,37 @@
        return BeanUtils.toBean(invoiceList, ErpPurchaseInvoiceRespVO.class, (invoiceVO) -> {
            // 2.1 拼接供应商名称
            findAndThen(supplierMap, invoiceVO.getSupplierId(), supplier -> invoiceVO.setSupplierName(supplier.getName()));
            // 2.2 拼接采购订单信息
            // 2.2 拼接采购订单信息(主订单)
            findAndThen(orderMap, invoiceVO.getPurchaseOrderId(), order ->
                    invoiceVO.setOrder(BeanUtils.toBean(order, ErpPurchaseOrderRespVO.class)));
            // 2.2.1 拼接采购订单分摊明细
            List<ErpPurchaseInvoiceOrderDO> rows = allocationMap.getOrDefault(invoiceVO.getId(), Collections.emptyList());
            List<ErpPurchaseInvoiceOrderRespVO> allocationVOs = new ArrayList<>(rows.size());
            for (ErpPurchaseInvoiceOrderDO row : rows) {
                ErpPurchaseInvoiceOrderRespVO allocationVO = new ErpPurchaseInvoiceOrderRespVO()
                        .setPurchaseOrderId(row.getPurchaseOrderId()).setPrice(row.getPrice());
                ErpPurchaseOrderDO order = orderMap.get(row.getPurchaseOrderId());
                if (order != null) {
                    allocationVO.setOrderNo(order.getNo()).setSupplierId(order.getSupplierId())
                            .setOrderTotalPrice(order.getTotalPrice());
                    findAndThen(orderSupplierMap, order.getSupplierId(),
                            supplier -> allocationVO.setSupplierName(supplier.getName()));
                }
                // 该订单其他来票已占用金额 = 全部分摊 - 本张来票的分摊
                BigDecimal otherInvoicedPrice = orderAllocations.stream()
                        .filter(other -> ObjectUtil.equal(other.getPurchaseOrderId(), row.getPurchaseOrderId())
                                && !ObjectUtil.equal(other.getInvoiceId(), invoiceVO.getId()))
                        .map(ErpPurchaseInvoiceOrderDO::getPrice)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
                allocationVO.setInvoicedPrice(otherInvoicedPrice);
                if (order != null) {
                    allocationVO.setRemainPrice(order.getTotalPrice().subtract(otherInvoicedPrice));
                }
                allocationVOs.add(allocationVO);
            }
            invoiceVO.setOrderAllocations(allocationVOs);
            invoiceVO.setOrderCount(allocationVOs.size());
            invoiceVO.setOrderNos(CollUtil.join(allocationVOs, "、", ErpPurchaseInvoiceOrderRespVO::getOrderNo));
            // 2.3 拼接创建人名称
            MapUtils.findAndThen(userMap, NumberUtils.parseLong(invoiceVO.getCreator()),
                    user -> invoiceVO.setCreatorName(user.getNickname()));