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 = 1 0 0 ,
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 = 0 M
} ;
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 = 0 M ;
if ( ! string . IsNullOrEmpty ( jdSkuId ) )
{
var jdSkuRecentCost = jdskuRecentCostList . FirstOrDefault ( x = > x . SkuId = = jdSkuId ) ;
if ( jdSkuRecentCost ! = null )
{
prePurchaseAmount = ( jdSkuRecentCost . SingleSkuAmount ? ? 0 M +
jdSkuRecentCost . SingleFirstFreight ? ? 0 M +
jdSkuRecentCost . SingleFreight ? ? 0 M +
jdSkuRecentCost . SingleDeliveryFreight ? ? 0 M +
jdSkuRecentCost . SingleConsumableAmount ? ? 0 M +
jdSkuRecentCost . SingleInStorageAmount ? ? 0 M +
jdSkuRecentCost . SingleOutStorageAmount ? ? 0 M +
jdSkuRecentCost . SinglePackagingLaborAmount ? ? 0 M +
jdSkuRecentCost . SingleOperationAmount ? ? 0 M ) * 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 < 5 0 0 & & spuOptimizationTask . PreItemCount < 1 0 )
{
//移除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 ( 1 0 0 0 ) ; //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 < 1 5 )
addDays = 0 ; //当日
else
addDays = payTime . DayOfWeek = = DayOfWeek . Friday ? 2 : 1 ; //次日,星期五是后天
}
else if ( payTime . DayOfWeek = = DayOfWeek . Saturday )
addDays = 1 ;
return payTime . Date . AddDays ( addDays ) . AddHours ( 1 6 ) ;
}
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 > = 2 0 )
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 ;
}
}
}