package cn.iocoder.yudao.module.erp.service.statistics; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.crm.api.customer.CrmCustomerApi; import cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO; import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.sale.ErpSaleCustomerSummaryRespVO; import cn.iocoder.yudao.module.erp.controller.admin.statistics.vo.sale.ErpSaleProductSummaryRespVO; import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleCustomerReceiptStatisticsDO; import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleCustomerStatisticsDO; import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleProductStatisticsDO; import cn.iocoder.yudao.module.erp.dal.mysql.statistics.ErpSaleStatisticsMapper; import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * ERP 销售统计 Service 实现类 * * @author 超级管理员 */ @Service public class ErpSaleStatisticsServiceImpl implements ErpSaleStatisticsService { @Resource private ErpSaleStatisticsMapper saleStatisticsMapper; @Resource private CrmCustomerApi customerApi; @Resource private MdmItemApi mdmItemApi; @Override public BigDecimal getSalePrice(LocalDateTime beginTime, LocalDateTime endTime) { return saleStatisticsMapper.getSalePrice(beginTime, endTime); } @Override public List getCustomerSummary(Long customerId, LocalDateTime beginTime, LocalDateTime endTime) { List saleList = saleStatisticsMapper.selectCustomerStatistics(customerId, beginTime, endTime); if (CollectionUtils.isAnyEmpty(saleList)) { return new ArrayList<>(); } // 1. 已收款金额按客户归集(收款单可能早于/晚于订单,不做订单级勾稽,只按客户汇总) Map receiptMap = CollectionUtils.convertMap( saleStatisticsMapper.selectCustomerReceiptStatistics(customerId, beginTime, endTime), ErpSaleCustomerReceiptStatisticsDO::getCustomerId, ErpSaleCustomerReceiptStatisticsDO::getReceiptAmount); // 2. 客户名称 Map customerMap = customerApi.getCustomerMap( CollectionUtils.convertSet(saleList, ErpSaleCustomerStatisticsDO::getCustomerId)); // 3. 组装 List result = new ArrayList<>(saleList.size()); for (ErpSaleCustomerStatisticsDO sale : saleList) { BigDecimal saleAmount = sale.getSaleAmount() == null ? BigDecimal.ZERO : sale.getSaleAmount(); BigDecimal receiptAmount = receiptMap.getOrDefault(sale.getCustomerId(), BigDecimal.ZERO); CrmCustomerRespDTO customer = customerMap.get(sale.getCustomerId()); ErpSaleCustomerSummaryRespVO vo = new ErpSaleCustomerSummaryRespVO(); vo.setCustomerId(sale.getCustomerId()); vo.setCustomerName(customer != null ? customer.getName() : "客户(" + sale.getCustomerId() + ")"); vo.setOrderCount(sale.getOrderCount()); vo.setSaleAmount(saleAmount); vo.setReceiptAmount(receiptAmount); vo.setUnreceivedAmount(saleAmount.subtract(receiptAmount)); vo.setLastOrderTime(sale.getLastOrderTime()); result.add(vo); } return result; } @Override public List getProductSummary(Long productId, LocalDateTime beginTime, LocalDateTime endTime) { List saleList = saleStatisticsMapper.selectProductStatistics(productId, beginTime, endTime); if (CollectionUtils.isAnyEmpty(saleList)) { return new ArrayList<>(); } // 1. 产品名称与参考成本价 Map itemMap = mdmItemApi.getItemMap( CollectionUtils.convertSet(saleList, ErpSaleProductStatisticsDO::getProductId)); // 2. 组装,毛利 = 销售金额 - 数量 × 参考成本价 List result = new ArrayList<>(saleList.size()); for (ErpSaleProductStatisticsDO sale : saleList) { MdmItemRespDTO item = itemMap.get(sale.getProductId()); BigDecimal saleAmount = sale.getSaleAmount() == null ? BigDecimal.ZERO : sale.getSaleAmount(); BigDecimal costPrice = item != null && item.getCostPrice() != null ? item.getCostPrice() : BigDecimal.ZERO; BigDecimal totalCount = sale.getTotalCount() == null ? BigDecimal.ZERO : sale.getTotalCount(); BigDecimal costAmount = costPrice.multiply(totalCount); ErpSaleProductSummaryRespVO vo = new ErpSaleProductSummaryRespVO(); vo.setProductId(sale.getProductId()); vo.setProductName(item != null ? item.getName() : "产品(" + sale.getProductId() + ")"); vo.setOrderCount(sale.getOrderCount()); vo.setTotalCount(totalCount); vo.setSaleAmount(saleAmount); vo.setCostAmount(costAmount); vo.setProfitAmount(saleAmount.subtract(costAmount)); result.add(vo); } return result; } }