步步为盈
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

397 lines
22 KiB

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<Enums.OrderState?> 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.,
Enums.OrderState.
};
}
#region 同步SKU最近成本
public void SyncAllShopOrderSkuRecentCost()
{
var date = DateTime.Now.Date.AddDays(-1);
SyncOrderSkuRecentCost(new SkuRecentCostRequest()
{
ShopId = null,
StartDate = date,
EndDate = date
});
}
/// <summary>
/// 同步昨天SKU的采购成本
/// </summary>
/// <param name="request"></param>
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<OrderCostDetail, Order>()
.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<OrderCostDetail>()
.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<SkuRecentCost>(skuIdList).ToList();
List<SkuRecentCost> insertSkuRecetCostList = new List<SkuRecentCost>();
List<IUpdate<SkuRecentCost>> updateSkuRecentCostList = new List<IUpdate<SkuRecentCost>>();
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<SkuRecentCost>(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<SkuRecentCost>();
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<IUpdate<SkuRecentCost>> updateList = new List<IUpdate<SkuRecentCost>>();
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., Enums.StorageType. };
var shopId = long.Parse(shop.ShopId);
var orderList = fsql.Select<Order>().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<OrderCost>().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<OrderCostDetail> insertOrderCostDetailList = new List<OrderCostDetail>();
List<OrderCost> insertOrderCostList = new List<OrderCost>();
var orderSkuAndRecentList = fsql.Select<OrderSku, SkuRecentCost>()
.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<OrderCostDetail> currentOrderInsertOcdList = new List<OrderCostDetail>();
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
}
}