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.
661 lines
36 KiB
661 lines
36 KiB
using BBWY.Common.Http;
|
|
using BBWY.Common.Models;
|
|
using BBWY.Server.Business.Extensions;
|
|
using BBWY.Server.Business.PlatformSDK.DataExtension;
|
|
using BBWY.Server.Model;
|
|
using BBWY.Server.Model.Db;
|
|
using BBWY.Server.Model.Dto;
|
|
using FreeSql;
|
|
using Microsoft.Extensions.Caching.Memory;
|
|
using Microsoft.Extensions.Options;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Linq;
|
|
using NLog;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Net.Http;
|
|
using System.Threading.Tasks;
|
|
using Yitter.IdGenerator;
|
|
|
|
namespace BBWY.Server.Business
|
|
{
|
|
public class OrderSyncBusiness : BaseSyncBusiness, IDenpendency
|
|
{
|
|
private IDictionary<Enums.Platform, Action<JArray, long, string, string, string, string, decimal>> syncOrderMethodDic;
|
|
|
|
private IMemoryCache memoryCache;
|
|
|
|
public OrderSyncBusiness(RestApiService restApiService,
|
|
IOptions<GlobalConfig> options,
|
|
NLogManager nLogManager,
|
|
IFreeSql fsql,
|
|
IIdGenerator idGenerator,
|
|
TaskSchedulerManager taskSchedulerManager,
|
|
VenderBusiness venderBusiness,
|
|
IMemoryCache memoryCache,
|
|
YunDingBusiness yunDingBusiness) : base(restApiService,
|
|
options,
|
|
nLogManager,
|
|
fsql,
|
|
idGenerator,
|
|
taskSchedulerManager,
|
|
venderBusiness,
|
|
yunDingBusiness)
|
|
{
|
|
this.memoryCache = memoryCache;
|
|
syncOrderMethodDic = new Dictionary<Enums.Platform, Action<JArray, long, string, string, string, string, decimal>>()
|
|
{
|
|
{ Enums.Platform.京东, SyncJDOrder }
|
|
};
|
|
}
|
|
/// <summary>
|
|
/// 手动同步订单
|
|
/// </summary>
|
|
/// <param name="shopId"></param>
|
|
/// <param name="orderId"></param>
|
|
/// <param name="startTime"></param>
|
|
/// <param name="endTime"></param>
|
|
public void ManualSyncOrder(long shopId, string orderId, DateTime? startTime = null, DateTime? endTime = null)
|
|
{
|
|
var shop = venderBusiness.GetShopByShopId(shopId.ToString());
|
|
SyncOrder(shop, orderId, startTime, endTime, isAuto: false, Enums.SortTimeType.StartTime);
|
|
}
|
|
|
|
private void SyncOrder(ShopResponse shop, string orderId, DateTime? startTime = null, DateTime? endTime = null, bool isAuto = false, Enums.SortTimeType? sortTimeType = null)
|
|
{
|
|
try
|
|
{
|
|
//logger.Info($"订单同步 {shop.ShopName} isAuto {isAuto}");
|
|
if (!syncOrderMethodDic.ContainsKey(shop.PlatformId))
|
|
throw new Exception("不支持的平台");
|
|
var shopId = long.Parse(shop.ShopId);
|
|
var relayAPIHost = GetPlatformRelayAPIHost(shop.PlatformId);
|
|
var orderListApiResult = restApiService.SendRequest(relayAPIHost, "api/PlatformSDK/GetOrderList", new SearchPlatformOrderRequest()
|
|
{
|
|
StartDate = startTime ?? DateTime.Now.AddHours(-3),
|
|
EndDate = endTime ?? DateTime.Now,
|
|
AppKey = shop.AppKey,
|
|
AppSecret = shop.AppSecret,
|
|
AppToken = shop.AppToken,
|
|
PageIndex = 1,
|
|
PageSize = 100,
|
|
Platform = shop.PlatformId,
|
|
JDColType = string.IsNullOrEmpty(shop.ShopType) ? "0" : shop.ShopType,
|
|
//SaveResponseLog = true,
|
|
OrderId = orderId,
|
|
SortTimeType = sortTimeType
|
|
}, GetYunDingRequestHeader(), HttpMethod.Post);
|
|
if (orderListApiResult.StatusCode != System.Net.HttpStatusCode.OK)
|
|
throw new Exception($"获取订单失败 {orderListApiResult.Content}");
|
|
|
|
var orderListResponse = JsonConvert.DeserializeObject<ApiResponse<JArray>>(orderListApiResult.Content);
|
|
if (!orderListResponse.Success)
|
|
throw new Exception($"获取订单失败 {orderListApiResult.Content}");
|
|
|
|
if (orderListResponse.Data == null || orderListResponse.Data.Count == 0)
|
|
return;
|
|
|
|
syncOrderMethodDic[shop.PlatformId](orderListResponse.Data, shopId, relayAPIHost, shop.AppKey, shop.AppSecret, shop.AppToken, shop.PlatformCommissionRatio ?? 0.05M);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
var shopData = JsonConvert.SerializeObject(shop);
|
|
nLogManager.Default().Error(ex, $"SyncOrder ShopData:{shopData}");
|
|
}
|
|
}
|
|
|
|
public void SyncOrderByDate(SyncOrderByDateRequest syncOrderByDateRequest)
|
|
{
|
|
if (fsql.Select<OrderSyncTask>().Where(ost => ost.ShopId == syncOrderByDateRequest.ShopId && ost.State == Enums.OrderSyncState.Running).Any())
|
|
throw new BusinessException("存在未结束的同步任务,请稍后同步");
|
|
syncOrderByDateRequest.EndTime = syncOrderByDateRequest.EndTime.Date.AddDays(1).AddSeconds(-1);
|
|
if ((syncOrderByDateRequest.EndTime - syncOrderByDateRequest.StartTime).Days > 7)
|
|
throw new BusinessException("同步任务时差最长7天");
|
|
|
|
var orderSyncTask = new OrderSyncTask()
|
|
{
|
|
Id = idGenerator.NewLong(),
|
|
ShopId = syncOrderByDateRequest.ShopId,
|
|
State = Enums.OrderSyncState.Running,
|
|
SyncStartTime = syncOrderByDateRequest.StartTime,
|
|
SyncEndTime = syncOrderByDateRequest.EndTime
|
|
};
|
|
fsql.Insert(orderSyncTask).ExecuteAffrows();
|
|
Task.Factory.StartNew(() =>
|
|
{
|
|
var currentStartTime = syncOrderByDateRequest.StartTime;
|
|
var currentEndTime = currentStartTime.AddHours(3);
|
|
var keeploop = true;
|
|
while (keeploop)
|
|
{
|
|
try
|
|
{
|
|
ManualSyncOrder(syncOrderByDateRequest.ShopId, string.Empty, currentStartTime, currentEndTime);
|
|
}
|
|
catch (Exception ex) { }
|
|
finally
|
|
{
|
|
var lessHour = (syncOrderByDateRequest.EndTime - currentEndTime).TotalHours;
|
|
if (lessHour > 3)
|
|
{
|
|
currentStartTime = currentStartTime.AddHours(3);
|
|
currentEndTime = currentEndTime.AddHours(3);
|
|
}
|
|
else if (lessHour > 0 && lessHour < 3)
|
|
{
|
|
currentStartTime = currentEndTime;
|
|
currentEndTime = syncOrderByDateRequest.EndTime;
|
|
}
|
|
else if (lessHour <= 0)
|
|
{
|
|
keeploop = false;
|
|
}
|
|
}
|
|
}
|
|
try
|
|
{
|
|
fsql.Update<OrderSyncTask>(orderSyncTask.Id).Set(ost => ost.State, Enums.OrderSyncState.End).ExecuteAffrows();
|
|
}
|
|
catch (Exception ex) { }
|
|
}, System.Threading.CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.SyncOrderTaskScheduler);
|
|
}
|
|
|
|
private void SyncJDOrder(JArray orderTokenJArray, long shopId, string relayAPIHost, string appKey, string appSecret, string appToken, decimal platformCommissionRatio)
|
|
{
|
|
|
|
var orderTokenList = orderTokenJArray.Where(o => o.Value<decimal>("orderTotalPrice") != 0);
|
|
|
|
var interfaceOrderIdList = orderTokenList.Select(orderJToken => orderJToken.Value<string>("orderId"));
|
|
var interfaceCanceledOrderIdList = orderTokenList.Where(orderJToken => orderJToken.Value<string>("orderState").Equals("TRADE_CANCELED"))
|
|
.Select(orderJToken => orderJToken.Value<string>("orderId")); //接口查询结果中取消状态的订单Id
|
|
|
|
var dbOrderList = fsql.Select<Order>().Where(o => interfaceOrderIdList.Contains(o.Id)).ToList(o => new Order()
|
|
{
|
|
Id = o.Id,
|
|
OrderState = o.OrderState,
|
|
StorageType = o.StorageType
|
|
}); //数据库订单
|
|
var dbOrderConsigneeList = fsql.Select<OrderConsignee>().Where(oc => interfaceOrderIdList.Contains(oc.OrderId)).ToList(); //数据库订单收货信息
|
|
var dbOrderCostList = fsql.Select<OrderCost>().Where(oc => interfaceOrderIdList.Contains(oc.OrderId)).ToList(); //数据库订单成本信息
|
|
var dbOrderCouponList = fsql.Select<OrderCoupon>().Where(oc => interfaceOrderIdList.Contains(oc.OrderId)).ToList(); //数据库订单优惠信息
|
|
|
|
List<OrderCostDetail> dbOrderCostDetailList = null; //数据库成本明细
|
|
if (interfaceCanceledOrderIdList.Count() > 0 &&
|
|
dbOrderList.Any(dbOrder => interfaceCanceledOrderIdList.Contains(dbOrder.Id) && dbOrder.OrderState != Enums.OrderState.已取消))
|
|
{
|
|
dbOrderCostDetailList = fsql.Select<OrderCostDetail>().Where(ocd => interfaceCanceledOrderIdList.Contains(ocd.OrderId) && ocd.IsEnabled == true).ToList();
|
|
}
|
|
|
|
var orderSkuIds = new List<string>();
|
|
foreach (var orderJToken in orderTokenList)
|
|
{
|
|
var itemInfoList = orderJToken["itemInfoList"].Where(skuJToken => skuJToken.Value<decimal>("jdPrice") != 0M).Select(skuJToken => skuJToken.Value<string>("skuId"));
|
|
foreach (var skuId in itemInfoList)
|
|
{
|
|
if (!orderSkuIds.Contains(skuId))
|
|
orderSkuIds.Add(skuId);
|
|
}
|
|
}
|
|
var dbPurchaseOrderList = fsql.Select<PurchaseOrder>().Where(po => po.RemainingQuantity != 0 && orderSkuIds.Contains(po.SkuId)).ToList(); //数据库采购单
|
|
orderSkuIds.Clear();
|
|
|
|
#region 数据库操作
|
|
List<Order> insertOrderList = new List<Order>();
|
|
List<OrderConsignee> insertOrderConsigneeList = new List<OrderConsignee>();
|
|
List<OrderCost> insertOrderCostList = new List<OrderCost>();
|
|
List<OrderCostDetail> insertOrderCostDetailList = new List<OrderCostDetail>();
|
|
List<OrderSku> insertOrderSkuList = new List<OrderSku>();
|
|
List<OrderCoupon> insertOrderCouponList = new List<OrderCoupon>();
|
|
|
|
IList<IUpdate<Order>> updateOrderList = new List<IUpdate<Order>>();
|
|
IList<IUpdate<PurchaseOrder>> updatePurchaseOrderList = new List<IUpdate<PurchaseOrder>>();
|
|
#endregion
|
|
|
|
foreach (var orderJToken in orderTokenList)
|
|
{
|
|
var orderId = orderJToken.Value<string>("orderId");
|
|
var dbOrder = dbOrderList.FirstOrDefault(o => o.Id == orderId);
|
|
var isNewOrder = dbOrder == null;
|
|
SDCalculationCostRequest sDCalculationCostRequest = null; //SD信息埋点
|
|
|
|
#region 订单基本信息
|
|
var buyerRemark = orderJToken.Value<string>("orderRemark");
|
|
var venderRemark = orderJToken.Value<string>("venderRemark");
|
|
var modifyTime = orderJToken.Value<DateTime?>("modified");
|
|
var endTime = orderJToken.Value<DateTime?>("orderEndTime");
|
|
var waybillNo = orderJToken.Value<string>("waybill");
|
|
if (dbOrder == null)
|
|
{
|
|
dbOrder = new Order()
|
|
{
|
|
Id = orderId,
|
|
BuyerRemark = buyerRemark,
|
|
VenderRemark = venderRemark,
|
|
FreightPrice = orderJToken.Value<decimal>("freightPrice"),
|
|
EndTime = endTime,
|
|
StartTime = orderJToken.Value<DateTime>("orderStartTime"),
|
|
ModifyTime = modifyTime,
|
|
OrderPayment = orderJToken.Value<decimal>("orderPayment"),
|
|
SellerPreferentialAmount = orderJToken.Value<decimal>("sellerDiscount"),
|
|
OrderSellerPrice = orderJToken.Value<decimal>("orderSellerPrice"),
|
|
OrderTotalPrice = orderJToken.Value<decimal>("orderTotalPrice"),
|
|
OrderType = (Enums.OrderType)orderJToken.Value<int>("orderType"),
|
|
Platform = Enums.Platform.京东,
|
|
ShopId = shopId,
|
|
//VenderId = orderJToken.Value<long>("venderId"),
|
|
WaybillNo = waybillNo,
|
|
StoreOrder = orderJToken.Value<string>("storeOrder") ?? string.Empty,
|
|
StoreId = orderJToken.Value<string>("storeId")
|
|
};
|
|
|
|
if (memoryCache.TryGetValue(orderId, out sDCalculationCostRequest))
|
|
{
|
|
dbOrder.StorageType = Enums.StorageType.SD;
|
|
dbOrder.SDType = sDCalculationCostRequest.SDType;
|
|
dbOrder.Flag = sDCalculationCostRequest.Flag;
|
|
if (!string.IsNullOrEmpty(sDCalculationCostRequest.VenderRemark))
|
|
dbOrder.VenderRemark = sDCalculationCostRequest.VenderRemark;
|
|
dbOrder.SDKey = sDCalculationCostRequest.SDKey;
|
|
dbOrder.SDPayBillNo = sDCalculationCostRequest.SDPayBillNo;
|
|
dbOrder.SDOperator = sDCalculationCostRequest.SDOperator;
|
|
dbOrder.SDPayChannel = sDCalculationCostRequest.SDPayChannel;
|
|
}
|
|
|
|
if (dbOrder.StoreOrder.Contains("京仓"))
|
|
dbOrder.StorageType = Enums.StorageType.京仓;
|
|
else if (dbOrder.StoreOrder.Contains("云仓"))
|
|
dbOrder.StorageType = Enums.StorageType.云仓;
|
|
|
|
var payType = orderJToken.Value<string>("payType");
|
|
if (payType.Contains("-"))
|
|
dbOrder.PayType = (Enums.PayType)Convert.ToInt32(payType.Substring(0, 1));
|
|
|
|
insertOrderList.Add(dbOrder);
|
|
|
|
#region OrderSku
|
|
var orderSkuList = orderJToken["itemInfoList"].Where(skuJToken => skuJToken.Value<decimal>("jdPrice") != 0M).Select(skuToken => new OrderSku()
|
|
{
|
|
Id = idGenerator.NewLong(),
|
|
ItemTotal = skuToken.Value<int>("itemTotal"),
|
|
Price = skuToken.Value<decimal>("jdPrice"),
|
|
ProductId = skuToken.Value<string>("wareId"),
|
|
Title = skuToken.Value<string>("skuName").SimplifySkuName(),
|
|
ProductNo = skuToken.Value<string>("productNo"),
|
|
CreateTime = DateTime.Now,
|
|
OrderId = orderId,
|
|
SkuId = skuToken.Value<string>("skuId")
|
|
}).ToList();
|
|
insertOrderSkuList.AddRange(orderSkuList);
|
|
#endregion
|
|
}
|
|
#endregion
|
|
|
|
#region 收货人信息
|
|
if (dbOrderConsigneeList.FirstOrDefault(oc => oc.OrderId == orderId) == null)
|
|
{
|
|
var orderConsignee = new OrderConsignee()
|
|
{
|
|
OrderId = orderId,
|
|
//Address = orderJToken["consigneeInfo"].Value<string>("fullAddress"),
|
|
//ContactName = orderJToken["consigneeInfo"].Value<string>("fullname"),
|
|
//Mobile = orderJToken["consigneeInfo"].Value<string>("mobile"),
|
|
//TelePhone = orderJToken["consigneeInfo"].Value<string>("telephone"),
|
|
City = orderJToken["consigneeInfo"].Value<string>("city"),
|
|
Province = orderJToken["consigneeInfo"].Value<string>("province"),
|
|
County = orderJToken["consigneeInfo"].Value<string>("county"),
|
|
Town = orderJToken["consigneeInfo"].Value<string>("town"),
|
|
IsDecode = false,
|
|
CreateTime = DateTime.Now
|
|
};
|
|
insertOrderConsigneeList.Add(orderConsignee);
|
|
}
|
|
#endregion
|
|
|
|
#region 订单优惠
|
|
if (!dbOrderCouponList.Any(oc => oc.OrderId == orderId))
|
|
{
|
|
var orderCouponJArray = (JArray)orderJToken["couponDetailList"];
|
|
if (orderCouponJArray.HasValues)
|
|
{
|
|
foreach (var orderCouponJToken in orderCouponJArray)
|
|
{
|
|
var couponType = orderCouponJToken.Value<string>("couponType");
|
|
if (string.IsNullOrEmpty(couponType))
|
|
continue;
|
|
dbOrder.PreferentialAmount += orderCouponJToken.Value<decimal>("couponPrice");
|
|
insertOrderCouponList.Add(new OrderCoupon()
|
|
{
|
|
Id = idGenerator.NewLong(),
|
|
SkuId = orderCouponJToken.Value<string>("skuId"),
|
|
OrderId = orderId,
|
|
CreateTime = DateTime.Now,
|
|
CouponType = couponType,
|
|
CouponPrice = orderCouponJToken.Value<decimal>("couponPrice")
|
|
});
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 订单状态转换
|
|
var jdOrderState = orderJToken.Value<string>("orderState");
|
|
Enums.OrderState? orderState = null;
|
|
|
|
#region SOP状态翻译
|
|
if (jdOrderState.Equals("NOT_PAY")) //未付款
|
|
{
|
|
orderState = Enums.OrderState.待付款;
|
|
}
|
|
else if (jdOrderState.Equals("WAIT_SELLER_STOCK_OUT")) //等待出库
|
|
{
|
|
orderState = Enums.OrderState.等待采购;
|
|
if (dbOrder.StorageType != null)
|
|
orderState = Enums.OrderState.待出库;
|
|
}
|
|
else if (jdOrderState.Equals("WAIT_GOODS_RECEIVE_CONFIRM"))
|
|
{
|
|
orderState = Enums.OrderState.待收货;
|
|
}
|
|
else if (jdOrderState.Equals("FINISHED_L"))
|
|
{
|
|
orderState = Enums.OrderState.已完成;
|
|
}
|
|
else if (jdOrderState.Equals("LOCKED"))
|
|
{
|
|
orderState = Enums.OrderState.锁定;
|
|
}
|
|
else if (jdOrderState.Equals("TRADE_CANCELED"))
|
|
{
|
|
orderState = Enums.OrderState.已取消;
|
|
}
|
|
else if (jdOrderState.Equals("POP_ORDER_PAUSE") || jdOrderState.Equals("PAUSE"))
|
|
{
|
|
orderState = Enums.OrderState.暂停;
|
|
}
|
|
#endregion
|
|
|
|
#region FBP状态翻译
|
|
else if (jdOrderState.Equals("DengDaiDaYin") || jdOrderState.Equals("DengDaiChuKu") || jdOrderState.Equals("DengDaiDaBao") || jdOrderState.Equals("DengDaiFaHuo"))
|
|
{
|
|
orderState = Enums.OrderState.待出库;
|
|
}
|
|
else if (jdOrderState.Equals("DengDaiQueRenShouHuo"))
|
|
{
|
|
orderState = Enums.OrderState.待收货;
|
|
}
|
|
else if (jdOrderState.Equals("WanCheng"))
|
|
{
|
|
orderState = Enums.OrderState.已完成;
|
|
}
|
|
else if (jdOrderState.Equals("SuoDing") || jdOrderState.Equals("LOCKED"))
|
|
{
|
|
orderState = Enums.OrderState.锁定;
|
|
}
|
|
else if (jdOrderState.Equals("TRADE_CANCELED"))
|
|
{
|
|
orderState = Enums.OrderState.已取消;
|
|
}
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region 取消订单恢复库存
|
|
if (orderState == Enums.OrderState.已取消 &&
|
|
!isNewOrder &&
|
|
dbOrder.OrderState != Enums.OrderState.已取消 &&
|
|
dbOrder.StorageType != Enums.StorageType.SD &&
|
|
dbOrder.StorageType != Enums.StorageType.代发)
|
|
{
|
|
var currentOrderCostDetailList = dbOrderCostDetailList.Where(ocd => ocd.OrderId == orderId);
|
|
if (currentOrderCostDetailList.Count() > 0)
|
|
{
|
|
foreach (var orderCostDetail in currentOrderCostDetailList)
|
|
{
|
|
var updateSql = fsql.Update<PurchaseOrder>(orderCostDetail.PurchaseOrderPKId)
|
|
.Set(po => po.RemainingQuantity + orderCostDetail.DeductionQuantity);
|
|
updatePurchaseOrderList.Add(updateSql);
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 扣减库存, 计算成本
|
|
if (dbOrder.StorageType != null &&
|
|
dbOrder.StorageType != Enums.StorageType.代发 &&
|
|
orderState != null &&
|
|
orderState != Enums.OrderState.待付款 &&
|
|
orderState != Enums.OrderState.已取消)
|
|
{
|
|
var orderCost = dbOrderCostList.FirstOrDefault(oc => oc.OrderId == dbOrder.Id);
|
|
if (orderCost == null)
|
|
{
|
|
if (isNewOrder && dbOrder.StorageType == Enums.StorageType.SD && sDCalculationCostRequest != null)
|
|
{
|
|
//检查SD埋点
|
|
if (sDCalculationCostRequest.PlatformCommissionRatio == 0M)
|
|
sDCalculationCostRequest.PlatformCommissionRatio = 0.05M;
|
|
orderCost = new OrderCost()
|
|
{
|
|
OrderId = sDCalculationCostRequest.OrderId,
|
|
PlatformCommissionRatio = sDCalculationCostRequest.PlatformCommissionRatio,
|
|
PreferentialAmount = dbOrder.PreferentialAmount,
|
|
Profit = 0,
|
|
DeliveryExpressFreight = sDCalculationCostRequest.DeliveryExpressFreight,
|
|
CreateTime = DateTime.Now,
|
|
IsManualEdited = true,
|
|
SDCommissionAmount = sDCalculationCostRequest.SDCommissionAmount,
|
|
SDOrderAmount = sDCalculationCostRequest.SDOrderAmount
|
|
};
|
|
orderCost.CalculationSDOrderProfitAndCost(dbOrder, null);
|
|
insertOrderCostList.Add(orderCost);
|
|
}
|
|
else if (!fsql.Select<OrderCost>(dbOrder.Id).Any()) //再查询一次数据库,以防同步开始执行后被人为操作扣减库存,造成重复扣减库存
|
|
{
|
|
var orderSkuJArray = orderJToken["itemInfoList"].Where(skuJToken => skuJToken.Value<decimal>("jdPrice") != 0M);
|
|
if (orderSkuJArray != null && orderSkuJArray.Count() > 0)
|
|
{
|
|
var orderCostPurchaseAmount = 0M;
|
|
var orderDeliveryExpressFreight = 0M; //发货总运费,sku购买数量第二个开始半价
|
|
|
|
#region 扣减库存
|
|
foreach (var orderSkuJToken in orderSkuJArray)
|
|
{
|
|
var orderSkuId = orderSkuJToken.Value<string>("skuId");
|
|
var itemTotal = orderSkuJToken.Value<int>("itemTotal"); //sku购买数量
|
|
var itemPrice = orderSkuJToken.Value<decimal>("jdPrice"); //sku单价
|
|
var isReduceMultiTimes = false; //是否多次扣减库存
|
|
while (itemTotal != 0)
|
|
{
|
|
var purchaseOrder = dbPurchaseOrderList.FirstOrDefault(po => po.StorageType == dbOrder.StorageType &&
|
|
po.RemainingQuantity != 0 &&
|
|
po.SkuId == orderSkuId);
|
|
if (purchaseOrder == null)
|
|
break; //没有库存了
|
|
|
|
//本次扣减量
|
|
var deductionQuantity = purchaseOrder.RemainingQuantity >= itemTotal ? itemTotal : purchaseOrder.RemainingQuantity;
|
|
//本次扣减量的采购成本
|
|
var currentPurchaseAmount = purchaseOrder.UnitCost * deductionQuantity;
|
|
//本次扣减量的发货运费
|
|
var currentSkuDeliveryFreight = isReduceMultiTimes ?
|
|
(purchaseOrder.SingleDeliveryFreight / 2 * deductionQuantity) :
|
|
(purchaseOrder.SingleDeliveryFreight + purchaseOrder.SingleDeliveryFreight / 2 * (deductionQuantity - 1));
|
|
|
|
purchaseOrder.RemainingQuantity -= deductionQuantity;
|
|
itemTotal -= deductionQuantity;
|
|
|
|
//累计采购成本
|
|
orderCostPurchaseAmount += currentPurchaseAmount;
|
|
//累计发货运费(销售运费)
|
|
orderDeliveryExpressFreight += currentSkuDeliveryFreight;
|
|
isReduceMultiTimes = true;
|
|
|
|
var updateSql = fsql.Update<PurchaseOrder>(purchaseOrder.Id).Set(po => po.RemainingQuantity - deductionQuantity);
|
|
updatePurchaseOrderList.Add(updateSql);
|
|
|
|
var orderCostDetail = new OrderCostDetail()
|
|
{
|
|
Id = idGenerator.NewLong(),
|
|
OrderId = orderId,
|
|
ProductId = orderSkuJToken.Value<string>("wareId"),
|
|
SkuId = orderSkuId,
|
|
CreateTime = DateTime.Now,
|
|
PurchaseOrderPKId = purchaseOrder.Id,
|
|
//UnitCost = purchaseOrder.UnitCost,
|
|
DeductionQuantity = deductionQuantity,
|
|
DeliveryExpressFreight = currentSkuDeliveryFreight,
|
|
//TotalCost = currentPurchaseAmount,
|
|
ConsumableAmount = purchaseOrder.SingleConsumableAmount * deductionQuantity,
|
|
FirstFreight = purchaseOrder.SingleFirstFreight * deductionQuantity,
|
|
//OperationAmount = purchaseOrder.SingleOperationAmount * deductionQuantity,
|
|
InStorageAmount = purchaseOrder.SingleInStorageAmount * deductionQuantity,
|
|
OutStorageAmount = purchaseOrder.SingleOutStorageAmount * deductionQuantity,
|
|
PurchaseFreight = purchaseOrder.SingleFreight * deductionQuantity,
|
|
SkuAmount = purchaseOrder.SingleSkuAmount * deductionQuantity,
|
|
StorageAmount = purchaseOrder.SingleStorageAmount * deductionQuantity,
|
|
IsEnabled = true
|
|
};
|
|
orderCostDetail.SkuGrossProfit = itemPrice * deductionQuantity -
|
|
(orderCostDetail.TotalCost + orderCostDetail.DeliveryExpressFreight);
|
|
insertOrderCostDetailList.Add(orderCostDetail);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 计算成本
|
|
orderCost = new OrderCost()
|
|
{
|
|
OrderId = orderId,
|
|
PlatformCommissionRatio = platformCommissionRatio,
|
|
PreferentialAmount = dbOrder.PreferentialAmount,
|
|
Profit = 0,
|
|
PurchaseAmount = orderCostPurchaseAmount,
|
|
DeliveryExpressFreight = orderDeliveryExpressFreight,
|
|
CreateTime = DateTime.Now
|
|
};
|
|
orderCost.CalculationOrderProfitAndCost(dbOrder, null);
|
|
//orderCost.PlatformCommissionAmount = dbOrder.OrderSellerPrice * orderCost.PlatformCommissionRatio;
|
|
//orderCost.Profit = dbOrder.OrderSellerPrice +
|
|
// dbOrder.FreightPrice -
|
|
// orderCost.PurchaseAmount -
|
|
// orderCost.DeliveryExpressFreight -
|
|
// orderCost.PlatformCommissionAmount;
|
|
insertOrderCostList.Add(orderCost);
|
|
#endregion
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region 检查订单信息是否变化
|
|
if (isNewOrder)
|
|
{
|
|
dbOrder.OrderState = orderState;
|
|
}
|
|
else if ((orderState != null && orderState != dbOrder.OrderState) ||
|
|
buyerRemark != dbOrder.BuyerRemark ||
|
|
venderRemark != dbOrder.VenderRemark ||
|
|
modifyTime != dbOrder.ModifyTime ||
|
|
endTime != dbOrder.EndTime ||
|
|
waybillNo != dbOrder.WaybillNo)
|
|
{
|
|
var updateSql = fsql.Update<Order>(orderId).SetIf(orderState != null && orderState != dbOrder.OrderState, o => o.OrderState, orderState)
|
|
.SetIf(buyerRemark != dbOrder.BuyerRemark, o => o.BuyerRemark, buyerRemark)
|
|
.SetIf(venderRemark != dbOrder.VenderRemark, o => o.VenderRemark, venderRemark)
|
|
.SetIf(modifyTime != dbOrder.ModifyTime, o => o.ModifyTime, modifyTime)
|
|
.SetIf(endTime != dbOrder.EndTime, o => o.EndTime, modifyTime)
|
|
.SetIf(waybillNo != dbOrder.WaybillNo, o => o.WaybillNo, waybillNo);
|
|
updateOrderList.Add(updateSql);
|
|
}
|
|
#endregion
|
|
|
|
#region 删除SD埋点
|
|
try
|
|
{
|
|
if (sDCalculationCostRequest != null)
|
|
memoryCache.Remove(orderId);
|
|
}
|
|
catch { }
|
|
#endregion
|
|
|
|
}
|
|
|
|
#region 补齐sku logo
|
|
if (insertOrderSkuList.Count() > 0)
|
|
{
|
|
foreach (var orderSku in insertOrderSkuList)
|
|
{
|
|
if (!orderSkuIds.Contains(orderSku.SkuId))
|
|
orderSkuIds.Add(orderSku.SkuId);
|
|
}
|
|
|
|
var orderSkuRequestCount = (orderSkuIds.Count() - 1) / 50 + 1; //sku最多一次请求50条
|
|
for (var i = 0; i < orderSkuRequestCount; i++)
|
|
{
|
|
var orderSkuIdString = string.Join(",", orderSkuIds.Skip(i * 50).Take(50));
|
|
var skuHttpResult = restApiService.SendRequest(relayAPIHost, "Api/PlatformSDK/GetSimpleProductSkuList", new SearchProductSkuRequest()
|
|
{
|
|
AppKey = appKey,
|
|
AppSecret = appSecret,
|
|
AppToken = appToken,
|
|
Platform = Enums.Platform.京东,
|
|
Sku = orderSkuIdString
|
|
}, GetYunDingRequestHeader(), HttpMethod.Post);
|
|
if (skuHttpResult.StatusCode != System.Net.HttpStatusCode.OK)
|
|
continue;
|
|
var skuResponse = JsonConvert.DeserializeObject<ApiResponse<IList<SimpleProductSkuResponse>>>(skuHttpResult.Content);
|
|
if (!skuResponse.Success)
|
|
continue;
|
|
foreach (var sku in skuResponse.Data)
|
|
{
|
|
var insertSkus = insertOrderSkuList.Where(orderSku => orderSku.SkuId == sku.Id);
|
|
foreach (var insertSku in insertSkus) { insertSku.Logo = sku.Logo; }
|
|
}
|
|
}
|
|
}
|
|
#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 (insertOrderCostList.Count() > 0)
|
|
fsql.Insert(insertOrderCostList).ExecuteAffrows();
|
|
if (insertOrderCostDetailList.Count() > 0)
|
|
fsql.Insert(insertOrderCostDetailList).ExecuteAffrows();
|
|
if (insertOrderCouponList.Count() > 0)
|
|
fsql.Insert(insertOrderCouponList).ExecuteAffrows();
|
|
|
|
if (updatePurchaseOrderList.Count() > 0)
|
|
{
|
|
foreach (var update in updatePurchaseOrderList)
|
|
update.ExecuteAffrows();
|
|
}
|
|
|
|
if (updateOrderList.Count() > 0)
|
|
{
|
|
foreach (var update in updateOrderList)
|
|
update.ExecuteAffrows();
|
|
}
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// 同步所有店铺的订单
|
|
/// </summary>
|
|
public void SyncAllShopOrder()
|
|
{
|
|
var shopList = venderBusiness.GetShopList();
|
|
foreach (var shop in shopList)
|
|
{
|
|
Task.Factory.StartNew(() => SyncOrder(shop, string.Empty, isAuto: true), System.Threading.CancellationToken.None, TaskCreationOptions.LongRunning, taskSchedulerManager.SyncOrderTaskScheduler);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|