using BBWY.Common.Http; 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 FreeSql; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http.Headers; using Yitter.IdGenerator; namespace BBWY.Server.Business { public class StatisticsBusiness : BaseBusiness, IDenpendency { private IList invalidOrderStateList; private FreeSqlMultiDBManager freeSqlMultiDBManager; private RestApiService restApiService; private List filterExceptionStateList; public StatisticsBusiness(IFreeSql fsql, NLogManager nLogManager, IIdGenerator idGenerator, FreeSqlMultiDBManager freeSqlMultiDBManager, RestApiService restApiService) : base(fsql, nLogManager, idGenerator) { invalidOrderStateList = new List() { Enums.OrderState.待付款, Enums.OrderState.已取消 }; this.freeSqlMultiDBManager = freeSqlMultiDBManager; this.restApiService = restApiService; filterExceptionStateList = new List() { Enums.OrderState.等待采购, Enums.OrderState.待付款, Enums.OrderState.已取消 }; } 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 actualAmount, decimal sdCost) { var xxRespose = detailList.FirstOrDefault(xx => xx.Spu == spuId); if (xxRespose == null) { xxRespose = new XingXiangItemResponse() { Spu = spuId, Profit = 0M, ActualAmount = 0M }; detailList.Add(xxRespose); } xxRespose.Profit += profit; xxRespose.ActualAmount += actualAmount; if (isSD) { xxRespose.SDOrderCount++; xxRespose.SDOrderAmount += actualAmount; 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, FreightPrice = o.FreightPrice, //SellerPreferentialAmount = o.SellerPreferentialAmount, Profit = oc.Profit }); if (orderList.Count() == 0) return null; var orderIdList = orderList.Select(o => o.Id).ToList(); 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(); //来自订单的spu var spuIdList = orderSkuList.Select(osku => osku.ProductId).Distinct().ToList(); List noOrderSpuIdList = null; //来自推广的spu { var skuIdList = fsql.Select() .Where(jas => jas.Date == xingXiangSearchOrderRequest.SearchDate && jas.ShopId == xingXiangSearchOrderRequest.ShopId) .Distinct().ToList(jas => jas.Sku); if (skuIdList.Count() > 0) { var productIdFromPopularizeList = fsql.Select(skuIdList).Distinct().ToList(ps => ps.ProductId); noOrderSpuIdList = productIdFromPopularizeList.Except(spuIdList).ToList(); if (noOrderSpuIdList.Count() > 0) spuIdList.AddRange(noOrderSpuIdList); } } List spuGoiList = null; GOIByShop shopGoi = null; #region spu goi { var httpResult = restApiService.SendRequest("http://snapi.qiyue666.com/", "Api/GOI/QueryPopularizeLevelGOIBySpuId", new { SpuIdList = spuIdList, StartTime = xingXiangSearchOrderRequest.SearchDate, EndTime = xingXiangSearchOrderRequest.SearchDate }, null, System.Net.Http.HttpMethod.Post); if (httpResult.StatusCode != System.Net.HttpStatusCode.OK) throw new BusinessException("查询spu goi失败"); var listRes = JsonConvert.DeserializeObject>>(httpResult.Content)?.Data; spuGoiList = listRes.ItemList; } #endregion #region shop goi { var httpResult = restApiService.SendRequest("http://snapi.qiyue666.com/", "Api/GOI/QueryPopularizeLevelGOIByShopId", new { xingXiangSearchOrderRequest.ShopId, StartTime = xingXiangSearchOrderRequest.SearchDate, EndTime = xingXiangSearchOrderRequest.SearchDate }, null, System.Net.Http.HttpMethod.Post); if (httpResult.StatusCode != System.Net.HttpStatusCode.OK) throw new BusinessException("查询店铺 goi失败"); shopGoi = JsonConvert.DeserializeObject>(httpResult.Content)?.Data; } #endregion 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, order.OrderSellerPrice + order.FreightPrice, Math.Abs(order.Profit ?? 0M)); XingXiangCumulative(detailList, currentOrderSkuList[0].ProductId, true, order.Profit ?? 0M, order.OrderSellerPrice + order.FreightPrice, 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 currentSkuOrderSkuList = currentOrderSkuList.Where(osku => osku.ProductId == spuGroup.Key); var totalActualAmount = currentSkuOrderSkuList.Sum(osku => { //var pingtaibutie = (osku.PingTaiChengDanYouHuiQuan ?? 0M) + (osku.SuperRedEnvelope ?? 0M) + (osku.XianPinLeiDongQuan ?? 0M) + (osku.JingDou ?? 0M) + (osku.DongQuan ?? 0M); //return (((osku.ShouldPay ?? 0M) + (osku.Balance ?? 0M) - (osku.VenderFee ?? 0M) + pingtaibutie) * osku.ItemTotal) ?? 0M; return (((osku.ActualAmount ?? 0M) - (osku.VenderFee ?? 0M)) * osku.ItemTotal) ?? 0M; }); var totalProfit = currentSpuCostDetailList.Sum(ocd => ocd.SkuGrossProfit); XingXiangCumulative(detailList, spuGroup.Key, false, totalProfit, totalActualAmount, 0); } } //var shopProductAmount = orderSkuList.Sum(osku => osku.ItemTotal * osku.Price); var shopActualAmount = orderSkuList.Sum(osku => { var pingtaibutie = (osku.PingTaiChengDanYouHuiQuan ?? 0M) + (osku.SuperRedEnvelope ?? 0M) + (osku.XianPinLeiDongQuan ?? 0M) + (osku.JingDou ?? 0M) + (osku.DongQuan ?? 0M); return (((osku.ShouldPay ?? 0M) + (osku.Balance ?? 0M) - (osku.VenderFee ?? 0M) + pingtaibutie) * osku.ItemTotal) ?? 0M; }); if (noOrderSpuIdList != null && noOrderSpuIdList.Count() > 0) { foreach (var spuId in noOrderSpuIdList) { //var spuGoi = spuGoiList?.FirstOrDefault(x => x.Spu == spuId); var xxRespose = new XingXiangItemResponse() { Spu = spuId, Profit = 0M, ActualAmount = 0M, SpuYingLiRatio = 0M }; detailList.Add(xxRespose); } } foreach (var d in detailList) { var spuGoi = spuGoiList?.FirstOrDefault(x => x.Spu == d.Spu); if (spuGoi != null) { //var spuActualAmount = orderSkuList.Where(osku => osku.ProductId == d.Spu).Sum(osku => osku.ShouldPay ?? 0M); d.SpuYingLiRatio = d.ActualAmount == 0 ? 0 : Math.Round((spuGoi.Profit - spuGoi.Cost) / d.ActualAmount, 2); } } 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), ShopYingLiRatio = shopActualAmount == 0 ? 0 : Math.Round((shopGoi.Profit - shopGoi.Cost) / shopActualAmount, 2), ShopProfitRatio = shopActualAmount == 0 ? 0 : Math.Round(shopGoi.Profit / shopActualAmount, 2), ShopActualAmount = shopActualAmount }; } /// /// 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.IsGift == false && 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 && (SqlExt.IsNull(oc.PurchaseAmount, 0) == 0M || SqlExt.IsNull(oc.Profit, 0) < 0)) || (o.StorageType == null && !filterExceptionStateList.Contains(o.OrderState)))).Count(); response.WaitOutStoreCount = fsql.Select().Where(o => o.ShopId == shopId && o.OrderState == Enums.OrderState.待出库 && o.StartTime >= dt && o.IsGift == false).Count(); response.AfterSaleOrderUnhandleCount = fsql.Select().Where(aso => aso.ShopId == shopId && (aso.ProductHealth == null || aso.ProductResult == null) && aso.CreateTime >= afterDt).Count(); return response; } public PurchaseOrderCountStatisticsResponse GetPurchaseOrderCountStatistics(long shopId) { var list = fsql.Select().Where(po => po.ShopId == shopId) .GroupBy(po => po.OrderState) .ToList(g => new { Count = g.Count(), OrderState = g.Key }); var response = new PurchaseOrderCountStatisticsResponse() { WaitPayCount = list.FirstOrDefault(x => x.OrderState == Enums.PurchaseOrderState.待付款)?.Count ?? 0, CancelCount = list.FirstOrDefault(x => x.OrderState == Enums.PurchaseOrderState.已取消)?.Count ?? 0, CompletedCount = list.FirstOrDefault(x => x.OrderState == Enums.PurchaseOrderState.已完成)?.Count ?? 0, WaitCheckCount = list.FirstOrDefault(x => x.OrderState == Enums.PurchaseOrderState.待验收)?.Count ?? 0, WaitComputationCount = list.FirstOrDefault(x => x.OrderState == Enums.PurchaseOrderState.待核算)?.Count ?? 0, WaitPurchaseCount = list.FirstOrDefault(x => x.OrderState == Enums.PurchaseOrderState.等待采购 || x.OrderState == Enums.PurchaseOrderState.部分采购)?.Count ?? 0, WaitShippment = list.FirstOrDefault(x => x.OrderState == Enums.PurchaseOrderState.待发货 || x.OrderState == Enums.PurchaseOrderState.部分发货)?.Count ?? 0, WaitReceiveCount = list.FirstOrDefault(x => x.OrderState == Enums.PurchaseOrderState.待收货 || x.OrderState == Enums.PurchaseOrderState.部分收货)?.Count ?? 0 }; 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; } } }