using BBWY.Common.Extensions; using BBWY.Common.Models; using BBWY.Server.Business.Extensions; using BBWY.Server.Model; using BBWY.Server.Model.Db; using BBWY.Server.Model.Dto; using FreeSql; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using Yitter.IdGenerator; namespace BBWY.Server.Business { public class OrderEstimateCostSyncBusiness : BaseBusiness, IDenpendency { private TaskSchedulerManager taskSchedulerManager; private VenderBusiness venderBusiness; private List invalidOrderStateList; public OrderEstimateCostSyncBusiness(IFreeSql fsql, NLogManager nLogManager, IIdGenerator idGenerator, TaskSchedulerManager taskSchedulerManager, VenderBusiness venderBusiness) : base(fsql, nLogManager, idGenerator) { this.taskSchedulerManager = taskSchedulerManager; this.venderBusiness = venderBusiness; invalidOrderStateList = new List() { Enums.OrderState.待付款, Enums.OrderState.已取消, Enums.OrderState.暂停 }; } #region 同步SKU最近成本 public void SyncAllShopOrderSkuRecentCost() { var date = DateTime.Now.Date.AddDays(-1); SyncOrderSkuRecentCost(new SkuRecentCostRequest() { ShopId = null, StartDate = date, EndDate = date }); } /// /// 同步昨天SKU的采购成本 /// /// public void SyncOrderSkuRecentCost(SkuRecentCostRequest request) { var shopList = venderBusiness.GetShopList(request.ShopId, Model.Enums.Platform.京东); request.EndDate = request.EndDate.Date.AddDays(1).AddSeconds(-1); foreach (var shop in shopList) { var _shopId = long.Parse(shop.ShopId); Task.Factory.StartNew(() => SyncOrderSkuRecentCost(shop, request.StartDate, request.EndDate), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.SyncSkuYesterdayCostTaskScheduler); } } private void SyncOrderSkuRecentCost(ShopResponse shop, DateTime startDate, DateTime endDate) { try { var shopId = long.Parse(shop.ShopId); var yesterdaycostDetailist = fsql.Select() .InnerJoin((ocd, o) => ocd.OrderId == o.Id) .Where((ocd, o) => o.ShopId == shopId && o.StartTime >= startDate && o.StartTime <= endDate && !invalidOrderStateList.Contains(o.OrderState) && o.IsGift == false && o.StorageType != Enums.StorageType.SD && ocd.IsEnabled == true && ocd.IsEstimateCost == false) .GroupBy((ocd, o) => ocd.SkuId) .WithTempQuery(g => new { MaxId = g.Sum(g.Value.Item1.Id), SkuId = g.Key }) .From() .InnerJoin((ocd1, ocd2) => ocd1.MaxId == ocd2.Id) .ToList((ocd1, ocd2) => ocd2); Console.WriteLine($"SKU最近成本同步-{shop.ShopName},有销量的订单sku一共{yesterdaycostDetailist.Count()}个"); if (yesterdaycostDetailist.Count() == 0) return; var skuIdList = yesterdaycostDetailist.Select(ocd => ocd.SkuId).Distinct().ToList(); var dbSkuRecentCostList = fsql.Select(skuIdList).ToList(); List insertSkuRecetCostList = new List(); List> updateSkuRecentCostList = new List>(); foreach (var yesocd in yesterdaycostDetailist) { var q = yesocd.DeductionQuantity; if (q <= 0) q = 1; var singleConsumableAmount = yesocd.ConsumableAmount / q; var singleDeliveryFreight = yesocd.DeliveryExpressFreight / q; var singleFirstFreight = yesocd.FirstFreight / q; var singleFreight = yesocd.PurchaseFreight / q; var singleInStorageAmount = yesocd.InStorageAmount / q; var singleOutStorageAmount = yesocd.OutStorageAmount / q; var singleSkuAmount = yesocd.SkuAmount / q; var singleStorageAmount = yesocd.StorageAmount / q; var skuRecentCost = dbSkuRecentCostList.FirstOrDefault(x => x.SkuId == yesocd.SkuId); if (skuRecentCost != null) { skuRecentCost.SingleConsumableAmount = singleConsumableAmount; skuRecentCost.SingleDeliveryFreight = singleDeliveryFreight; skuRecentCost.SingleFirstFreight = singleFirstFreight; skuRecentCost.SingleFreight = singleFreight; skuRecentCost.SingleInStorageAmount = singleInStorageAmount; skuRecentCost.SingleOutStorageAmount = singleOutStorageAmount; skuRecentCost.SingleSkuAmount = singleSkuAmount; skuRecentCost.SingleStorageAmount = singleStorageAmount; skuRecentCost.UpdateTime = DateTime.Now; var update = fsql.Update(yesocd.SkuId).SetSource(skuRecentCost); updateSkuRecentCostList.Add(update); } else { skuRecentCost = new SkuRecentCost() { SkuId = yesocd.SkuId, CreateTime = DateTime.Now, UpdateTime = DateTime.Now, ProductId = yesocd.ProductId, RecentOrderId = yesocd.OrderId, ShopId = shopId, SingleConsumableAmount = singleConsumableAmount, SingleDeliveryFreight = singleDeliveryFreight, SingleFirstFreight = singleFirstFreight, SingleFreight = singleFreight, SingleInStorageAmount = singleInStorageAmount, SingleOutStorageAmount = singleOutStorageAmount, SingleSkuAmount = singleSkuAmount, SingleStorageAmount = singleStorageAmount }; insertSkuRecetCostList.Add(skuRecentCost); } } fsql.Transaction(() => { if (insertSkuRecetCostList.Count() > 0) fsql.Insert(insertSkuRecetCostList).ExecuteAffrows(); if (updateSkuRecentCostList.Count() > 0) { foreach (var update in updateSkuRecentCostList) update.ExecuteAffrows(); } }); } catch (Exception ex) { nLogManager.GetLogger($"SKU最近成本-{shop.ShopName}").Error(ex); } } #endregion #region 预估成本 public void EstimateCostForAllShopNoCostOrder() { EstimateCostForNoCostOrder(new SkuRecentCostRequest() { ShopId = null, StartDate = DateTime.Now.AddHours(-3), EndDate = DateTime.Now }); } public void EstimateCostForNoCostOrder(SkuRecentCostRequest request) { var shopList = venderBusiness.GetShopList(request.ShopId, Model.Enums.Platform.京东); //request.EndDate = request.EndDate.Date.AddDays(1).AddSeconds(-1); foreach (var shop in shopList) { Task.Factory.StartNew(() => EstimateCostForNoCostOrder(shop, request.StartDate, request.EndDate), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.SyncSkuYesterdayCostTaskScheduler); } } private void EstimateCostForNoCostOrder(ShopResponse shop, DateTime startTime, DateTime endTime) { try { var shopId = long.Parse(shop.ShopId); var orderList = fsql.Select().Where(o => o.ShopId == shopId && o.ModifyTime >= startTime && o.ModifyTime <= endTime && !invalidOrderStateList.Contains(o.OrderState) && o.IsGift == false && o.StorageType == null && !fsql.Select().Where(oc => oc.OrderId == o.Id).Any()) .ToList(); Console.WriteLine($"预估成本-{shop.ShopName},符合条件且没有成本的订单一共{orderList.Count()}个"); if (orderList.Count() == 0) return; var orderIdList = orderList.Select(o => o.Id).ToList(); List insertOrderCostDetailList = new List(); List insertOrderCostList = new List(); var orderSkuAndRecentList = fsql.Select() .LeftJoin((osku, src) => osku.SkuId == src.SkuId) .Where((osku, src) => orderIdList.Contains(osku.SkuId) && osku.Price > 0) .ToList((osku, src) => new { osku.Id, osku.OrderId, osku.SkuId, osku.ProductId, osku.ShouldPay, osku.PingTaiChengDanYouHuiQuan, osku.SuperRedEnvelope, osku.XianPinLeiDongQuan, osku.VenderFee, osku.JingDou, osku.DongQuan, osku.Balance, osku.ItemTotal, src.SingleConsumableAmount, src.SingleSkuAmount, src.SingleDeliveryFreight, src.SingleFirstFreight, src.SingleFreight, src.SingleInStorageAmount, src.SingleOutStorageAmount, src.SingleStorageAmount }); foreach (var order in orderList) { var currentOrderSkuList = orderSkuAndRecentList.Where(osku => osku.OrderId == order.Id).ToList(); if (currentOrderSkuList.Any(osku => osku.ShouldPay == null || osku.ShouldPay == 0 || osku.SingleSkuAmount == null || osku.SingleSkuAmount == 0)) continue; //预估成本和毛利,必须订单下的每一笔sku都具备最近成本 List currentOrderInsertOcdList = new List(); foreach (var osku in currentOrderSkuList) { var ocd = new OrderCostDetail() { Id = idGenerator.NewLong(), ConsumableAmount = (osku.SingleConsumableAmount * osku.ItemTotal) ?? 0M, DeductionQuantity = osku.ItemTotal ?? 1, CreateTime = DateTime.Now, DeliveryExpressFreight = (osku.SingleDeliveryFreight * osku.ItemTotal) ?? 0M, FirstFreight = (osku.SingleFirstFreight * osku.ItemTotal) ?? 0M, InStorageAmount = (osku.SingleInStorageAmount * osku.ItemTotal) ?? 0M, OutStorageAmount = (osku.SingleOutStorageAmount * osku.ItemTotal) ?? 0M, OrderId = order.Id, ProductId = osku.ProductId, PurchaseFreight = (osku.SingleFreight * osku.ItemTotal) ?? 0M, PurchaseOrderPKId = 0, SkuAmount = (osku.SingleSkuAmount * osku.ItemTotal) ?? 0M, SkuId = osku.SkuId, StorageAmount = (osku.SingleStorageAmount * osku.ItemTotal) ?? 0M, IsEnabled = true, IsEstimateCost = true }; ocd.CalculationSkuGrossProfit(osku.ShouldPay ?? 0M, osku.PingTaiChengDanYouHuiQuan ?? 0M, osku.SuperRedEnvelope ?? 0M, osku.XianPinLeiDongQuan ?? 0M, osku.VenderFee ?? 0M, osku.JingDou ?? 0M, osku.DongQuan ?? 0M, osku.Balance ?? 0M, shop.PlatformCommissionRatio ?? 0.05M); currentOrderInsertOcdList.Add(ocd); } var orderCost = new OrderCost() { OrderId = order.Id, CreateTime = DateTime.Now, AfterTotalCost = 0M, DeliveryExpressFreight = currentOrderInsertOcdList.Sum(ocd => ocd.DeliveryExpressFreight), IsEstimateCost = true, IsManualEdited = false, PlatformCommissionRatio = shop.PlatformCommissionRatio ?? 0.05M, PurchaseAmount = currentOrderInsertOcdList.Sum(ocd => ocd.TotalCost), PreferentialAmount = order.PreferentialAmount }; orderCost.CalculationOrderProfitAndCost(order, null); insertOrderCostDetailList.AddRange(currentOrderInsertOcdList); insertOrderCostList.Add(orderCost); } } catch (Exception ex) { nLogManager.GetLogger($"预估成本-{shop.ShopName}").Error(ex); } } #endregion } }