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.Concurrent;
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, timeOutSeconds: 120);
                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)
        {
            //if (shopId == 10388155)
            //{
            //    nLogManager.GetLogger("订单同步-布莱特玩具专营店").Info(JsonConvert.SerializeObject(orderTokenJArray));
            //}

            #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>();

            List<GiftOrder> insertGiftOrderList = new List<GiftOrder>();
            List<GiftOrderSku> insertGiftOrderSkuList = new List<GiftOrderSku>();
            IList<IUpdate<GiftOrder>> updateGiftOrderList = new List<IUpdate<GiftOrder>>();

            IList<IUpdate<Order>> updateOrderList = new List<IUpdate<Order>>();
            IList<IUpdate<PurchaseOrder>> updatePurchaseOrderList = new List<IUpdate<PurchaseOrder>>();
            #endregion

            #region 赠品
            var giftOrderJArray = orderTokenJArray.Where(o => o.Value<decimal>("orderTotalPrice") == 0M);
            if (giftOrderJArray.Count() > 0)
            {
                var giftOrderIds = giftOrderJArray.Select(orderJToken => orderJToken.Value<string>("orderId")).ToArray();
                var dbGiftOrderList = fsql.Select<GiftOrder>(giftOrderIds).ToList();
                var dbGiftOrderIds = dbGiftOrderList.Select(go => go.Id).ToList();

                var exceptIds = giftOrderIds.Except(dbGiftOrderIds);
                if (exceptIds.Count() > 0)
                {
                    var newGiftOrderJArray = giftOrderJArray.Where(o => exceptIds.Contains(o.Value<string>("orderId")));
                    foreach (var orderJToken in newGiftOrderJArray)
                    {
                        var orderState = ConvertOrderState(orderJToken);
                        if (orderState == Enums.OrderState.待付款 || orderState == Enums.OrderState.已取消)
                            continue;
                        var orderStartTime = orderJToken.Value<DateTime>("orderStartTime");
                        var modifyTime = orderJToken.Value<DateTime?>("modified");
                        insertGiftOrderList.Add(new GiftOrder()
                        {
                            Id = orderJToken.Value<string>("orderId"),
                            CreateTime = DateTime.Now,
                            Platform = Enums.Platform.京东,
                            ShopId = shopId,
                            StartTime = orderStartTime,
                            ModifyTime = modifyTime,
                            OrderState = orderState
                        });

                        var itemInfoList = orderJToken["itemInfoList"] as JArray;
                        foreach (var orderSkuJToken in itemInfoList)
                        {
                            var itemTotal = orderSkuJToken.Value<int>("itemTotal");
                            var jdPrice = orderSkuJToken.Value<decimal>("jdPrice");
                            var wareId = orderSkuJToken.Value<string>("wareId");
                            var skuId = orderSkuJToken.Value<string>("skuId");
                            insertGiftOrderSkuList.Add(new GiftOrderSku()
                            {
                                Id = idGenerator.NewLong(),
                                CreateTime = DateTime.Now,
                                GiftOrderId = orderJToken.Value<string>("orderId"),
                                ItemTotal = itemTotal,
                                Price = jdPrice,
                                ProductId = wareId,
                                ShopId = shopId,
                                SkuId = skuId
                            });
                        }
                    }
                }

                var intersectIds = giftOrderIds.Intersect(dbGiftOrderIds);
                if (intersectIds.Count() > 0)
                {
                    foreach (var intersercId in intersectIds)
                    {
                        var orderJToken = giftOrderJArray.FirstOrDefault(o => o.Value<string>("orderId") == intersercId);
                        var dbGiftOrder = dbGiftOrderList.FirstOrDefault(o => o.Id == intersercId);
                        var orderState = ConvertOrderState(orderJToken);
                        if (orderState != null && orderState != dbGiftOrder.OrderState)
                        {
                            var modifyTime = orderJToken.Value<DateTime?>("modified");
                            var update = fsql.Update<GiftOrder>(intersercId).Set(go => go.OrderState, orderState)
                                                                            .Set(go => go.ModifyTime, modifyTime);
                            updateGiftOrderList.Add(update);
                        }
                    }
                }
            }
            #endregion

            var noGiftOrderList = orderTokenJArray.Where(o => o.Value<decimal>("orderTotalPrice") != 0M);

            var interfaceOrderIdList = noGiftOrderList.Select(orderJToken => orderJToken.Value<string>("orderId"));
            var interfaceCanceledOrderIdList = noGiftOrderList.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 noGiftOrderList)
            {
                var itemInfoList = orderJToken["itemInfoList"].Where(skuJToken => skuJToken.Value<decimal>("jdPrice") != 0M);
                foreach (var josku in itemInfoList)
                {
                    var skuId = josku.Value<string>("skuId");
                    if (!orderSkuIds.Contains(skuId))
                        orderSkuIds.Add(skuId);
                }
            }
            var dbPurchaseOrderList = fsql.Select<PurchaseOrder>().Where(po => po.RemainingQuantity != 0 && orderSkuIds.Contains(po.SkuId)).ToList(); //数据库采购单
            orderSkuIds.Clear();

            foreach (var orderJToken in noGiftOrderList)
            {
                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 itemInfoList = orderJToken["itemInfoList"] as JArray;
                    foreach (var orderSkuJToken in itemInfoList)
                    {
                        var itemTotal = orderSkuJToken.Value<int>("itemTotal");
                        var jdPrice = orderSkuJToken.Value<decimal>("jdPrice");
                        var wareId = orderSkuJToken.Value<string>("wareId");
                        var skuId = orderSkuJToken.Value<string>("skuId");

                        //if (orderSkuJToken.Value<decimal>("jdPrice") != 0M)
                        //{
                        var osku = new OrderSku()
                        {
                            Id = idGenerator.NewLong(),
                            ItemTotal = itemTotal,
                            Price = jdPrice,
                            ProductId = wareId,
                            Title = orderSkuJToken.Value<string>("skuName").SimplifySkuName(),
                            ProductNo = orderSkuJToken.Value<string>("productNo"),
                            CreateTime = DateTime.Now,
                            OrderId = orderId,
                            SkuId = skuId
                        };
                        insertOrderSkuList.Add(osku);
                        //}
                        //CumulativeSkuDailySalesDetail(skuDailySalesDetailDictionary, dbOrder.StartTime.Value, shopId, skuId, wareId, jdPrice, itemTotal);

                    }
                    #endregion
                }
                #endregion

                #region 收货人信息
                if (dbOrderConsigneeList.FirstOrDefault(oc => oc.OrderId == orderId) == null)
                {
                    var orderConsignee = new OrderConsignee()
                    {
                        OrderId = orderId,
                        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 orderState = ConvertOrderState(orderJToken, dbOrder.StorageType);
                #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购买数量第二个开始半价

                                var avgPreferential = dbOrder.PreferentialAmount / orderSkuJArray.Count();

                                #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 - avgPreferential -
                                                                         (orderCostDetail.TotalCost + orderCostDetail.DeliveryExpressFreight) -
                                                                         itemPrice * deductionQuantity * platformCommissionRatio;
                                        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 (insertGiftOrderList.Count() > 0)
                    fsql.Insert(insertGiftOrderList).ExecuteAffrows();
                if (insertGiftOrderSkuList.Count() > 0)
                    fsql.Insert(insertGiftOrderSkuList).ExecuteAffrows();

                if (updatePurchaseOrderList.Count() > 0)
                {
                    foreach (var update in updatePurchaseOrderList)
                        update.ExecuteAffrows();
                }

                if (updateOrderList.Count() > 0)
                {
                    foreach (var update in updateOrderList)
                        update.ExecuteAffrows();
                }

                if (updateGiftOrderList.Count() > 0)
                {
                    foreach (var update in updateGiftOrderList)
                        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);
            }
        }

        /// <summary>
        /// 转换订单状态
        /// </summary>
        /// <param name="orderJToken"></param>
        /// <param name="storageType"></param>
        /// <returns></returns>
        private Enums.OrderState? ConvertOrderState(JToken orderJToken, Enums.StorageType? storageType = null)
        {
            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 (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

            return orderState;
        }
    }
}