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, NLog.ILogger logger, IIdGenerator idGenerator, FreeSqlMultiDBManager freeSqlMultiDBManager) : base(fsql, logger, idGenerator) { 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) { response.PularizeEndDate = pularizeEndDate; var profit = 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 <= pularizeEndTime).Sum((o, oc) => oc.Profit); //response.Profit = profit; //计算SD成本 var sdCost = 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 <= pularizeEndTime).Sum((o, oc) => oc.Profit); 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(); } //var shopId = request.ShopId.ToString(); //var mdsShop = freeSqlMultiDBManager.MDSfsql.Select().Where(s => s.ShopId == shopId).ToOne(); //if (mdsShop != null) //{ // var advCost = freeSqlMultiDBManager.JDXXfsql.Select().Where(s => s.ShopsId == mdsShop.Id && // s.CreateTime >= request.StartTime && // s.CreateTime <= request.EndTime) // .ToAggregate(s => s.Sum(s.Key.ExpressCost + s.Key.ShotgunCost)); // response.AdvCost = advCost; // response.Profit -= advCost; //} response.ShopId = request.ShopId; return response; } public IList GetOrderAchievementStatisticsList(AllShopOrderAchievementRequest request) { request.EndTime = request.EndTime.Date.AddDays(1).AddSeconds(-1); var responseList = fsql.Select().LeftJoin((o, oc) => o.Id == oc.OrderId) .Where((o, oc) => o.OrderState != null && !invalidOrderStateList.Contains(o.OrderState.Value) && //排除待付款和取消 o.StartTime >= request.StartTime && o.StartTime <= request.EndTime) .GroupBy((o, oc) => o.ShopId) .ToList((g) => new OrderAchievementResponse() { ShopId = g.Key, OrderCount = g.Count(g.Value.Item1.Id), Profit = g.Sum(g.Value.Item2.Profit), SaleAmount = g.Sum(g.Value.Item1.OrderPayment), DeliveryExpressFreight = g.Sum(g.Value.Item2.DeliveryExpressFreight), PlatformCommissionAmount = g.Sum(g.Value.Item2.PlatformCommissionAmount), PurchaseAmount = g.Sum(g.Value.Item2.PurchaseAmount) }); var mdsShops = freeSqlMultiDBManager.MDSfsql.Select().Where(s => !string.IsNullOrEmpty(s.ShopId)).ToList(); var mdsShopIds = mdsShops.Select(s => s.Id); var advCosts = freeSqlMultiDBManager.JDXXfsql.Select().Where(s => mdsShopIds.Contains(s.ShopsId) && s.CreateTime >= request.StartTime && s.CreateTime <= request.EndTime) .GroupBy(s => s.ShopsId) .ToList(g => new { ShopId = g.Key, AdvCost = g.Sum(g.Value.ExpressCost + g.Value.ShotgunCost) }); foreach (var response in responseList) { string shopId = response.ShopId.ToString(); var mdsShop = mdsShops.FirstOrDefault(s => s.ShopId == shopId); if (mdsShop == null) continue; var advCostResponse = advCosts.FirstOrDefault(a => a.ShopId == mdsShop.Id); if (advCostResponse == null) continue; response.AdvCost = advCostResponse.AdvCost; response.Profit -= advCostResponse.AdvCost; } return responseList; } 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 => 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, DateTime startDate, DateTime endDate) { startDate = startDate.Date; endDate = endDate.Date.AddDays(1).AddSeconds(-1); var response = new OrderCountStatisticsResponse(); response.WaitPurchaseCount = fsql.Select().Where(o => o.ShopId == shopId && o.StartTime >= startDate && o.StartTime <= endDate && o.OrderState == Enums.OrderState.等待采购).Count(); response.ExceptionCount = fsql.Select().LeftJoin((o, oc) => o.Id == oc.OrderId) .Where((o, oc) => o.ShopId == shopId && o.StartTime >= startDate && o.StartTime <= endDate && 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(); 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) }); } } }