public void RefreshAmazonRates()
        {
            var syncInfo = new EmptySyncInformer(_log, SyncType.Orders);

            using (var db = _dbFactory.GetRWDb())
            {
                var toRefreshOrderIds = (from o in db.Orders.GetAll()
                                         join sh in db.OrderShippingInfos.GetAll() on o.Id equals sh.OrderId
                                         where o.OrderStatus == OrderStatusEnumEx.Unshipped &&
                                         sh.IsActive &&
                                         (o.Market == (int)MarketType.Amazon ||
                                          o.Market == (int)MarketType.AmazonAU ||
                                          o.Market == (int)MarketType.AmazonEU) &&
                                         (sh.ShippingMethodId == (int)ShippingUtils.AmazonFedExExpressSaverShippingMethodId || //TEMP: old
                                          sh.ShippingMethodId == (int)ShippingUtils.AmazonFedExHomeDeliveryShippingMethodId || //TEMP: old
                                          o.SourceShippingService == ShippingUtils.SecondDayServiceName ||
                                          o.SourceShippingService == ShippingUtils.NextDayServiceName ||
                                          o.OrderType == (int)OrderTypeEnum.Prime)
                                         select o.Id).ToList();

                _log.Info("Orders to update: " + String.Join(", ", toRefreshOrderIds.Select(o => o).ToList()));

                var orderIdList = toRefreshOrderIds.ToArray();
                if (!orderIdList.Any())
                {
                    return;
                }

                IList <DTOOrder> dtoOrders = db.ItemOrderMappings.GetSelectedOrdersWithItems(_weightService, orderIdList, includeSourceItems: true).ToList();
                foreach (var dtoOrder in dtoOrders)
                {
                    //Ignore shipped orders
                    if (ShippingUtils.IsOrderShipped(dtoOrder.OrderStatus) ||
                        dtoOrder.ShippingInfos.Any(s => !String.IsNullOrEmpty(s.LabelPath)) ||
                        dtoOrder.ShippingInfos.Any(s => !String.IsNullOrEmpty(s.TrackingNumber)))
                    {
                        _log.Info("OrderId: " + dtoOrder.Id + " (" + dtoOrder.OrderId + ") - Skipped (has shipped status or has tr#)");
                    }
                    else
                    {
                        _log.Info("Add recalc action for OrderId=" + dtoOrder.OrderId);

                        _actionService.AddAction(db,
                                                 SystemActionType.UpdateRates,
                                                 dtoOrder.OrderId,
                                                 new UpdateRatesInput()
                        {
                            OrderId = dtoOrder.Id
                        },
                                                 null,
                                                 null);
                    }
                }
            }
        }
        public void RefreshSuspiciousFedexRates()
        {
            var syncInfo = new EmptySyncInformer(_log, SyncType.Orders);

            using (var db = _dbFactory.GetRWDb())
            {
                var toRefreshOrderIds = (from o in db.Orders.GetAll()
                                         join sh in db.OrderShippingInfos.GetAll() on o.Id equals sh.OrderId
                                         where o.OrderStatus == OrderStatusEnumEx.Unshipped &&
                                         sh.IsActive &&
                                         (sh.ShippingMethodId == ShippingUtils.FedexOneRate2DayEnvelope ||
                                          sh.ShippingMethodId == ShippingUtils.FedexOneRate2DayPak) &&
                                         sh.StampsShippingCost > 12
                                         select o.Id).ToList();

                _log.Info("Orders to update: " + String.Join(", ", toRefreshOrderIds.Select(o => o).ToList()));

                var orderIdList = toRefreshOrderIds.ToArray();
                if (!orderIdList.Any())
                {
                    return;
                }

                IList <DTOOrder> dtoOrders = db.ItemOrderMappings.GetSelectedOrdersWithItems(_weightService, orderIdList, includeSourceItems: true).ToList();
                foreach (var dtoOrder in dtoOrders)
                {
                    //Ignore shipped orders
                    if (ShippingUtils.IsOrderShipped(dtoOrder.OrderStatus) ||
                        dtoOrder.ShippingInfos.Any(s => !String.IsNullOrEmpty(s.LabelPath)) ||
                        dtoOrder.ShippingInfos.Any(s => !String.IsNullOrEmpty(s.TrackingNumber)))
                    {
                        _log.Info("OrderId: " + dtoOrder.Id + " (" + dtoOrder.OrderId + ") - Skipped (has shipped status or has tr#)");
                    }
                    else
                    {
                        _log.Info("Add recalc action for OrderId=" + dtoOrder.OrderId);

                        _actionService.AddAction(db,
                                                 SystemActionType.UpdateRates,
                                                 dtoOrder.OrderId,
                                                 new UpdateRatesInput()
                        {
                            OrderId = dtoOrder.Id
                        },
                                                 null,
                                                 null);
                    }
                }
            }
        }
        public void ProcessSystemAction(CancellationToken cancelToken)
        {
            var syncInfo = new EmptySyncInformer(_log, SyncType.Orders);

            using (var db = _dbFactory.GetRWDb())
            {
                var updateRateActions = _actionService.GetUnprocessedByType(db, SystemActionType.UpdateRates, null, null);

                foreach (var action in updateRateActions)
                {
                    if (cancelToken.IsCancellationRequested)
                    {
                        return;
                    }

                    var actionStatus = SystemActionStatus.None;
                    try
                    {
                        var inputData = SystemActionHelper.FromStr <UpdateRatesInput>(action.InputData);
                        var orderId   = inputData.OrderId;
                        if (!orderId.HasValue && !String.IsNullOrEmpty(inputData.OrderNumber))
                        {
                            var order = db.Orders.GetByOrderNumber(inputData.OrderNumber);
                            orderId = order.Id;
                        }

                        if (orderId.HasValue)
                        {
                            var orderIdList            = new long[] { orderId.Value };
                            IList <DTOOrder> dtoOrders = db.ItemOrderMappings.GetSelectedOrdersWithItems(_weightService, orderIdList, includeSourceItems: true).ToList();

                            foreach (var dtoOrder in dtoOrders)
                            {
                                //Ignore shipped orders
                                if ((dtoOrder.Market != (int)MarketType.eBay &&
                                     ShippingUtils.IsOrderShipped(dtoOrder.OrderStatus)) ||
                                    dtoOrder.ShippingInfos.Any(s => !String.IsNullOrEmpty(s.LabelPath))

                                    || dtoOrder.BatchId.HasValue) //NOTE: SKip orders in batch
                                {
                                    actionStatus = SystemActionStatus.Skipped;
                                }
                                else
                                {
                                    var markets = new MarketplaceKeeper(_dbFactory, false);
                                    markets.Init();
                                    var companyAddress = new CompanyAddressService(_company, markets.GetAll());
                                    var synchronizer   = new AmazonOrdersSynchronizer(_log,
                                                                                      _company,
                                                                                      syncInfo,
                                                                                      _rateProviders,
                                                                                      companyAddress,
                                                                                      _time,
                                                                                      _weightService,
                                                                                      _messageService);
                                    if (!synchronizer.UIUpdate(db, dtoOrder, false, false, keepCustomShipping: false, switchToMethodId: null))
                                    {
                                        actionStatus = SystemActionStatus.Fail;
                                    }
                                    else
                                    {
                                        actionStatus = SystemActionStatus.Done;
                                    }
                                }
                            }

                            _log.Info("Order rates was recalculated, actionId=" + action.Id + ", status=" + actionStatus);
                        }
                        else
                        {
                            actionStatus = SystemActionStatus.NotFoundEntity;
                            _log.Info("Can't find order, actionId=" + action.Id + ", orderId=" + inputData.OrderId + ", orderNumber=" + inputData.OrderNumber);
                        }
                    }
                    catch (Exception ex)
                    {
                        _log.Error("Fail recalculate order rates action, actionId=" + action.Id, ex);
                        actionStatus = SystemActionStatus.Fail;
                    }

                    _actionService.SetResult(db,
                                             action.Id,
                                             actionStatus,
                                             null,
                                             null);
                }

                db.Commit();
            }
        }
        public virtual ActionResult ReCalcShippingService(long batchId,
                                                          string orderIds,
                                                          int?switchToProviderId,
                                                          int?switchToMethodId)
        {
            LogI("ReCalcShippingService begin, orderIds=" + orderIds);

            IList <string> failedUpdate  = new List <string>();
            IList <string> successUpdate = new List <string>();

            if (!string.IsNullOrEmpty(orderIds))
            {
                var stringOrderIdList = orderIds.Split(", ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                var orderIdList       = stringOrderIdList.Select(long.Parse).ToArray();
                var rateProviders     = ServiceFactory.GetShipmentProviders(LogService,
                                                                            Time,
                                                                            DbFactory,
                                                                            WeightService,
                                                                            AccessManager.Company.ShipmentProviderInfoList,
                                                                            null,
                                                                            null,
                                                                            null,
                                                                            null);

                var syncInfo = new EmptySyncInformer(LogService, SyncType.Orders);

                IList <DTOOrder> dtoOrders = Db.ItemOrderMappings.GetSelectedOrdersWithItems(WeightService, orderIdList, includeSourceItems: true).ToList();
                foreach (var dtoOrder in dtoOrders)
                {
                    //Ignore shipped orders
                    if ((dtoOrder.Market != (int)MarketType.eBay && ShippingUtils.IsOrderShipped(dtoOrder.OrderStatus)) ||
                        dtoOrder.ShippingInfos.Any(s => !String.IsNullOrEmpty(s.LabelPath)))
                    {
                        failedUpdate.Add(dtoOrder.OrderId);
                        continue;
                    }

                    if (switchToProviderId.HasValue &&
                        dtoOrder.ShipmentProviderType != switchToProviderId.Value)
                    {
                        var skipChanges = false;
                        if (switchToProviderId == (int)ShipmentProviderType.FedexOneRate)
                        {
                            if (ShippingUtils.IsInternational(dtoOrder.FinalShippingCountry))
                            {
                                skipChanges = true;
                            }
                        }

                        if (!skipChanges)
                        {
                            var dbOrder = Db.Orders.Get(dtoOrder.Id);
                            dbOrder.ShipmentProviderType = switchToProviderId.Value;
                            Db.Commit();
                            dtoOrder.ShipmentProviderType = switchToProviderId.Value;
                        }
                    }

                    var synchronizer = new AmazonOrdersSynchronizer(LogService,
                                                                    AccessManager.Company,
                                                                    syncInfo,
                                                                    rateProviders,
                                                                    CompanyAddress,
                                                                    Time,
                                                                    WeightService,
                                                                    MessageService);

                    if (synchronizer.UIUpdate(Db, dtoOrder, false, false, keepCustomShipping: false, switchToMethodId: switchToMethodId))
                    {
                        successUpdate.Add(dtoOrder.OrderId);
                    }
                    else
                    {
                        failedUpdate.Add(dtoOrder.OrderId);
                    }
                }
            }
            LogI("ReCalcShippingService result, failedUpdate=" + String.Join(", ", failedUpdate)
                 + ", successUpdate=" + String.Join(", ", successUpdate));

            return(new JsonResult
            {
                Data = ValueResult <IList <string> > .Success("", new List <string>() { String.Join(", ", failedUpdate), String.Join(", ", successUpdate) }),
                JsonRequestBehavior = JsonRequestBehavior.AllowGet
            });
        }