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.
838 lines
50 KiB
838 lines
50 KiB
using BBWYB.Common.Log;
|
|
using BBWYB.Common.Models;
|
|
using BBWYB.Server.Model;
|
|
using BBWYB.Server.Model.Db;
|
|
using BBWYB.Server.Model.Db.BBWY;
|
|
using BBWYB.Server.Model.Db.SpuOptimization;
|
|
using BBWYB.Server.Model.Dto;
|
|
using FreeSql;
|
|
using Newtonsoft.Json.Linq;
|
|
using SDKAdapter;
|
|
using SDKAdapter.OperationPlatform.Client;
|
|
using SDKAdapter.OperationPlatform.Models;
|
|
using Yitter.IdGenerator;
|
|
|
|
namespace BBWYB.Server.Business.Sync
|
|
{
|
|
public class OrderSyncBusiness : BaseBusiness, IDenpendency
|
|
{
|
|
private OP_PlatformClientFactory opPlatformClientFactory;
|
|
private VenderBusiness venderBusiness;
|
|
private TaskSchedulerManager taskSchedulerManager;
|
|
private List<Enums.TimeLimitTaskType> timeLimitTaskTypes;
|
|
private TimeLimitRules timeLimitRules;
|
|
private FreeSqlMultiDBManager fsqlManager;
|
|
|
|
public OrderSyncBusiness(IFreeSql fsql,
|
|
NLogManager nLogManager,
|
|
IIdGenerator idGenerator,
|
|
OP_PlatformClientFactory opPlatformClientFactory,
|
|
VenderBusiness venderBusiness,
|
|
TaskSchedulerManager taskSchedulerManager,
|
|
TimeLimitRules timeLimitRules,
|
|
FreeSqlMultiDBManager fsqlManager) : base(fsql, nLogManager, idGenerator)
|
|
{
|
|
this.opPlatformClientFactory = opPlatformClientFactory;
|
|
this.venderBusiness = venderBusiness;
|
|
this.taskSchedulerManager = taskSchedulerManager;
|
|
timeLimitTaskTypes = new List<Enums.TimeLimitTaskType>()
|
|
{
|
|
Enums.TimeLimitTaskType.采购任务,
|
|
Enums.TimeLimitTaskType.待议价任务
|
|
};
|
|
this.timeLimitRules = timeLimitRules;
|
|
this.fsqlManager = fsqlManager;
|
|
}
|
|
|
|
public void AutoOrderSync()
|
|
{
|
|
var shopList = venderBusiness.GetShopList(platform: Enums.Platform.拳探);
|
|
foreach (var shop in shopList)
|
|
{
|
|
Task.Factory.StartNew(() => Sync(shop, string.Empty, DateTime.Now.AddHours(-3), DateTime.Now, AdapterEnums.SortTimeField.Modify, AdapterEnums.SortType.Desc), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.SyncOrderTaskScheduler);
|
|
}
|
|
}
|
|
|
|
public void ManualOrderSync(long shopId, string orderId, DateTime? startTime, DateTime? endTime)
|
|
{
|
|
var shop = venderBusiness.GetShopList(shopId, platform: Enums.Platform.拳探).FirstOrDefault();
|
|
if (shop == null)
|
|
throw new BusinessException($"未找到店铺Id {shopId}");
|
|
|
|
Task.Factory.StartNew(() => Sync(shop, orderId, startTime, endTime, AdapterEnums.SortTimeField.Modify, AdapterEnums.SortType.Desc), CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.SyncOrderTaskScheduler);
|
|
}
|
|
|
|
public void ManualOrderSync(long shopId, DateTime startTime, DateTime endTime)
|
|
{
|
|
var shop = venderBusiness.GetShopList(shopId, platform: Enums.Platform.拳探).FirstOrDefault();
|
|
if (shop == null)
|
|
throw new BusinessException($"未找到店铺Id {shopId}");
|
|
while (true)
|
|
{
|
|
var s = startTime;
|
|
var e = s.AddHours(3);
|
|
Sync(shop, string.Empty, s, e, AdapterEnums.SortTimeField.Modify, AdapterEnums.SortType.Desc);
|
|
if (e >= endTime)
|
|
break;
|
|
startTime = startTime.AddHours(3);
|
|
}
|
|
}
|
|
|
|
private void Sync(ShopResponse shop,
|
|
string orderId,
|
|
DateTime? startTime,
|
|
DateTime? endTime,
|
|
AdapterEnums.SortTimeField sortTimeField,
|
|
AdapterEnums.SortType sortType)
|
|
{
|
|
var shopId = long.Parse(shop.ShopId);
|
|
var loggerName = $"订单同步-{shop.ShopName}";
|
|
try
|
|
{
|
|
var qtOrderList = opPlatformClientFactory.GetClient(AdapterEnums.PlatformType.拳探).GetOrderList(new OP_QueryOrderRequest()
|
|
{
|
|
AppKey = shop.AppKey,
|
|
AppSecret = shop.AppSecret,
|
|
AppToken = shop.AppToken,
|
|
OrderId = orderId,
|
|
PageIndex = 1,
|
|
PageSize = 100,
|
|
Platform = AdapterEnums.PlatformType.拳探,
|
|
SortTimeField = sortTimeField,
|
|
SortType = sortType,
|
|
StartDate = startTime,
|
|
EndDate = endTime
|
|
});
|
|
if (qtOrderList.Count == 0)
|
|
return;
|
|
|
|
var qtOrderIdList = qtOrderList.Items.Select(qto => qto.OrderId).ToList();
|
|
var dbOrderList = fsql.Select<Model.Db.Order>(qtOrderIdList).ToList();
|
|
|
|
|
|
var payedQTOrderIdList = qtOrderList.Items.Where(qto => qto.IsPay).Select(qto => qto.OrderId).ToList();
|
|
|
|
var payedQTSpuIdList = qtOrderList.Items.Where(qto => qto.IsPay).SelectMany(qto => qto.OrderSkuList).Select(qtos => qtos.ProductId).Distinct().ToList();
|
|
var payedQTSkuIdList = qtOrderList.Items.Where(qto => qto.IsPay).SelectMany(qto => qto.OrderSkuList).Select(qtos => qtos.SkuId).Distinct().ToList();
|
|
|
|
//限时任务列表
|
|
var dbTimeLimitTaskList = fsql.Select<TimeLimitTask>().Where(t => timeLimitTaskTypes.Contains(t.TaskType.Value) &&
|
|
payedQTOrderIdList.Contains(t.OrderId)).ToList();
|
|
|
|
//限时采购任务列表
|
|
var dbPurchaseTimeLimitTaskList = dbTimeLimitTaskList.Where(t => t.TaskType == Enums.TimeLimitTaskType.采购任务).ToList();
|
|
|
|
//限时议价任务列表
|
|
var dbOptimizationLimitTaskList = dbTimeLimitTaskList.Where(t => t.TaskType == Enums.TimeLimitTaskType.待议价任务).ToList();
|
|
|
|
//现有sku销量
|
|
var dbSkuTotalSaleInfoList = fsql.Select<SkuTotalSaleInfo>().Where(s => s.ShopId == shopId && s.IsEnabled == true && payedQTSkuIdList.Contains(s.SkuId))
|
|
.ToList();
|
|
|
|
//现有spu销量
|
|
var dbSpuTotalSaleInfoList = fsql.Select<SpuTotalSaleInfo>().Where(s => s.ShopId == shopId && s.IsEnabled == true && payedQTSpuIdList.Contains(s.ProductId))
|
|
.ToList();
|
|
|
|
#region DB Operation
|
|
List<Model.Db.Order> insertOrderList = new List<Model.Db.Order>();
|
|
List<OrderSku> insertOrderSkuList = new List<OrderSku>();
|
|
//List<long> updateOrderSkuIdList_OptimizationFlag = new List<long>();
|
|
Dictionary<Enums.TriggerOptimizationReason, List<long>> updateOSkuOptimizationFlagByReasonGroups = new Dictionary<Enums.TriggerOptimizationReason, List<long>>();
|
|
List<OrderConsignee> insertOrderConsigneeList = new List<OrderConsignee>();
|
|
List<TimeLimitTask> insertTimeLimitTaskList = new List<TimeLimitTask>();
|
|
List<string> deleteTimeLimitTaskOrderIdList = new List<string>();
|
|
List<IUpdate<Model.Db.Order>> updateOrderList = new List<IUpdate<Model.Db.Order>>();
|
|
List<SkuTotalSaleInfo> insertSkuTotalSaleInfoList = new List<SkuTotalSaleInfo>();
|
|
IList<SkuTotalSaleInfo> updateSkuTotalSaleInfoList = new List<SkuTotalSaleInfo>();
|
|
|
|
List<SpuTotalSaleInfo> insertSpuTotalSaleInfoList = new List<SpuTotalSaleInfo>();
|
|
IList<SpuTotalSaleInfo> updateSpuTotalSaleInfoList = new List<SpuTotalSaleInfo>();
|
|
|
|
List<SpuOptimizationTask> insertSpuOptimizationTaskList = new List<SpuOptimizationTask>();
|
|
List<SkuOptimizationTask> insertSkuOptimizationTaskList = new List<SkuOptimizationTask>();
|
|
List<SpuOptimizationBargainTeamTask> insertSpuOptimizationBargainTeamTaskList = new List<SpuOptimizationBargainTeamTask>();
|
|
List<SpuOptimizationCompetitiveTenderTask> insertSpuOptimizationCompetitiveTenderTaskList = new List<SpuOptimizationCompetitiveTenderTask>();
|
|
//List<SpuOptimizationPurchaserCompetitiveTenderTask> insertSpuOptimizationPurchaserCompetitiveTenderTaskList = new List<SpuOptimizationPurchaserCompetitiveTenderTask>();
|
|
#endregion
|
|
|
|
//等待检查sku销量的订单集合
|
|
List<OP_OrderResponse> waitToCheckSkuSaleOrderList = new List<OP_OrderResponse>();
|
|
|
|
IDictionary<string, int> deductionSkuCountDictionary = new Dictionary<string, int>();
|
|
IDictionary<string, int> deductionSpuCountDictionary = new Dictionary<string, int>();
|
|
|
|
#region 同步订单
|
|
foreach (var qtOrder in qtOrderList.Items)
|
|
{
|
|
var dbOrder = dbOrderList.FirstOrDefault(o => o.Id == qtOrder.OrderId);
|
|
var orderState = ConvertQuanTanOrderState(qtOrder.OrderState, qtOrder.IsPay, dbOrder?.IsPurchased ?? false);
|
|
if (dbOrder == null)
|
|
{
|
|
//新订单
|
|
dbOrder = new Model.Db.Order()
|
|
{
|
|
Id = qtOrder.OrderId,
|
|
OrderSn = qtOrder.OrderSn,
|
|
BuyerRemark = qtOrder.BuyerRemark,
|
|
EndTime = qtOrder.EndTime,
|
|
//ExpressName = qtOrder.DeliveryResponse.ExpressName,
|
|
FreightPrice = qtOrder.FreightAmount,
|
|
ModifyTime = qtOrder.ModifyTime,
|
|
IsPurchased = false,
|
|
OrderPayment = qtOrder.OrderPayment,
|
|
OrderSellerPrice = qtOrder.OrderProductAmount,
|
|
OrderTotalPrice = qtOrder.OrderTotalAmount,
|
|
OrderType = 0,
|
|
PayType = qtOrder.PayType,
|
|
Platform = Enums.Platform.拳探,
|
|
PreferentialAmount = qtOrder.PreferentialAmount,
|
|
//PurchaseRemark = String.Empty,
|
|
ShopId = shopId,
|
|
SellerPreferentialAmount = qtOrder.SellerPreferentialAmount,
|
|
StartTime = qtOrder.StartTime,
|
|
VenderRemark = qtOrder.VenderRemark,
|
|
//WaybillNo = qtOrder.DeliveryResponse.WayBillNo,
|
|
OrderState = orderState,
|
|
ClientOrderId = qtOrder.ClientOrderId,
|
|
BuyerAccount = qtOrder.UserAccount,
|
|
InPackAmount = qtOrder.PackAmount,
|
|
PayTime = qtOrder.PayTime,
|
|
};
|
|
JArray belongSkus = null;
|
|
if (!string.IsNullOrEmpty(qtOrder.Extended))
|
|
{
|
|
try
|
|
{
|
|
var jobject = JObject.Parse(qtOrder.Extended);
|
|
//dbOrder.SourceSku = jobject.Value<string>("SourceSku");
|
|
dbOrder.SourceShopName = jobject.Value<string>("SourceShopName");
|
|
|
|
if (jobject.ContainsKey("BelongSkus"))
|
|
belongSkus = jobject["BelongSkus"] as JArray;
|
|
|
|
if (jobject.ContainsKey("IntoStoreType"))
|
|
dbOrder.IntoStoreType = (Enums.IntoStoreType?)jobject.Value<int?>("IntoStoreType");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
if (!insertOrderList.Any(o => o.Id == dbOrder.Id))
|
|
insertOrderList.Add(dbOrder);
|
|
|
|
//订单sku
|
|
foreach (var qtOrderSku in qtOrder.OrderSkuList)
|
|
{
|
|
insertOrderSkuList.Add(new OrderSku()
|
|
{
|
|
//Id = idGenerator.NewLong(),
|
|
Id = long.Parse(qtOrderSku.Id),
|
|
CreateTime = DateTime.Now,
|
|
SkuId = qtOrderSku.SkuId,
|
|
ItemTotal = qtOrderSku.Quantity,
|
|
Logo = qtOrderSku.SkuLogo,
|
|
OrderId = qtOrder.OrderId,
|
|
Price = qtOrderSku.SkuPrice,
|
|
InitialPrice = qtOrderSku.SkuPrice,
|
|
Title = qtOrderSku.SkuTitle,
|
|
ShopId = shopId,
|
|
ProductId = qtOrderSku.ProductId,
|
|
BelongSkuId = belongSkus?.FirstOrDefault(j => j.Value<string>("SkuId") == qtOrderSku.SkuId)?.Value<string>("BelongSkuId") ?? string.Empty,
|
|
InPackAmount = qtOrderSku.PackAmount,
|
|
BuyerPayFreight = qtOrderSku.FreightAmount,
|
|
IsNeedOptimization = 0,
|
|
IsOptimizationCompleted = 0
|
|
});
|
|
}
|
|
//收货人
|
|
insertOrderConsigneeList.Add(new OrderConsignee()
|
|
{
|
|
OrderId = qtOrder.OrderId,
|
|
Address = qtOrder.Consignee.Address,
|
|
City = qtOrder.Consignee.City,
|
|
ContactName = qtOrder.Consignee.ContactName,
|
|
County = qtOrder.Consignee.County,
|
|
CreateTime = DateTime.Now,
|
|
Mobile = qtOrder.Consignee.Mobile,
|
|
Province = qtOrder.Consignee.Province,
|
|
TelePhone = qtOrder.Consignee.Mobile,
|
|
Town = qtOrder.Consignee.Town
|
|
});
|
|
|
|
if (qtOrder.IsPay && !waitToCheckSkuSaleOrderList.Any(x => x.OrderId == qtOrder.OrderId))
|
|
waitToCheckSkuSaleOrderList.Add(qtOrder);
|
|
}
|
|
else
|
|
{
|
|
#region 订单状态脱离拳探 只处理付款和取消
|
|
Enums.OrderState? updateOrderState = null;
|
|
if (orderState == Enums.OrderState.待付款 && dbOrder.OrderState != Enums.OrderState.待付款)
|
|
{
|
|
//dbOrder.OrderState = Enums.OrderState.待付款;
|
|
updateOrderState = Enums.OrderState.待付款;
|
|
}
|
|
|
|
if (dbOrder.OrderState == Enums.OrderState.待付款 && orderState != Enums.OrderState.待付款 && orderState != Enums.OrderState.已取消)
|
|
{
|
|
updateOrderState = Enums.OrderState.等待采购;
|
|
if (!waitToCheckSkuSaleOrderList.Any(x => x.OrderId == qtOrder.OrderId))
|
|
waitToCheckSkuSaleOrderList.Add(qtOrder);
|
|
}
|
|
|
|
if (dbOrder.OrderState != Enums.OrderState.已取消 && orderState == Enums.OrderState.已取消)
|
|
{
|
|
updateOrderState = Enums.OrderState.已取消;
|
|
if (dbPurchaseTimeLimitTaskList.Any(t => t.OrderId == qtOrder.OrderId))
|
|
deleteTimeLimitTaskOrderIdList.Add(qtOrder.OrderId);
|
|
|
|
foreach (var qtOrderSku in qtOrder.OrderSkuList)
|
|
{
|
|
if (!deductionSkuCountDictionary.ContainsKey(qtOrderSku.SkuId))
|
|
deductionSkuCountDictionary.Add(qtOrderSku.SkuId, 0);
|
|
deductionSkuCountDictionary[qtOrderSku.SkuId] += qtOrderSku.Quantity;
|
|
|
|
if (!deductionSpuCountDictionary.ContainsKey(qtOrderSku.ProductId))
|
|
deductionSpuCountDictionary.Add(qtOrderSku.ProductId, 0);
|
|
deductionSpuCountDictionary[qtOrderSku.ProductId] += qtOrderSku.Quantity;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
var updateModifyTime = dbOrder.ModifyTime != qtOrder.ModifyTime;
|
|
var updateBuyerRemark = dbOrder.BuyerRemark != qtOrder.BuyerRemark;
|
|
var updateVenderRemark = dbOrder.VenderRemark != qtOrder.VenderRemark;
|
|
var updateBuyerAccount = dbOrder.BuyerAccount != qtOrder.UserAccount;
|
|
var updateOrderSn = dbOrder.OrderSn != qtOrder.OrderSn;
|
|
var updatePayTime = dbOrder.PayTime != qtOrder.PayTime;
|
|
|
|
if (updateOrderState != null || updateModifyTime || updateBuyerRemark || updateVenderRemark || updateBuyerAccount || updateOrderSn || updatePayTime)
|
|
{
|
|
var update = fsql.Update<Model.Db.Order>(dbOrder.Id).SetIf(updateOrderState != null, o => o.OrderState, updateOrderState)
|
|
.SetIf(updateModifyTime, o => o.ModifyTime, qtOrder.ModifyTime)
|
|
.SetIf(updateBuyerRemark, o => o.BuyerRemark, qtOrder.BuyerRemark)
|
|
.SetIf(updateVenderRemark, o => o.VenderRemark, qtOrder.VenderRemark)
|
|
.SetIf(updateBuyerAccount, o => o.BuyerAccount, qtOrder.UserAccount)
|
|
.SetIf(updateOrderSn, o => o.OrderSn, qtOrder.OrderSn)
|
|
.SetIf(updatePayTime, o => o.PayTime, qtOrder.PayTime);
|
|
updateOrderList.Add(update);
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 统计销量
|
|
foreach (var qtOrder in waitToCheckSkuSaleOrderList)
|
|
{
|
|
foreach (var qtOrderSku in qtOrder.OrderSkuList)
|
|
{
|
|
#region 统计sku销量
|
|
{
|
|
var skuTotalSaleInfo = dbSkuTotalSaleInfoList.FirstOrDefault(s => s.SkuId == qtOrderSku.SkuId);
|
|
if (skuTotalSaleInfo == null)
|
|
{
|
|
skuTotalSaleInfo = insertSkuTotalSaleInfoList.FirstOrDefault(s => s.SkuId == qtOrderSku.SkuId);
|
|
if (skuTotalSaleInfo == null)
|
|
{
|
|
skuTotalSaleInfo = new SkuTotalSaleInfo()
|
|
{
|
|
SkuId = qtOrderSku.SkuId,
|
|
CreateTime = DateTime.Now,
|
|
IsEnabled = true,
|
|
ItemCount = 0,
|
|
ProductId = qtOrderSku.ProductId,
|
|
ShopId = shopId,
|
|
UpdateTime = DateTime.Now
|
|
};
|
|
insertSkuTotalSaleInfoList.Add(skuTotalSaleInfo);
|
|
}
|
|
}
|
|
else if (!updateSkuTotalSaleInfoList.Any(s => s.SkuId == qtOrderSku.SkuId))
|
|
{
|
|
updateSkuTotalSaleInfoList.Add(skuTotalSaleInfo);
|
|
}
|
|
skuTotalSaleInfo.ItemCount += qtOrderSku.Quantity;
|
|
}
|
|
#endregion
|
|
|
|
#region 统计spu销量
|
|
{
|
|
var spuTotalSaleInfo = dbSpuTotalSaleInfoList.FirstOrDefault(s => s.ProductId == qtOrderSku.ProductId);
|
|
if (spuTotalSaleInfo == null)
|
|
{
|
|
spuTotalSaleInfo = insertSpuTotalSaleInfoList.FirstOrDefault(s => s.ProductId == qtOrderSku.ProductId);
|
|
if (spuTotalSaleInfo == null)
|
|
{
|
|
spuTotalSaleInfo = new SpuTotalSaleInfo()
|
|
{
|
|
CreateTime = DateTime.Now,
|
|
IsEnabled = true,
|
|
ItemCount = 0,
|
|
ProductId = qtOrderSku.ProductId,
|
|
ShopId = shopId,
|
|
UpdateTime = DateTime.Now,
|
|
LastOptimizationItemCount = 0
|
|
};
|
|
insertSpuTotalSaleInfoList.Add(spuTotalSaleInfo);
|
|
}
|
|
}
|
|
else if (!updateSpuTotalSaleInfoList.Any(s => s.ProductId == qtOrderSku.ProductId))
|
|
{
|
|
updateSpuTotalSaleInfoList.Add(spuTotalSaleInfo);
|
|
}
|
|
spuTotalSaleInfo.ItemCount += qtOrderSku.Quantity;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 检查待议价任务
|
|
{
|
|
if (waitToCheckSkuSaleOrderList.Count() > 0)
|
|
{
|
|
var spuIdList = waitToCheckSkuSaleOrderList.SelectMany(o => o.OrderSkuList.Select(osku => osku.ProductId)).Distinct().ToList();
|
|
|
|
////没有完成首次采购的spu
|
|
//var noFisrstPurchasedSpuList = dbSpuTotalSaleInfoList.Union(insertSpuTotalSaleInfoList)
|
|
// .Where(s => s.IsFirstPurchaseCompleted == false)
|
|
// .Select(s => s.ProductId)
|
|
// .ToList();
|
|
|
|
//之前没有销量的spu
|
|
var noFisrstPurchasedSpuList = insertSpuTotalSaleInfoList.Select(s => s.ProductId).ToList();
|
|
|
|
//查询已存在未结束的优化任务
|
|
var dbSpuOptimizationTaskList = fsql.Select<SpuOptimizationTask>()
|
|
.Where(t => t.ShopId == shopId &&
|
|
t.IsOptimizationCompleted == false &&
|
|
spuIdList.Contains(t.ProductId))
|
|
.ToList();
|
|
|
|
|
|
if (noFisrstPurchasedSpuList.Count() > 0)
|
|
{
|
|
var bargainTeamList = venderBusiness.GetYiJiaGroup(); //获取议价组
|
|
var shopList = venderBusiness.GetShopList(platform: Enums.Platform.京东);
|
|
var bargainTeamIdList = bargainTeamList.Select(t => t.Id).ToList();
|
|
var waitToCompetitiveTenderSchemeList = fsql.Select<PurchaseScheme>()
|
|
.Where(ps => bargainTeamIdList.Contains(ps.BelongBargainTeamId) &&
|
|
spuIdList.Contains(ps.ProductId))
|
|
.ToList(); //需要参与竞标采购方案
|
|
|
|
var waitToCompetitiveTenderSchemeIdList = waitToCompetitiveTenderSchemeList.Select(ps => ps.Id).ToList();
|
|
var waitToCompetitiveTenderSchemePurchaserList = fsql.Select<PurchaseSchemeProduct>()
|
|
.Where(psp => waitToCompetitiveTenderSchemeIdList.Contains(psp.SkuPurchaseSchemeId))
|
|
.GroupBy(psp => new { psp.SkuPurchaseSchemeId, psp.PurchaserId })
|
|
.ToList(g => new { g.Key.SkuPurchaseSchemeId, g.Key.PurchaserId }); //需要参与竞标的采购商
|
|
|
|
|
|
var waitToCheckOrderSpuGroups = waitToCheckSkuSaleOrderList.SelectMany(o => o.OrderSkuList).GroupBy(osku => osku.ProductId);
|
|
|
|
foreach (var spuGroup in waitToCheckOrderSpuGroups)
|
|
{
|
|
if (noFisrstPurchasedSpuList.Contains(spuGroup.Key) &&
|
|
!dbSpuOptimizationTaskList.Any(t => t.ProductId == spuGroup.Key) &&
|
|
!insertSpuOptimizationTaskList.Any(t => t.ProductId == spuGroup.Key))
|
|
{
|
|
var includeSpuOrderList = waitToCheckSkuSaleOrderList.Where(o => o.OrderSkuList.Any(osku => osku.ProductId == spuGroup.Key));
|
|
|
|
var sourceShopName = string.Empty;
|
|
long sourceShopId = 0;
|
|
//拳探sku-京东sku下单关系映射表
|
|
var mappingQT_JDSKUDictionary = new Dictionary<string, string>();
|
|
|
|
#region 解析来源店铺数据
|
|
foreach (var waitCheckOrder in includeSpuOrderList)
|
|
{
|
|
if (!string.IsNullOrEmpty(waitCheckOrder.Extended))
|
|
{
|
|
try
|
|
{
|
|
var jobject = JObject.Parse(waitCheckOrder.Extended);
|
|
sourceShopName = jobject.Value<string>("SourceShopName");
|
|
|
|
if (jobject.ContainsKey("BelongSkus"))
|
|
{
|
|
var jbelongSkus = jobject["BelongSkus"] as JArray;
|
|
foreach (var j in jbelongSkus)
|
|
{
|
|
var skuId = j.Value<string>("SkuId");
|
|
var belongSkuId = j.Value<string>("BelongSkuId");
|
|
if (!mappingQT_JDSKUDictionary.ContainsKey(skuId))
|
|
mappingQT_JDSKUDictionary.TryAdd(skuId, belongSkuId);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
|
|
}
|
|
}
|
|
}
|
|
if (!string.IsNullOrEmpty(sourceShopName))
|
|
{
|
|
var belongShop = shopList.FirstOrDefault(s => s.ShopName == sourceShopName);
|
|
if (belongShop != null)
|
|
sourceShopId = long.Parse(belongShop.ShopId);
|
|
}
|
|
#endregion
|
|
|
|
#region 读取JDSKU预估金额
|
|
var jdskus = mappingQT_JDSKUDictionary.Values.ToList();
|
|
var jdskuRecentCostList = fsqlManager.BBWYCfsql.Select<SkuRecentCost>(jdskus).ToList();
|
|
#endregion
|
|
|
|
#region 处理SKU分组
|
|
var skuGroups = spuGroup.GroupBy(osku => osku.SkuId).ToList();
|
|
var skuIdList = skuGroups.Select(g => g.Key).ToList();
|
|
#endregion
|
|
|
|
#region 创建SPU优化任务
|
|
var spuOptimizationTask = new SpuOptimizationTask()
|
|
{
|
|
Id = idGenerator.NewLong(),
|
|
BelongShopId = sourceShopId,
|
|
BelongShopName = sourceShopName,
|
|
CompletionTime = null,
|
|
CreateTime = DateTime.Now,
|
|
IsOptimizationCompleted = false,
|
|
LastOptimizationTime = null,
|
|
ProductId = spuGroup.Key,
|
|
ShopId = shopId,
|
|
ProductTitle = SubstringProductTitleFromSku(spuGroup.FirstOrDefault()?.ProductTitle),
|
|
TriggerOptimizationReason = Enums.TriggerOptimizationReason.首次采购,
|
|
PreSkuCount = skuGroups.Count(),
|
|
PreItemCount = 0,
|
|
PrePurchaseAmount = 0M
|
|
};
|
|
insertSpuOptimizationTaskList.Add(spuOptimizationTask);
|
|
#endregion
|
|
|
|
#region 创建SKU优化任务
|
|
foreach (var skuGroup in skuGroups)
|
|
{
|
|
mappingQT_JDSKUDictionary.TryGetValue(skuGroup.Key, out string jdSkuId);
|
|
var preItemCount = skuGroup.Sum(osku => osku.Quantity);
|
|
var prePurchaseAmount = 0M;
|
|
if (!string.IsNullOrEmpty(jdSkuId))
|
|
{
|
|
var jdSkuRecentCost = jdskuRecentCostList.FirstOrDefault(x => x.SkuId == jdSkuId);
|
|
if (jdSkuRecentCost != null)
|
|
{
|
|
prePurchaseAmount = (jdSkuRecentCost.SingleSkuAmount ?? 0M +
|
|
jdSkuRecentCost.SingleFirstFreight ?? 0M +
|
|
jdSkuRecentCost.SingleFreight ?? 0M +
|
|
jdSkuRecentCost.SingleDeliveryFreight ?? 0M +
|
|
jdSkuRecentCost.SingleConsumableAmount ?? 0M +
|
|
jdSkuRecentCost.SingleInStorageAmount ?? 0M +
|
|
jdSkuRecentCost.SingleOutStorageAmount ?? 0M +
|
|
jdSkuRecentCost.SinglePackagingLaborAmount ?? 0M +
|
|
jdSkuRecentCost.SingleOperationAmount ?? 0M) * preItemCount;
|
|
}
|
|
}
|
|
var skuOptimizationTask = new SkuOptimizationTask()
|
|
{
|
|
Id = idGenerator.NewLong(),
|
|
CreateTime = DateTime.Now,
|
|
JDSkuId = jdSkuId,
|
|
PreItemCount = preItemCount,
|
|
SkuId = skuGroup.Key,
|
|
SpuOptimizationTaskId = spuOptimizationTask.Id,
|
|
PrePurchaseAmount = prePurchaseAmount
|
|
};
|
|
insertSkuOptimizationTaskList.Add(skuOptimizationTask);
|
|
|
|
//累计spu优化任务信息
|
|
spuOptimizationTask.PreItemCount += preItemCount;
|
|
spuOptimizationTask.PrePurchaseAmount += prePurchaseAmount;
|
|
}
|
|
#endregion
|
|
|
|
#region 验证过滤条件
|
|
if (spuOptimizationTask.PrePurchaseAmount < 500 && spuOptimizationTask.PreItemCount < 10)
|
|
{
|
|
//移除spu优化任务
|
|
insertSpuOptimizationTaskList.Remove(spuOptimizationTask);
|
|
|
|
//移除sku优化任务
|
|
var waitRemoveSkuTaskList = insertSkuOptimizationTaskList.Where(t => t.SpuOptimizationTaskId == spuOptimizationTask.Id).ToList();
|
|
foreach (var skuTask in waitRemoveSkuTaskList)
|
|
insertSkuOptimizationTaskList.Remove(skuTask);
|
|
waitRemoveSkuTaskList.Clear();
|
|
|
|
continue;
|
|
}
|
|
#endregion
|
|
|
|
#region 暂停一秒区分时间
|
|
Thread.Sleep(1000); //mysql的datetime不支持毫秒级,导致插入时间有误差,暂时用Thread.Sleep补偿
|
|
#endregion
|
|
|
|
#region 创建SPU优化议价组任务
|
|
foreach (var department in bargainTeamList)
|
|
{
|
|
var spuOptimizationBargainTeamTask = new SpuOptimizationBargainTeamTask()
|
|
{
|
|
Id = idGenerator.NewLong(),
|
|
BelongTeamId = department.Id,
|
|
BelongTeamName = department.DepartmentName,
|
|
CompletionTime = null,
|
|
IsOptimizationCompleted = false,
|
|
SpuOptimizationTaskId = spuOptimizationTask.Id
|
|
};
|
|
insertSpuOptimizationBargainTeamTaskList.Add(spuOptimizationBargainTeamTask);
|
|
|
|
#region 创建采购方案竞标任务
|
|
var waitJoinSchemeList = waitToCompetitiveTenderSchemeList.Where(ps => ps.BelongBargainTeamId == department.Id &&
|
|
skuIdList.Contains(ps.SkuId))
|
|
.ToList();
|
|
//var waitJoinSchemeIdList = waitJoinSchemeList.Select(ps => ps.Id).ToList();
|
|
//var waitJonPurchaserList = waitToCompetitiveTenderSchemePurchaserList.Where(x => waitJoinSchemeIdList.Contains(x.SkuPurchaseSchemeId));
|
|
|
|
if (waitJoinSchemeList.Count() > 0)
|
|
{
|
|
insertSpuOptimizationCompetitiveTenderTaskList.AddRange(waitJoinSchemeList.Select(ps => new SpuOptimizationCompetitiveTenderTask()
|
|
{
|
|
Id = idGenerator.NewLong(),
|
|
BargainTeamId = ps.BelongBargainTeamId,
|
|
CreateTime = DateTime.Now,
|
|
IsUpdateQuotedPrice = false,
|
|
SchemeGroupId = ps.SchemeGroupId,
|
|
SchemeId = ps.Id,
|
|
SkuId = ps.SkuId,
|
|
SpuOptimizationBargainTeamTaskId = spuOptimizationBargainTeamTask.Id,
|
|
SpuOptimizationTaskId = spuOptimizationTask.Id,
|
|
UpdateTime = DateTime.Now
|
|
}));
|
|
|
|
//insertSpuOptimizationPurchaserCompetitiveTenderTaskList.AddRange(waitJonPurchaserList.Select(x =>
|
|
//{
|
|
// var ps = waitJoinSchemeList.FirstOrDefault(ps => ps.Id == x.SkuPurchaseSchemeId);
|
|
// return new SpuOptimizationPurchaserCompetitiveTenderTask()
|
|
// {
|
|
// Id = idGenerator.NewLong(),
|
|
// BargainTeamId = ps.BelongBargainTeamId,
|
|
// CreateTime = DateTime.Now,
|
|
// UpdateTime = DateTime.Now,
|
|
// IsUpdateQuotedPrice = false,
|
|
// PurchaserId = x.PurchaserId,
|
|
// SchemeGroupId = ps.SchemeGroupId,
|
|
// SchemeId = ps.Id,
|
|
// SkuId = ps.SkuId,
|
|
// SpuOptimizationTaskId = spuOptimizationTask.Id
|
|
// };
|
|
//}));
|
|
}
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region 创建优化限时任务
|
|
|
|
{
|
|
//判断sku是否首次采购
|
|
//var isFirst = !dbSpuTotalSaleInfoList.Any(s => s.ProductId == spuGroup.Key);
|
|
|
|
insertTimeLimitTaskList.Add(new TimeLimitTask()
|
|
{
|
|
Id = idGenerator.NewLong(),
|
|
CreateTme = DateTime.Now,
|
|
//ExpirationTime = DateTime.Now.AddDays(isFirst ? 2 : 1),
|
|
ExpirationTime = timeLimitRules.CalculateExpirationTime(Enums.TimeLimitTaskType.待议价任务, DateTime.Now),
|
|
//OrderId = o.OrderId,
|
|
//OrderSn = o.OrderSn,
|
|
ShopId = shopId,
|
|
//SkuId = waitCheckOrderSku.SkuId,
|
|
TaskType = Enums.TimeLimitTaskType.待议价任务,
|
|
TaskId = spuOptimizationTask.Id,
|
|
Remark = "首次采购限时任务"
|
|
});
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 检查限时采购任务
|
|
CheckPurchaseTimeLimitTask(shopId, qtOrderList.Items, dbPurchaseTimeLimitTaskList, insertTimeLimitTaskList);
|
|
#endregion
|
|
|
|
fsql.Transaction(() =>
|
|
{
|
|
if (insertOrderList.Count > 0)
|
|
fsql.Insert(insertOrderList).ExecuteAffrows();
|
|
|
|
if (insertOrderSkuList.Count() > 0)
|
|
fsql.Insert(insertOrderSkuList).ExecuteAffrows();
|
|
|
|
if (insertOrderConsigneeList.Count() > 0)
|
|
fsql.Insert(insertOrderConsigneeList).ExecuteAffrows();
|
|
|
|
if (insertTimeLimitTaskList.Count() > 0)
|
|
fsql.Insert(insertTimeLimitTaskList).ExecuteAffrows();
|
|
|
|
if (insertSpuOptimizationTaskList.Count() > 0)
|
|
fsql.Insert(insertSpuOptimizationTaskList).ExecuteAffrows();
|
|
if (insertSkuOptimizationTaskList.Count() > 0)
|
|
fsql.Insert(insertSkuOptimizationTaskList).ExecuteAffrows();
|
|
if (insertSpuOptimizationBargainTeamTaskList.Count() > 0)
|
|
fsql.Insert(insertSpuOptimizationBargainTeamTaskList).ExecuteAffrows();
|
|
if (insertSpuOptimizationCompetitiveTenderTaskList.Count() > 0)
|
|
fsql.Insert(insertSpuOptimizationCompetitiveTenderTaskList).ExecuteAffrows();
|
|
//if (insertSpuOptimizationPurchaserCompetitiveTenderTaskList.Count() > 0)
|
|
// fsql.Insert(insertSpuOptimizationPurchaserCompetitiveTenderTaskList).ExecuteAffrows();
|
|
|
|
if (updateOrderList.Count() > 0)
|
|
foreach (var update in updateOrderList)
|
|
update.ExecuteAffrows();
|
|
|
|
if (deleteTimeLimitTaskOrderIdList.Count() > 0)
|
|
fsql.Delete<TimeLimitTask>().Where(t => deleteTimeLimitTaskOrderIdList.Contains(t.OrderId)).ExecuteAffrows();
|
|
|
|
if (insertSkuTotalSaleInfoList.Count() > 0)
|
|
fsql.Insert(insertSkuTotalSaleInfoList).ExecuteAffrows();
|
|
if (updateSkuTotalSaleInfoList.Count() > 0)
|
|
{
|
|
foreach (var item in updateSkuTotalSaleInfoList)
|
|
fsql.Update<SkuTotalSaleInfo>(item.SkuId).Set(s => s.ItemCount, item.ItemCount)
|
|
.Set(s => s.UpdateTime, DateTime.Now)
|
|
.ExecuteAffrows();
|
|
}
|
|
|
|
if (insertSpuTotalSaleInfoList.Count() > 0)
|
|
fsql.Insert(insertSpuTotalSaleInfoList).ExecuteAffrows();
|
|
if (updateSpuTotalSaleInfoList.Count() > 0)
|
|
{
|
|
foreach (var item in updateSpuTotalSaleInfoList)
|
|
fsql.Update<SpuTotalSaleInfo>(item.ProductId).Set(s => s.ItemCount, item.ItemCount)
|
|
.Set(s => s.UpdateTime, DateTime.Now)
|
|
.ExecuteAffrows();
|
|
}
|
|
|
|
foreach (var key in deductionSkuCountDictionary.Keys)
|
|
fsql.Update<SkuTotalSaleInfo>(key).Set(s => s.ItemCount - deductionSkuCountDictionary[key]).ExecuteAffrows();
|
|
foreach (var key in deductionSpuCountDictionary.Keys)
|
|
fsql.Update<SpuTotalSaleInfo>(key).Set(s => s.ItemCount - deductionSpuCountDictionary[key]).ExecuteAffrows();
|
|
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
nLogManager.GetLogger(loggerName).Error(ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检查限时采购任务
|
|
/// </summary>
|
|
/// <param name="shopId"></param>
|
|
/// <param name="orderList"></param>
|
|
/// <param name="dbTimeLimits"></param>
|
|
/// <param name="insertTimeLimitTasks"></param>
|
|
private void CheckPurchaseTimeLimitTask(long shopId, IList<OP_OrderResponse> orderList, IList<TimeLimitTask> dbTimeLimits, List<TimeLimitTask> insertTimeLimitTasks)
|
|
{
|
|
foreach (var order in orderList)
|
|
{
|
|
if (!order.IsPay || order.PayTime == null || order.OrderState == "-1")
|
|
continue;
|
|
var waitInserTimeLimitTasks = order.OrderSkuList.Where(osku => !dbTimeLimits.Any(x => x.OrderId == order.OrderId && x.SkuId == osku.SkuId))
|
|
.Select(osku => new TimeLimitTask()
|
|
{
|
|
Id = idGenerator.NewLong(),
|
|
CreateTme = DateTime.Now,
|
|
OrderId = order.OrderId,
|
|
OrderSn = order.OrderSn,
|
|
SkuId = osku.SkuId,
|
|
TaskType = Enums.TimeLimitTaskType.采购任务,
|
|
ShopId = shopId,
|
|
ExpirationTime = timeLimitRules.CalculateExpirationTime(Enums.TimeLimitTaskType.采购任务, order.PayTime.Value),
|
|
PayTime = order.PayTime
|
|
}).ToList();
|
|
if (waitInserTimeLimitTasks != null && waitInserTimeLimitTasks.Count() > 0)
|
|
insertTimeLimitTasks.AddRange(waitInserTimeLimitTasks);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 计算采购限时任务的到期时间
|
|
/// </summary>
|
|
/// <param name="payTime">付款时间</param>
|
|
/// <returns></returns>
|
|
private DateTime CalculationPurcashTimeLimitTaskExpirationTime(DateTime payTime)
|
|
{
|
|
var addDays = 0;
|
|
if (payTime.DayOfWeek == DayOfWeek.Sunday ||
|
|
payTime.DayOfWeek == DayOfWeek.Monday ||
|
|
payTime.DayOfWeek == DayOfWeek.Tuesday ||
|
|
payTime.DayOfWeek == DayOfWeek.Wednesday ||
|
|
payTime.DayOfWeek == DayOfWeek.Thursday ||
|
|
payTime.DayOfWeek == DayOfWeek.Friday)
|
|
{
|
|
if (payTime.Hour >= 0 && payTime.Hour < 15)
|
|
addDays = 0; //当日
|
|
else
|
|
addDays = payTime.DayOfWeek == DayOfWeek.Friday ? 2 : 1; //次日,星期五是后天
|
|
}
|
|
else if (payTime.DayOfWeek == DayOfWeek.Saturday)
|
|
addDays = 1;
|
|
return payTime.Date.AddDays(addDays).AddHours(16);
|
|
}
|
|
|
|
private Enums.OrderState? ConvertQuanTanOrderState(string qtOrderState, bool isPay, bool isPurchased)
|
|
{
|
|
/*
|
|
-1、已取消;
|
|
0、待发货;
|
|
1、待收货;
|
|
2、待评价;
|
|
3、已完成;
|
|
*/
|
|
if (qtOrderState == "-1")
|
|
return Enums.OrderState.已取消;
|
|
|
|
if (!isPay)
|
|
return Enums.OrderState.待付款;
|
|
|
|
if (qtOrderState == "0")
|
|
{
|
|
if (!isPurchased)
|
|
return Enums.OrderState.等待采购;
|
|
return Enums.OrderState.待发货;
|
|
}
|
|
|
|
if (qtOrderState == "1")
|
|
return Enums.OrderState.待收货;
|
|
if (qtOrderState == "2")
|
|
return Enums.OrderState.待收货;
|
|
if (qtOrderState == "3")
|
|
return Enums.OrderState.已完成;
|
|
return null;
|
|
}
|
|
|
|
public Enums.TriggerOptimizationReason? GetOptimizationReason(SpuTotalSaleInfo s)
|
|
{
|
|
if (s.IsFirstPurchaseCompleted == false)
|
|
return Enums.TriggerOptimizationReason.首次采购;
|
|
if (s.IsFirstPurchaseCompleted == true &&
|
|
s.IsFirstOptimizationCompleted == false &&
|
|
s.ItemCount - s.FirstPurchaseCompletedItemCount >= 20)
|
|
return Enums.TriggerOptimizationReason.首次优化;
|
|
if (s.IsFirstOptimizationCompleted == true && s.LastOptimizationItemCount != 0 && s.ItemCount * 1.0 / s.LastOptimizationItemCount >= 2)
|
|
return Enums.TriggerOptimizationReason.再次优化;
|
|
return null;
|
|
}
|
|
|
|
private string SubstringProductTitleFromSku(string productTitle)
|
|
{
|
|
if (!string.IsNullOrEmpty(productTitle) && productTitle.Contains(" "))
|
|
productTitle = productTitle.Substring(0, productTitle.LastIndexOf(" "));
|
|
return productTitle;
|
|
}
|
|
}
|
|
}
|
|
|