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.
390 lines
21 KiB
390 lines
21 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 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.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)
|
|
.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,
|
|
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 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 &&
|
|
!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.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,
|
|
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
|
|
}
|
|
}
|