private async Task <RpcInvoker.RpcResponse <TResult> > GetWithSafeAsync <TResult, TServerResponse>(Func <TServerResponse, TResult> converter, Func <Mage_Api_Model_Server_Wsi_HandlerPortTypeClient, string, Task <TServerResponse> > action, int abortAfter, bool suppressException = false, [CallerMemberName] string callerName = null) where TServerResponse : new() where TResult : class
        {
            var withSafeAsync = await RpcInvoker.SuppressExceptions(
                async() => await this.GetWithUnsafeAsync( converter, action, abortAfter ).ConfigureAwait(false)
                ).ConfigureAwait(false);

            return(withSafeAsync);
        }
        public virtual async Task <IEnumerable <RpcInvoker.RpcRequestResponse <PutStockItem, object> > > PutStockItemsAsync(List <PutStockItem> stockItems, Mark mark = null)
        {
            var methodParameters = stockItems.ToJson();

            try
            {
                var stockItemsProcessed = stockItems.Select(x =>
                {
                    var catalogInventoryStockItemUpdateEntity = (x.Qty > 0) ?
                                                                new catalogInventoryStockItemUpdateEntity()
                    {
                        is_in_stock = 1, is_in_stockSpecified = true, qty = x.Qty.ToString()
                    } :
                    new catalogInventoryStockItemUpdateEntity()
                    {
                        is_in_stock = 0, is_in_stockSpecified = false, qty = x.Qty.ToString()
                    };
                    return(Tuple.Create(x, catalogInventoryStockItemUpdateEntity));
                });

                const int maxCheckCount    = 2;
                const int delayBeforeCheck = 1800000;

                var privateClient = this._clientFactory.GetClient();

                RpcInvoker.RpcResponse <catalogInventoryStockItemMultiUpdateResponse> serverResponse = null;
                await ActionPolicies.GetAsync.Do(async() =>
                {
                    var statusChecker = new StatusChecker(maxCheckCount);
                    TimerCallback tcb = statusChecker.CheckStatus;

                    privateClient = this._clientFactory.RefreshClient(privateClient);

                    var sessionId = await this.GetSessionId().ConfigureAwait(false);

                    using (var stateTimer = new Timer(tcb, privateClient, 1000, delayBeforeCheck))
                    {
                        MagentoLogger.LogTraceStarted(this.CreateMethodCallInfo(methodParameters, mark));

                        var catalogInventoryStockItemUpdateEntities = stockItemsProcessed.Select(x => x.Item2).ToArray();

                        serverResponse = await RpcInvoker.SuppressExceptions(async() => await privateClient.catalogInventoryStockItemMultiUpdateAsync(sessionId.SessionId, stockItemsProcessed.Select(x => x.Item1.ProductId).ToArray(), catalogInventoryStockItemUpdateEntities).ConfigureAwait(false)).ConfigureAwait(false);

                        var updateBriefInfo = string.Format("{{Success:{0}}}", serverResponse.Result.result);
                        MagentoLogger.LogTraceEnded(CreateMethodCallInfo(methodParameters, mark: mark, methodResult: updateBriefInfo));
                    }
                }).ConfigureAwait(false);

                var result = stockItems.Select(y => new RpcInvoker.RpcRequestResponse <PutStockItem, object>(y, new RpcInvoker.RpcResponse <object>(serverResponse?.ErrorCode ?? RpcInvoker.SoapErrorCode.Unknown, serverResponse?.Result, serverResponse?.Exception)));
                return(result);
            }
            catch (Exception exc)
            {
                throw new MagentoSoapException($"An error occured during PutStockItemsAsync({methodParameters})", exc);
            }
        }
        public virtual async Task <IEnumerable <RpcInvoker.RpcRequestResponse <PutStockItem, object> > > PutStockItemsAsync(List <PutStockItem> stockItems, Mark mark = null)
        {
            var methodParameters = stockItems.ToJson();

            try
            {
                const int maxCheckCount    = 2;
                const int delayBeforeCheck = 1800000;

                var magentoStockItemsResponse = await this.GetStockItemsOldAsync(stockItems.Select(item => item.Sku)).ConfigureAwait(false);

                var magentoStockItems = magentoStockItemsResponse.Responses.Select(item => item as CatalogInventoryDataStockItemInterface).Where(item => item != null);

                var privateClient = this._clientFactory.CreateMagentoCatalogInventoryStockServiceClient();

                var res = new ConcurrentQueue <RpcInvoker.RpcRequestResponse <PutStockItem, object> >();

                await stockItems.DoInBatchAsync(10, async x =>
                {
                    await ActionPolicies.GetAsync.Do(async() =>
                    {
                        var statusChecker = new StatusChecker(maxCheckCount);
                        TimerCallback tcb = statusChecker.CheckStatus;

                        privateClient = this._clientFactory.RefreshMagentoCatalogInventoryStockServiceClient(privateClient);

                        using (var stateTimer = new Timer(tcb, privateClient, 1000, delayBeforeCheck))
                        {
                            MagentoLogger.LogTraceStarted(this.CreateMethodCallInfo(methodParameters, mark: mark));

                            var productId = int.Parse(x.ProductId);
                            var catalogInventoryDataStockItemInterface = magentoStockItems.FirstOrDefault(i => i.productId == productId);
                            if (catalogInventoryDataStockItemInterface == null)
                            {
                                MagentoLogger.LogTrace($"PutStockItemsAsync. Can't find StockItem with ProductId={x.ProductId} (SKU={x.Sku}).", mark);
                                catalogInventoryDataStockItemInterface = new CatalogInventoryDataStockItemInterface
                                {
                                    productId                      = productId,
                                    productIdSpecified             = true,
                                    isInStock                      = false,
                                    isQtyDecimal                   = false,
                                    showDefaultNotificationMessage = false,
                                    useConfigMinQty                = true,
                                    minQty = 0,
                                    useConfigMinSaleQty     = 1,
                                    minSaleQty              = 1,
                                    useConfigMaxSaleQty     = true,
                                    maxSaleQty              = 10000,
                                    useConfigBackorders     = true,
                                    backorders              = 0,
                                    useConfigNotifyStockQty = true,
                                    notifyStockQty          = 1,
                                    useConfigQtyIncrements  = true,
                                    qtyIncrements           = 0,
                                    useConfigEnableQtyInc   = false,
                                    enableQtyIncrements     = false,
                                    useConfigManageStock    = true,
                                    manageStock             = true,
                                    //lowStockDate = "2016-02-29 20:48:26",
                                    isDecimalDivided       = false,
                                    stockStatusChangedAuto = 1
                                };
                            }
                            catalogInventoryDataStockItemInterface.qty        = x.Qty.ToString();
                            catalogInventoryDataStockItemInterface.isInStock |= x.Qty > 0;

                            var catalogInventoryStockRegistryV1UpdateStockItemBySkuRequest = new CatalogInventoryStockRegistryV1UpdateStockItemBySkuRequest()
                            {
                                productSku = x.Sku,
                                stockItem  = catalogInventoryDataStockItemInterface
                            };

                            RpcInvoker.IRpcResponse <object> response = await RpcInvoker.SuppressExceptions(async() => await privateClient.catalogInventoryStockRegistryV1UpdateStockItemBySkuAsync(catalogInventoryStockRegistryV1UpdateStockItemBySkuRequest).ConfigureAwait(false)).ConfigureAwait(false);
                            var reqResp = new RpcInvoker.RpcRequestResponse <PutStockItem, object>(x, response);
                            res.Enqueue(reqResp);
                        }
                    }).ConfigureAwait(false);
                }).ConfigureAwait(false);

                MagentoLogger.LogTraceEnded(this.CreateMethodCallInfo(methodParameters, mark: mark, methodResult: res.ToJson()));
                //return errors count instead of true false;
                return(res);
            }
            catch (Exception exc)
            {
                throw new MagentoSoapException($"An error occured during PutStockItemsAsync({methodParameters})", exc);
            }
        }