gaoluyang
8 天以前 8e4eee5ad4d74e1a4e6ab4de3a9c28000700dce0
yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/statistics/ErpPurchaseStatisticsServiceImpl.java
@@ -1,11 +1,32 @@
package cn.iocoder.yudao.module.erp.service.statistics;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchasePriceAnalysisRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseStatisticsReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseSummaryRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseSupplierStatisticsRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.purchase.ErpPurchaseUncompletedOrderRespVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderItemDO;
import cn.iocoder.yudao.module.erp.dal.mysql.purchase.ErpPurchaseOrderItemMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.statistics.ErpPurchaseStatisticsMapper;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
/**
 * ERP 采购统计 Service 实现类
@@ -17,10 +38,97 @@
    @Resource
    private ErpPurchaseStatisticsMapper purchaseStatisticsMapper;
    @Resource
    private ErpPurchaseOrderItemMapper purchaseOrderItemMapper;
    @Resource
    private MdmItemApi mdmItemApi;
    @Override
    public BigDecimal getPurchasePrice(LocalDateTime beginTime, LocalDateTime endTime) {
        return purchaseStatisticsMapper.getPurchasePrice(beginTime, endTime);
    }
    @Override
    public ErpPurchaseSummaryRespVO getPurchaseSummary() {
        ErpPurchaseSummaryRespVO summary = purchaseStatisticsMapper.selectPurchaseSummary();
        return summary != null ? summary : new ErpPurchaseSummaryRespVO()
                .setTotalOrderCount(0L).setTotalOrderAmount(BigDecimal.ZERO)
                .setTotalInCount(0L).setTotalInAmount(BigDecimal.ZERO)
                .setTotalReturnCount(0L).setTotalReturnAmount(BigDecimal.ZERO);
    }
    @Override
    public PageResult<ErpPurchaseSupplierStatisticsRespVO> getSupplierStatistics(ErpPurchaseStatisticsReqVO reqVO) {
        Page<ErpPurchaseSupplierStatisticsRespVO> page = new Page<>(reqVO.getPageNo(), reqVO.getPageSize());
        purchaseStatisticsMapper.selectSupplierStatistics(page, reqVO);
        return new PageResult<>(page.getRecords(), page.getTotal());
    }
    @Override
    public PageResult<ErpPurchasePriceAnalysisRespVO> getPriceAnalysis(ErpPurchaseStatisticsReqVO reqVO) {
        Page<ErpPurchasePriceAnalysisRespVO> page = new Page<>(reqVO.getPageNo(), reqVO.getPageSize());
        purchaseStatisticsMapper.selectPriceAnalysis(page, reqVO);
        fillProductInfo(page.getRecords());
        return new PageResult<>(page.getRecords(), page.getTotal());
    }
    @Override
    public PageResult<ErpPurchaseUncompletedOrderRespVO> getUncompletedOrders(ErpPurchaseStatisticsReqVO reqVO) {
        Page<ErpPurchaseUncompletedOrderRespVO> page = new Page<>(reqVO.getPageNo(), reqVO.getPageSize());
        purchaseStatisticsMapper.selectUncompletedOrders(page, reqVO);
        fillUncompletedOrderInfo(page.getRecords());
        return new PageResult<>(page.getRecords(), page.getTotal());
    }
    /**
     * 补全产品名称、条码,并计算价格变化率
     */
    private void fillProductInfo(List<ErpPurchasePriceAnalysisRespVO> list) {
        if (CollUtil.isEmpty(list)) {
            return;
        }
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(list, ErpPurchasePriceAnalysisRespVO::getProductId));
        list.forEach(vo -> {
            MapUtils.findAndThen(itemMap, vo.getProductId(), item -> vo
                    .setProductName(item.getName()).setProductBarCode(item.getBarCode()));
            // 价格变化率 = (最近价格 - 平均价格) / 平均价格 × 100
            if (vo.getLatestPrice() == null || vo.getAvgPrice() == null
                    || vo.getAvgPrice().compareTo(BigDecimal.ZERO) == 0) {
                vo.setPriceChangeRate(BigDecimal.ZERO);
                return;
            }
            vo.setPriceChangeRate(vo.getLatestPrice().subtract(vo.getAvgPrice())
                    .multiply(BigDecimal.valueOf(100))
                    .divide(vo.getAvgPrice(), 2, RoundingMode.HALF_UP));
        });
    }
    /**
     * 补全产品名称,并计算未完成金额
     */
    private void fillUncompletedOrderInfo(List<ErpPurchaseUncompletedOrderRespVO> list) {
        if (CollUtil.isEmpty(list)) {
            return;
        }
        List<ErpPurchaseOrderItemDO> orderItems = purchaseOrderItemMapper.selectListByOrderIds(
                convertSet(list, ErpPurchaseUncompletedOrderRespVO::getOrderId));
        Map<Long, List<ErpPurchaseOrderItemDO>> orderItemMap = convertMultiMap(orderItems, ErpPurchaseOrderItemDO::getOrderId);
        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                convertSet(orderItems, ErpPurchaseOrderItemDO::getProductId));
        list.forEach(vo -> {
            List<ErpPurchaseOrderItemDO> items = orderItemMap.getOrDefault(vo.getOrderId(), Collections.emptyList());
            vo.setProductNames(items.stream()
                    .map(item -> {
                        MdmItemRespDTO mdmItem = itemMap.get(item.getProductId());
                        return mdmItem != null ? mdmItem.getName() : "ID=" + item.getProductId();
                    })
                    .distinct()
                    .collect(Collectors.joining(",")));
            BigDecimal orderAmount = vo.getOrderAmount() != null ? vo.getOrderAmount() : BigDecimal.ZERO;
            BigDecimal inAmount = vo.getInAmount() != null ? vo.getInAmount() : BigDecimal.ZERO;
            vo.setUncompletedAmount(orderAmount.subtract(inAmount));
        });
    }
}