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.Max(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 singlePackagingLaborAmount = yesocd.PackagingLaborAmount / q; var skuRecentCost = dbSkuRecentCostList.FirstOrDefault(x => x.SkuId == yesocd.SkuId); if (skuRecentCost != null) { if (skuRecentCost.SingleConsumableAmount != singleConsumableAmount || skuRecentCost.SingleDeliveryFreight != singleDeliveryFreight || skuRecentCost.SingleFirstFreight != singleFirstFreight || skuRecentCost.SingleFreight != singleFreight || skuRecentCost.SingleInStorageAmount != singleInStorageAmount || skuRecentCost.SingleOutStorageAmount != singleOutStorageAmount || skuRecentCost.SingleSkuAmount != singleSkuAmount || skuRecentCost.SinglePackagingLaborAmount != singlePackagingLaborAmount) //skuRecentCost.SingleStorageAmount != singleStorageAmount) { skuRecentCost.UpdateTime = DateTime.Now; var update = fsql.Update(yesocd.SkuId) .SetIf(skuRecentCost.SingleConsumableAmount != singleConsumableAmount, s => s.SingleConsumableAmount, singleConsumableAmount) .SetIf(skuRecentCost.SingleDeliveryFreight != singleDeliveryFreight, s => s.SingleDeliveryFreight, singleDeliveryFreight) .SetIf(skuRecentCost.SingleFirstFreight != singleFirstFreight, s => s.SingleFirstFreight, singleFirstFreight) .SetIf(skuRecentCost.SingleFreight != singleFreight, s => s.SingleFreight, singleFreight) .SetIf(skuRecentCost.SingleInStorageAmount != singleInStorageAmount, s => s.SingleInStorageAmount, singleInStorageAmount) .SetIf(skuRecentCost.SingleOutStorageAmount != singleOutStorageAmount, s => s.SingleOutStorageAmount, singleOutStorageAmount) .SetIf(skuRecentCost.SingleSkuAmount != singleSkuAmount, s => s.SingleSkuAmount, singleSkuAmount) //.SetIf(skuRecentCost.SingleStorageAmount != singleStorageAmount, s => s.SingleStorageAmount, singleStorageAmount) .SetIf(skuRecentCost.SinglePackagingLaborAmount != singlePackagingLaborAmount, s => s.SinglePackagingLaborAmount, singlePackagingLaborAmount) .Set(s => s.UpdateTime, DateTime.Now); 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, SinglePackagingLaborAmount = singlePackagingLaborAmount //SingleStorageAmount = singleStorageAmount }; insertSkuRecetCostList.Add(skuRecentCost); } } if (insertSkuRecetCostList.Count() > 0) { var insertList = new List(); var index = 0; foreach (var insert in insertSkuRecetCostList) { insertList.Add(insert); if (insertList.Count() == 50) { index++; Console.WriteLine($"SKU最近成本同步-{shop.ShopName},执行插入{index}"); fsql.Transaction(() => { fsql.Insert(insertList).ExecuteAffrows(); }); insertList.Clear(); } } if (insertList.Count() > 0) { index++; Console.WriteLine($"SKU最近成本同步-{shop.ShopName},执行最后插入{index}"); fsql.Transaction(() => { fsql.Insert(insertList).ExecuteAffrows(); }); insertList.Clear(); } insertSkuRecetCostList.Clear(); } if (updateSkuRecentCostList.Count() > 0) { List> updateList = new List>(); var index = 0; foreach (var update in updateSkuRecentCostList) { updateList.Add(update); if (updateList.Count == 20) { index++; Console.WriteLine($"SKU最近成本同步-{shop.ShopName},执行更新{index}"); fsql.Transaction(() => { foreach (var _update in updateList) _update.ExecuteAffrows(); }); updateList.Clear(); } } if (updateList.Count > 0) { index++; Console.WriteLine($"SKU最近成本同步-{shop.ShopName},执行最后更新{index}"); fsql.Transaction(() => { foreach (var _update in updateList) _update.ExecuteAffrows(); }); updateList.Clear(); } updateSkuRecentCostList.Clear(); } //fsql.Transaction(() => //{ // if (insertSkuRecetCostList.Count() > 0) // fsql.Insert(insertSkuRecetCostList).ExecuteAffrows(); // if (updateSkuRecentCostList.Count() > 0) // { // foreach (var update in updateSkuRecentCostList) // update.ExecuteAffrows(); // } //}); } catch (Exception ex) { Console.WriteLine($"{shop.ShopName},{ex.Message}"); 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 jcycStorageTypeList = new List() { Enums.StorageType.京仓, Enums.StorageType.云仓 }; 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 || jcycStorageTypeList.Contains(o.StorageType)) && !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.OrderId) && 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.SinglePackagingLaborAmount //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, PackagingLaborAmount = (osku.SinglePackagingLaborAmount * 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); } fsql.Transaction(() => { if (insertOrderCostDetailList.Count() > 0) fsql.Insert(insertOrderCostDetailList).ExecuteAffrows(); if (insertOrderCostList.Count() > 0) fsql.Insert(insertOrderCostList).ExecuteAffrows(); }); } catch (Exception ex) { nLogManager.GetLogger($"预估成本-{shop.ShopName}").Error(ex); } } #endregion } }