/// <summary>
        ///	Returns sku inventory
        /// </summary>
        /// <param name="sku"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        public async Task <ListingInventory> GetListingInventoryBySku(string sku, CancellationToken token)
        {
            Condition.Requires(sku).IsNotNullOrEmpty();

            ListingInventory listingInventory = null;

            // get all listings that have products with specified sku
            var listings = await GetListingsBySku(sku, token).ConfigureAwait(false);

            var listing = listings.FirstOrDefault();

            // get listing's product inventory
            if (listing != null)
            {
                listingInventory = await GetListingInventoryBySku(listing, sku, token);
            }

            return(listingInventory);
        }
        /// <summary>
        ///	Updates sku quantity asynchronously
        /// </summary>
        /// <param name="listing"></param>
        /// <param name="inventory"></param>
        /// <param name="sku"></param>
        /// <param name="quantity"></param>
        /// <returns></returns>
        private async Task UpdateSkuQuantityAsync(Listing listing, ListingInventory inventory, string sku, int quantity, CancellationToken token)
        {
            var mark = Mark.CreateNew();

            var updateInventoryRequest = new List <UpdateInventoryRequest>();

            // we should also add all product variations to request
            foreach (var product in inventory.Products)
            {
                var productOffering = product.Offerings.FirstOrDefault();

                if (productOffering == null)
                {
                    continue;
                }

                int productQuantity = productOffering.Quantity;

                if (product.Sku != null && product.Sku.ToLower().Equals(sku.ToLower()))
                {
                    productQuantity = quantity;
                }

                updateInventoryRequest.Add(new UpdateInventoryRequest()
                {
                    ProductId      = product.Id,
                    Sku            = product.Sku,
                    PropertyValues = DecodePropertyValuesWithQuotesAndEscape(product.PropertyValues),
                    // currently each product has one offering
                    ListingOffering = new ListingOfferingRequest[]
                    {
                        new ListingOfferingRequest()
                        {
                            Id       = productOffering.Id,
                            Quantity = productQuantity,
                            Price    = (decimal)productOffering.Price
                        }
                    }
                });
            }

            var url = String.Format(EtsyEndPoint.UpdateListingInventoryUrl, listing.Id);

            Dictionary <string, string> payload;

            try
            {
                EtsyLogger.LogStarted(this.CreateMethodCallInfo(url, mark, additionalInfo: this.AdditionalLogInfo()));

                payload = new Dictionary <string, string>
                {
                    { "products", JsonConvert.SerializeObject(updateInventoryRequest.ToArray()) }
                };

                if (inventory.PriceOnProperty.Length != 0)
                {
                    payload.Add("price_on_property", string.Join(",", inventory.PriceOnProperty));
                }

                if (inventory.QuantityOnProperty.Length != 0)
                {
                    payload.Add("quantity_on_property", string.Join(",", inventory.QuantityOnProperty));
                }

                if (inventory.SkuOnProperty.Length != 0)
                {
                    payload.Add("sku_on_property", string.Join(",", inventory.SkuOnProperty));
                }
            }
            catch (Exception exception)
            {
                var etsyException = new EtsyException(this.CreateMethodCallInfo(url, mark, additionalInfo: this.AdditionalLogInfo()), exception);
                EtsyLogger.LogTraceException(etsyException);
                throw etsyException;
            }

            var requestPayload = payload.ToJson();

            try
            {
                await base.PutAsync(url, payload, token, mark).ConfigureAwait(false);

                EtsyLogger.LogEnd(this.CreateMethodCallInfo(url, mark, additionalInfo: this.AdditionalLogInfo(), requestPayload: requestPayload));
            }
            catch (Exception exception)
            {
                var etsyException = new EtsyException(this.CreateMethodCallInfo(url, mark, additionalInfo: this.AdditionalLogInfo(), requestPayload: requestPayload), exception);
                EtsyLogger.LogTraceException(etsyException);
                throw etsyException;
            }
        }