步步为盈
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.

300 lines
16 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.Sum(g.Value.Item1.Id), SkuId = g.Key })
.From<OrderCostDetail>()
.InnerJoin((ocd1, ocd2) => ocd1.MaxId == ocd2.Id)
.ToList((ocd1, ocd2) => ocd2);
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)
{
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).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<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();
if (orderList.Count() == 0)
return;
var orderIdList = orderList.Select(o => o.Id).ToList();
/*
decimal skuShouldPay,
decimal pingTaiChengDanYouHuiQuan,
decimal superRedEnvelope,
decimal xianPinLeiDongQuan,
decimal skuVenderFee,
decimal jingdou,
decimal dongquan,
decimal balance,
*/
/*
SkuAmount +
PurchaseFreight +
FirstFreight +
InStorageAmount +
OutStorageAmount +
StorageAmount +
ConsumableAmount
*/
var orderSkuAndRecentList = fsql.Select<OrderSku, SkuRecentCost>()
.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都具备最近成本
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);
}
}
}
catch (Exception ex)
{
nLogManager.GetLogger($"预估成本-{shop.ShopName}").Error(ex);
}
}
#endregion
}
}