using BBWY.Common.Models; using BBWY.Server.Model; using BBWY.Server.Model.Db; using BBWY.Server.Model.Db.Mds; using BBWY.Server.Model.Dto; using System; using System.Collections.Generic; using System.Linq; using Yitter.IdGenerator; namespace BBWY.Server.Business { public class StatisticsBusiness : BaseBusiness, IDenpendency { private IList invalidOrderStateList; private FreeSqlMultiDBManager freeSqlMultiDBManager; public StatisticsBusiness(IFreeSql fsql, NLogManager nLogManager, IIdGenerator idGenerator, FreeSqlMultiDBManager freeSqlMultiDBManager, IEnumerable platformSDKBusinessList) : base(fsql, nLogManager, idGenerator, platformSDKBusinessList) { invalidOrderStateList = new List() { Enums.OrderState.待付款, Enums.OrderState.已取消 }; this.freeSqlMultiDBManager = freeSqlMultiDBManager; } public OrderAchievementResponse GetOrderAchievementStatistics(OrderAchievementRequest request) { request.EndTime = request.EndTime.Date.AddDays(1).AddSeconds(-1); var response = fsql.Select().LeftJoin((o, oc) => o.Id == oc.OrderId) .Where((o, oc) => o.ShopId == request.ShopId && o.OrderState != null && !invalidOrderStateList.Contains(o.OrderState.Value) && //排除待付款和取消 o.StorageType != Enums.StorageType.SD && o.StartTime >= request.StartTime && o.StartTime <= request.EndTime) .ToAggregate((o, oc) => new OrderAchievementResponse() { OrderCount = o.Count(), //Profit = oc.Sum(oc.Key.Profit), SaleAmount = o.Sum(o.Key.OrderPayment), DeliveryExpressFreight = oc.Sum(oc.Key.DeliveryExpressFreight), PlatformCommissionAmount = oc.Sum(oc.Key.PlatformCommissionAmount), PurchaseAmount = oc.Sum(oc.Key.PurchaseAmount) }); var shopPopularizeList = fsql.Select().Where(s => s.ShopId == request.ShopId && s.Date >= request.StartTime && s.Date <= request.EndTime).ToList(); //最后一次推广花费时间 var pularizeEndDate = shopPopularizeList.Count > 0 ? shopPopularizeList.Max(s => s.Date) : null; var pularizeEndTime = pularizeEndDate?.AddDays(1).AddSeconds(-1); if (pularizeEndTime != null) { //o.StorageType != Enums.StorageType.SD && response.PularizeEndDate = pularizeEndDate; var profitList = fsql.Select().LeftJoin((o, oc) => o.Id == oc.OrderId) .Where((o, oc) => o.ShopId == request.ShopId && o.OrderState != null && !invalidOrderStateList.Contains(o.OrderState.Value) && //排除待付款和取消 o.StartTime >= request.StartTime && o.StartTime <= pularizeEndTime) .GroupBy((o, oc) => new { IsSD = o.StorageType != null && o.StorageType == Enums.StorageType.SD }) .ToList(g => new { g.Key.IsSD, Value = g.Sum(g.Value.Item2.Profit) }); var profit = profitList.FirstOrDefault(t => !t.IsSD)?.Value ?? 0M; var sdCost = profitList.FirstOrDefault(t => t.IsSD)?.Value ?? 0M; response.SDCost = Math.Abs(sdCost); response.AdvCost = shopPopularizeList.Sum(s => s.Cost) + response.SDCost; response.Profit = profit - response.AdvCost - response.TaxCost - response.EmployeeCost; response.ShoppopularizeList = shopPopularizeList.GroupBy(s => s.ItemName).Select(g => new Shoppopularize() { ShopId = request.ShopId, Cost = g.Sum(s => s.Cost), ItemName = g.Key }).ToList(); } response.ShopId = request.ShopId; return response; } public IList GetOrderAchievementStatisticsList(AllShopOrderAchievementRequest request) { var minTime = DateTime.Parse("2022-05-01"); if (request.StartTime < minTime) request.StartTime = minTime; request.EndTime = request.EndTime.Date.AddDays(1).AddSeconds(-1); List list = new List(); var shopPularizeGroups = fsql.Select().Where(s => s.Date >= request.StartTime && s.Date <= request.EndTime) .GroupBy(s => s.ShopId) .ToList(g => new { ShopId = g.Key, MinDate = g.Min(g.Value.Date), MaxDate = g.Max(g.Value.Date), Cost = g.Sum(g.Value.Cost) }); var shopPularizeDateGroups = shopPularizeGroups.GroupBy(g => new { g.MinDate, g.MaxDate }).ToList(); foreach (var dateGroup in shopPularizeDateGroups) { var minDate = dateGroup.Key.MinDate; var maxDate = dateGroup.Key.MaxDate.Value.Date.AddDays(1).AddSeconds(-1); var shopIds = dateGroup.Select(g => g.ShopId).ToList(); var responseList = fsql.Select().LeftJoin((o, oc) => o.Id == oc.OrderId) .Where((o, oc) => o.OrderState != null && !invalidOrderStateList.Contains(o.OrderState.Value) && //排除待付款和取消 o.StartTime >= minDate && o.StartTime <= maxDate && shopIds.Contains(o.ShopId)) .GroupBy((o, oc) => o.ShopId) .ToList((g) => new OrderAchievementResponse() { ShopId = g.Key, Profit = g.Sum(g.Value.Item2.Profit) }); foreach (var r in responseList) { var shopPularize = shopPularizeGroups.FirstOrDefault(s => s.ShopId == r.ShopId); if (shopPularize != null) r.Profit -= shopPularize.Cost; } list.AddRange(responseList); } return list; } private void XingXiangCumulative(IList detailList, string spuId, bool isSD, decimal profit, decimal sdProductAmount, decimal sdCost) { var xxRespose = detailList.FirstOrDefault(xx => xx.Spu == spuId); if (xxRespose == null) { xxRespose = new XingXiangItemResponse() { Spu = spuId, Profit = 0M }; detailList.Add(xxRespose); } xxRespose.Profit += profit; if (isSD) { xxRespose.SDOrderCount++; xxRespose.SDOrderAmount += sdProductAmount; xxRespose.SDOrderCost += sdCost; } } public XingXinagSearchResponse XingXiangStatistics(XingXiangSearchOrderRequest xingXiangSearchOrderRequest) { var mdsShop = freeSqlMultiDBManager.MDSfsql.Select().Where(s => s.ShopId == xingXiangSearchOrderRequest.ShopId.ToString()).ToOne(); var platformCommissionRatio = mdsShop.PlatformCommissionRatio ?? 0.05M; var beginTime = xingXiangSearchOrderRequest.SearchDate.Date; var endTime = xingXiangSearchOrderRequest.SearchDate.Date.AddDays(1).AddSeconds(-1); IList detailList = null; //查询订单 var orderList = fsql.Select().InnerJoin((o, oc) => o.Id == oc.OrderId) .Where((o, oc) => o.ShopId == xingXiangSearchOrderRequest.ShopId) .Where((o, oc) => o.StartTime >= beginTime && o.StartTime <= endTime) .Where((o, oc) => !invalidOrderStateList.Contains(o.OrderState.Value)) .OrderByDescending((o, oc) => o.StartTime) .ToList((o, oc) => new Order() { Id = o.Id, //FreightPrice = o.FreightPrice, OrderState = o.OrderState, OrderTotalPrice = o.OrderTotalPrice, StartTime = o.StartTime, StorageType = o.StorageType, ShopId = o.ShopId, //SDCommissionAmount = oc.SDCommissionAmount, //DeliveryExpressFreight = oc.DeliveryExpressFreight, //PreferentialAmount = oc.PreferentialAmount, OrderSellerPrice = o.OrderSellerPrice, //SellerPreferentialAmount = o.SellerPreferentialAmount, Profit = oc.Profit }); if (orderList.Count() == 0) return null; var orderIdList = orderList.Select(o => o.Id).ToList(); //查询orderSku var orderSkuList = fsql.Select().Where(osku => osku.Price != 0 && orderIdList.Contains(osku.OrderId)).ToList(); //查询成本明细 var orderCostDetailList = fsql.Select().Where(ocd => orderIdList.Contains(ocd.OrderId) && ocd.IsEnabled == true).ToList(); detailList = new List(); foreach (var order in orderList) { var currentOrderSkuList = orderSkuList.Where(osku => osku.OrderId == order.Id).ToList(); if (order.StorageType == Enums.StorageType.SD) { XingXiangCumulative(detailList, currentOrderSkuList[0].ProductId, true, order.Profit ?? 0M, order.OrderSellerPrice, Math.Abs(order.Profit ?? 0M)); continue; } var currentOrderCostDetailList = orderCostDetailList.Where(ocd => ocd.OrderId == order.Id); var spuGroups = currentOrderSkuList.GroupBy(osku => osku.ProductId); var tempOrderProdcutAmount = currentOrderSkuList.Sum(osku => osku.ItemTotal * osku.Price) ?? 0M; var tempOrderCost = currentOrderCostDetailList.Count() > 0 ? currentOrderCostDetailList.Sum(ocd => ocd.TotalCost) : 0M; var tempOrderProfit = tempOrderProdcutAmount - tempOrderCost; foreach (var spuGroup in spuGroups) { var currentSpuCostDetailList = currentOrderCostDetailList.Where(ocd => ocd.ProductId == spuGroup.Key); var tempSpuProductAmount = spuGroup.Sum(osku => osku.Price * osku.ItemTotal) ?? 0M; var tempSpuCost = currentSpuCostDetailList.Count() > 0 ? currentSpuCostDetailList.Sum(ocd => ocd.TotalCost) : 0M; var tempSpuProfit = tempSpuProductAmount - tempSpuCost; var spuProfitPercent = tempOrderProfit == 0M ? 0M : tempSpuProfit / tempOrderProfit; var realSpuProfit = (order.Profit ?? 0M) * spuProfitPercent; XingXiangCumulative(detailList, spuGroup.Key, false, realSpuProfit, 0, 0); } //foreach (var group in spuGroups) //{ // var spuId = group.Key; // var profit = 0M; // var sdCost = 0M; // var prodcutAmount = group.Sum(osku => osku.Price * osku.ItemTotal) ?? 0; //货款 // var skuSellerPreferentialAmount = order.SellerPreferentialAmount / skuCount * group.Count(); //该SPU分摊的商家优惠金额 // prodcutAmount -= skuSellerPreferentialAmount; // var commissionAmount = prodcutAmount * platformCommissionRatio; //该SPU的平台扣点金额 // var freightPriceByUser = order.FreightPrice == 0 ? 0 : order.FreightPrice / skuCount * group.Count(); //该SPU分摊的用户承担运费 // var currentOrderCostDetailList = orderCostDetailList.Where(ocd => ocd.OrderId == order.Id && ocd.ProductId == spuId).ToList(); // var purchaseAmount = currentOrderCostDetailList.Count() > 0 ? currentOrderCostDetailList.Sum(ocd => ocd.TotalCost) : 0; // var deliveryFreight = currentOrderCostDetailList.Count() > 0 ? currentOrderCostDetailList.Sum(ocd => ocd.DeliveryExpressFreight) : 0; // if (order.StorageType != Enums.StorageType.SD) // { // profit = prodcutAmount + freightPriceByUser - purchaseAmount - deliveryFreight - commissionAmount; // } // else // { // var sdCommissionAmount = order.SDCommissionAmount.Value / skuCount * group.Count(); // profit = 0; // sdCost = sdCommissionAmount + commissionAmount + order.DeliveryExpressFreight ?? 0M; // totalSDOrderCost += sdCost; // } // var xxRespose = detailList.FirstOrDefault(xx => xx.Spu == spuId); // if (xxRespose == null) // { // xxRespose = new XingXiangItemResponse() { Spu = spuId, Profit = 0M }; // detailList.Add(xxRespose); // } // xxRespose.Profit += profit; // if (order.StorageType == Enums.StorageType.SD) // { // xxRespose.SDOrderCount++; // xxRespose.SDOrderAmount += prodcutAmount; // xxRespose.SDOrderCost += sdCost; // } //} } var sdOrderList = orderList.Where(o => o.StorageType == Enums.StorageType.SD); return new XingXinagSearchResponse() { ItemList = detailList, TotalSDOrderAmount = detailList.Sum(xx => xx.SDOrderAmount), TotalSDOrderCount = sdOrderList.Count(), TotalSDOrderCost = detailList.Sum(xx => xx.SDOrderCost), TotalProfit = detailList.Sum(xx => xx.Profit) }; } /// /// bbwy订单选项卡数量统计 /// /// /// /// /// public OrderCountStatisticsResponse GetOrderCountStatistics(long shopId) { //startDate = startDate.Date; //endDate = endDate.Date.AddDays(1).AddSeconds(-1); var dt = DateTime.Parse("2022-05-01"); var afterDt = DateTime.Parse("2022-10-01"); var response = new OrderCountStatisticsResponse(); response.WaitPurchaseCount = fsql.Select().Where(o => o.ShopId == shopId && o.OrderState == Enums.OrderState.等待采购 && o.StartTime >= dt).Count(); response.ExceptionCount = fsql.Select().LeftJoin((o, oc) => o.Id == oc.OrderId) .Where((o, oc) => o.ShopId == shopId && o.StartTime >= dt && o.IsGift == false && o.OrderState != Enums.OrderState.已取消 && ((o.StorageType != Enums.StorageType.SD && o.StorageType != null && oc.PurchaseAmount == 0M) || (o.StorageType != Enums.StorageType.SD && oc.PurchaseAmount + oc.DeliveryExpressFreight > o.OrderSellerPrice + o.FreightPrice) || (o.StorageType == null && o.OrderState != Enums.OrderState.等待采购))).Count(); response.WaitOutStoreCount = fsql.Select().Where(o => o.ShopId == shopId && o.OrderState == Enums.OrderState.待出库 && o.StartTime >= dt).Count(); response.AfterSaleOrderUnhandleCount = fsql.Select().Where(aso => aso.ShopId == shopId && (aso.ProductHealth == null || aso.ProductResult == null) && aso.CreateTime >= afterDt).Count(); return response; } /// /// SD组个人统计 /// /// /// /// /// public SDGroupPersonStatisticsResponse GetSDGroupPersonStatistics(string sdOperator, DateTime startDate, DateTime endDate) { endDate = endDate.Date.AddDays(1).AddSeconds(-1); return fsql.Select().Where(o => o.StorageType == Enums.StorageType.SD && o.SDOperator == sdOperator && o.StartTime >= startDate && o.StartTime <= endDate).ToAggregate(g => new SDGroupPersonStatisticsResponse { MySDCount = g.Count(), OrderPayment = g.Sum(g.Key.OrderPayment) }); } /// /// 查询sku最近销量 /// /// /// public IList GetSkuRecentSales(SkuRecentSalesRequest skuRecentSalesRequest) { var endTime = DateTime.Now; var startDate = DateTime.Now.Date.AddMonths(-1); var list = fsql.Select().WhereIf(skuRecentSalesRequest.SkuIds.Count() == 1, osku => osku.SkuId == skuRecentSalesRequest.SkuIds[0]) .WhereIf(skuRecentSalesRequest.SkuIds.Count() > 1, osku => skuRecentSalesRequest.SkuIds.Contains(osku.SkuId)) .Where(osku => osku.CreateTime >= startDate && osku.CreateTime <= endTime) .GroupBy(osku => osku.SkuId) .ToList(g => new SkuRecentSaleResponse() { SkuId = g.Key, SaleCount = g.Sum(g.Value.ItemTotal.Value) }); return list; } } }