diff --git a/README.md b/README.md index b715b11..07c0bbe 100644 --- a/README.md +++ b/README.md @@ -2,16 +2,17 @@ The [VTEX platform](https://www.nuget.org/packages/VTEX) SDK for .NET projects (both Core & Framework). +[![GitHub license](https://img.shields.io/github/license/guibranco/VTEX-SDK-dotnet)](https://github.com/guibranco/VTEX-SDK-dotnet) +[![Time tracker](https://wakatime.com/badge/github/guibranco/VTEX-SDK-dotnet.svg)](https://wakatime.com/badge/github/guibranco/VTEX-SDK-dotnet) + ![VTEX logo](https://raw.githubusercontent.com/guibranco/VTEX-SDK-dotnet/master/logo.png) ## CI/CD -[![Build status](https://ci.appveyor.com/api/projects/status/kuso66xs0ljrcxfn?svg=true)](https://ci.appveyor.com/project/guibranco/vtex-sdk-dotnet) -[![VTEX NuGet Version](https://img.shields.io/nuget/v/VTEX.svg?style=flat)](https://www.nuget.org/packages/VTEX/) -[![VTEX NuGet Downloads](https://img.shields.io/nuget/dt/VTEX.svg?style=flat)](https://www.nuget.org/packages/VTEX/) -[![Github All Releases](https://img.shields.io/github/downloads/guibranco/VTEX-SDK-dotnet/total.svg?style=flat)](https://github.com/guibranco/VTEX-SDK-dotnet) -[![Last release](https://img.shields.io/github/release-date/guibranco/VTEX-SDK-dotnet.svg?style=flat)](https://github.com/guibranco/VTEX-SDK-dotnet) -[![time tracker](https://wakatime.com/badge/github/guibranco/VTEX-SDK-dotnet.svg)](https://wakatime.com/badge/github/guibranco/VTEX-SDK-dotnet) +| Branch | Build status | Last commit | Tests | +|--------|--------------|-------------|-------| +| Master | [![Build status](https://ci.appveyor.com/api/projects/status/kuso66xs0ljrcxfn/branch/master?svg=true)](https://ci.appveyor.com/project/guibranco/vtex-sdk-dotnet/branch/master) | [![GitHub last commit](https://img.shields.io/github/last-commit/guibranco/VTEX-SDK-dotnet/master)](https://github.com/guibranco/VTEX-SDK-dotnet) | ![AppVeyor tests (branch)](https://img.shields.io/appveyor/tests/guibranco/vtex-sdk-dotnet/master?compact_message) | +| Develop | [![Build status](https://ci.appveyor.com/api/projects/status/kuso66xs0ljrcxfn/branch/develop?svg=true)](https://ci.appveyor.com/project/guibranco/vtex-sdk-dotnet/branch/develop) | [![GitHub last commit](https://img.shields.io/github/last-commit/guibranco/vtex-sdk-dotnet/develop)](https://github.com/guibranco/VTEX-SDK-dotnet) | ![AppVeyor tests (branch)](https://img.shields.io/appveyor/tests/guibranco/vtex-sdk-dotnet/develop?compact_message) | ## Code Quality @@ -35,17 +36,18 @@ The [VTEX platform](https://www.nuget.org/packages/VTEX) SDK for .NET projects ( ## Installation -Download the latest zip file from the [Release pages](https://github.com/guibranco/VTEX/releases) or simple install from [NuGet](https://www.nuget.org/packages/VTEX) package manager - -NuGet URL: [https://www.nuget.org/packages/VTEX](https://www.nuget.org/packages/VTEX) +### Github Releases -NuGet installation via *Package Manager Console*: +[![GitHub last release](https://img.shields.io/github/release-date/guibranco/VTEX-SDK-dotnet.svg?style=flat)](https://github.com/guibranco/VTEX-SDK-dotnet) [![Github All Releases](https://img.shields.io/github/downloads/guibranco/VTEX-SDK-dotnet/total.svg?style=flat)](https://github.com/guibranco/VTEX-SDK-dotnet) -```ps +Download the latest zip file from the [Release](https://github.com/GuiBranco/VTEX-SDK-dotnet/releases) page. -Install-Package VTEX +### Nuget package manager -``` +| Package | Version | Downloads | +|------------------|:-------:|:-------:| +| **VTEX** | [![VTEX NuGet Version](https://img.shields.io/nuget/v/VTEX.svg?style=flat)](https://www.nuget.org/packages/VTEX/) | [![VTEX NuGet Downloads](https://img.shields.io/nuget/dt/VTEX.svg?style=flat)](https://www.nuget.org/packages/VTEX/) | +| **VTEX.Health** | [![VTEX Health NuGet Version](https://img.shields.io/nuget/v/VTEX.Health.svg?style=flat)](https://www.nuget.org/packages/VTEX.Health/) | [![VTEX Health NuGet Downloads](https://img.shields.io/nuget/dt/VTEX.Health.svg?style=flat)](https://www.nuget.org/packages/VTEX.Health/) | --- diff --git a/Src/VTEX.API/VTEX.API.csproj b/Src/VTEX.API/VTEX.API.csproj index dcbc1e8..93c712d 100644 --- a/Src/VTEX.API/VTEX.API.csproj +++ b/Src/VTEX.API/VTEX.API.csproj @@ -1,4 +1,4 @@ - + netstandard2.0;netstandard2.1 @@ -6,7 +6,7 @@ - + diff --git a/Src/VTEX.Core/VTEX.Core.csproj b/Src/VTEX.Core/VTEX.Core.csproj index dcbc1e8..a5fbe4b 100644 --- a/Src/VTEX.Core/VTEX.Core.csproj +++ b/Src/VTEX.Core/VTEX.Core.csproj @@ -6,7 +6,7 @@ - + diff --git a/Src/VTEX.Health/PlatformStatus.cs b/Src/VTEX.Health/PlatformStatus.cs index 0d9f75f..c3d0ead 100644 --- a/Src/VTEX.Health/PlatformStatus.cs +++ b/Src/VTEX.Health/PlatformStatus.cs @@ -52,7 +52,9 @@ public string StatusInternal set { if (!string.IsNullOrWhiteSpace(value)) + { Status = EnumExtensions.GetEnumByInternalValueAttribute(value); + } } } diff --git a/Src/VTEX.Health/VTEX.Health.csproj b/Src/VTEX.Health/VTEX.Health.csproj index 187f512..fe7eecd 100644 --- a/Src/VTEX.Health/VTEX.Health.csproj +++ b/Src/VTEX.Health/VTEX.Health.csproj @@ -1,15 +1,40 @@ + {931C39A1-583E-4264-AC7C-508C7B1FC15E} netstandard2.0;netstandard2.1 8.0 + true + Guilherme Branco Stracini + Guilherme Branco Stracini + The VTEX platform (PaaS) (e-commerce) SDK. A .NET client to consume VTEX APIs for both Core and Framework projects + © 2020 Guilherme Branco Stracini. All rights reserved. + LICENSE + https://guibranco.github.io/VTEX-SDK-dotnet/ + packageLogo.png + https://github.com/guibranco/VTEX-SDK-dotnet + GIT + vtex paas client sdk ecommerce e-commerce platform apis + 1.0.0 + 1.0.0.0 - - + + + + + True + + + + True + + + + diff --git a/Src/VTEX.Health/VtexHealthClient.cs b/Src/VTEX.Health/VtexHealthClient.cs index 8878650..679903b 100644 --- a/Src/VTEX.Health/VtexHealthClient.cs +++ b/Src/VTEX.Health/VtexHealthClient.cs @@ -25,7 +25,10 @@ public class VtexHealthClient : IVtexHealthClient public VtexHealthClient(ILoggerFactory loggerFactory, HttpClient httpClient) { if (loggerFactory == null) + { throw new ArgumentNullException(nameof(loggerFactory)); + } + _logger = loggerFactory.CreateLogger(); _httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient)); } @@ -38,8 +41,8 @@ public VtexHealthClient(ILoggerFactory loggerFactory, HttpClient httpClient) public async Task> GetPlatformStatuesAsync(CancellationToken cancellationToken) { _logger.LogDebug("Getting platform status"); - var response = await _httpClient.GetAsync("/", cancellationToken); - var responseContent = await response.Content.ReadAsStringAsync(); + var response = await _httpClient.GetAsync("/", cancellationToken).ConfigureAwait(false); + var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false); _logger.LogDebug($"Platform status response: {response.StatusCode}"); return response.IsSuccessStatusCode ? JsonConvert.DeserializeObject(responseContent) : default; } diff --git a/Src/VTEX/GoodPractices/UnexpectedApiResponseException.cs b/Src/VTEX/GoodPractices/UnexpectedApiResponseException.cs index e9b6a99..0622735 100644 --- a/Src/VTEX/GoodPractices/UnexpectedApiResponseException.cs +++ b/Src/VTEX/GoodPractices/UnexpectedApiResponseException.cs @@ -66,7 +66,10 @@ protected UnexpectedApiResponseException(SerializationInfo info, StreamingContex public override void GetObjectData(SerializationInfo info, StreamingContext context) { if (info == null) + { throw new ArgumentNullException(nameof(info)); + } + info.AddValue("Request", Request); info.AddValue("Response", Response); info.AddValue("StatusCode", StatusCode); diff --git a/Src/VTEX/GoodPractices/UpdatePriceInfoSKUException.cs b/Src/VTEX/GoodPractices/UpdatePriceInfoSKUException.cs index 9a0b802..5bca536 100644 --- a/Src/VTEX/GoodPractices/UpdatePriceInfoSKUException.cs +++ b/Src/VTEX/GoodPractices/UpdatePriceInfoSKUException.cs @@ -9,23 +9,23 @@ /// [Serializable] - public class UpdatePriceInfoSKUException : Exception + public class UpdatePriceInfoSkuException : Exception { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The sku identifier. /// The inner exception. - public UpdatePriceInfoSKUException(int skuId, Exception innerException) + public UpdatePriceInfoSkuException(int skuId, Exception innerException) : base($"Unable to update the price of SKU {skuId} in VTEX platform", innerException) { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The that holds the serialized object data about the exception being thrown. /// The that contains contextual information about the source or destination. - protected UpdatePriceInfoSKUException(SerializationInfo info, StreamingContext context) : base(info, context) + protected UpdatePriceInfoSkuException(SerializationInfo info, StreamingContext context) : base(info, context) { } } } diff --git a/Src/VTEX/GoodPractices/UpdateStockInfoSKUException.cs b/Src/VTEX/GoodPractices/UpdateStockInfoSKUException.cs index d16e2ec..c8fa88b 100644 --- a/Src/VTEX/GoodPractices/UpdateStockInfoSKUException.cs +++ b/Src/VTEX/GoodPractices/UpdateStockInfoSKUException.cs @@ -9,23 +9,23 @@ /// [Serializable] - public class UpdateStockInfoSKUException : Exception + public class UpdateStockInfoSkuException : Exception { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The sku identifier. /// The inner exception. - public UpdateStockInfoSKUException(int skuId, Exception innerException) + public UpdateStockInfoSkuException(int skuId, Exception innerException) : base($"Unable to update the stock of SKU {skuId} in VTEX platform", innerException) { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The that holds the serialized object data about the exception being thrown. /// The that contains contextual information about the source or destination. - protected UpdateStockInfoSKUException(SerializationInfo info, StreamingContext context) : base(info, context) + protected UpdateStockInfoSkuException(SerializationInfo info, StreamingContext context) : base(info, context) { } } } diff --git a/Src/VTEX/GoodPractices/UpdateStockInfoSkuException.cs b/Src/VTEX/GoodPractices/UpdateStockInfoSkuException.cs new file mode 100644 index 0000000..c8fa88b --- /dev/null +++ b/Src/VTEX/GoodPractices/UpdateStockInfoSkuException.cs @@ -0,0 +1,31 @@ +namespace VTEX.GoodPractices +{ + using System; + using System.Runtime.Serialization; + + /// + /// Class UpdateStockInfoSKUException. This class cannot be inherited. + /// + /// + + [Serializable] + public class UpdateStockInfoSkuException : Exception + { + /// + /// Initializes a new instance of the class. + /// + /// The sku identifier. + /// The inner exception. + public UpdateStockInfoSkuException(int skuId, Exception innerException) + : base($"Unable to update the stock of SKU {skuId} in VTEX platform", innerException) + { } + + /// + /// Initializes a new instance of the class. + /// + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. + protected UpdateStockInfoSkuException(SerializationInfo info, StreamingContext context) : base(info, context) + { } + } +} diff --git a/Src/VTEX/PlatformConstants.cs b/Src/VTEX/PlatformConstants.cs index d530f01..c91aabc 100644 --- a/Src/VTEX/PlatformConstants.cs +++ b/Src/VTEX/PlatformConstants.cs @@ -9,61 +9,61 @@ internal static class PlatformConstants /// /// The rest oms feed /// - public const string OMS_FEED = "oms/pvt/feed/orders/status/"; + public const string OmsFeed = "oms/pvt/feed/orders/status/"; /// /// The rest oms orders /// - public const string OMS_ORDERS = "oms/pvt/orders"; + public const string OmsOrders = "oms/pvt/orders"; /// /// The rest oms invoices /// - public const string OMS_INVOICES = "oms/pub/orders"; + public const string OmsInvoices = "oms/pub/orders"; /// /// The rest oms tracking /// - public const string OMS_TRACKING = "oms/pvt/orders/{0}/invoice/{1}/tracking"; + public const string OmsTracking = "oms/pvt/orders/{0}/invoice/{1}/tracking"; /// /// The rest log warehouses /// - public const string LOG_WAREHOUSES = "logistics/pvt/inventory/warehouseitembalances"; + public const string LogWarehouses = "logistics/pvt/inventory/warehouseitembalances"; /// /// The rest pci transactions /// - public const string PCI_TRANSACTIONS = "pvt/transactions"; + public const string PciTransactions = "pvt/transactions"; /// /// The rest log reservations /// - public const string LOG_RESERVATIONS = "logistics/pvt/inventory/reservations"; + public const string LogReservations = "logistics/pvt/inventory/reservations"; /// /// The rest log inventory /// - public const string LOG_INVENTORY = "logistics/pvt/inventory/skus"; + public const string LogInventory = "logistics/pvt/inventory/skus"; /// /// The rest bridge search /// - public const string BRIDGE_SEARCH = "bridge/mb/search"; + public const string BridgeSearch = "bridge/mb/search"; /// /// The pricing endpoint. /// - public const string PRICING = "pricing/prices"; + public const string Pricing = "pricing/prices"; /// /// The rest catalog /// - public const string CATALOG = "catalog_system/pvt"; + public const string Catalog = "catalog_system/pvt"; /// /// The rest catalog pub /// - public const string CATALOG_PUB = "catalog_system/pub"; + public const string CatalogPub = "catalog_system/pub"; } } diff --git a/Src/VTEX/Transport/ChangeOrder.cs b/Src/VTEX/Transport/ChangeOrder.cs index b1a4718..118a9b1 100644 --- a/Src/VTEX/Transport/ChangeOrder.cs +++ b/Src/VTEX/Transport/ChangeOrder.cs @@ -29,13 +29,13 @@ public sealed class ChangeOrder public int DiscountValue { get; set; } /// - /// Gets or sets the incremente value. + /// Gets or sets the increment value. /// /// - /// The incremente value. + /// The increment value. /// [JsonProperty("incrementValue")] - public int IncrementeValue { get; set; } + public int IncrementValue { get; set; } /// /// Gets or sets the items added. diff --git a/Src/VTEX/Transport/ClientProfileData.cs b/Src/VTEX/Transport/ClientProfileData.cs index 19d2569..41a81e8 100644 --- a/Src/VTEX/Transport/ClientProfileData.cs +++ b/Src/VTEX/Transport/ClientProfileData.cs @@ -67,7 +67,10 @@ public string DocumentTypeInternal set { if (string.IsNullOrWhiteSpace(value)) + { return; + } + DocumentType = EnumExtensions.GetEnumByInternalValueAttribute(value); } } diff --git a/Src/VTEX/Transport/DateRange.cs b/Src/VTEX/Transport/DateRange.cs index 64980ca..5331df8 100644 --- a/Src/VTEX/Transport/DateRange.cs +++ b/Src/VTEX/Transport/DateRange.cs @@ -31,7 +31,9 @@ public string FromInternal set { if (DateTime.TryParse(value, out var from)) - From = from; + { + From = @from; + } } } @@ -57,7 +59,9 @@ public string ToInternal set { if (DateTime.TryParse(value, out var to)) + { To = to; + } } } } diff --git a/Src/VTEX/Transport/FixedPrice.cs b/Src/VTEX/Transport/FixedPrice.cs index 4df0f7b..2b50435 100644 --- a/Src/VTEX/Transport/FixedPrice.cs +++ b/Src/VTEX/Transport/FixedPrice.cs @@ -27,13 +27,13 @@ public sealed class FixedPrice public decimal Value { get; set; } /// - /// Gets or sets the listprice. + /// Gets or sets the list price. /// /// - /// The listprice. + /// The list price. /// [JsonProperty("listPrice")] - public decimal? Listprice { get; set; } + public decimal? ListPrice { get; set; } /// /// Gets or sets the minimum quantity. diff --git a/Src/VTEX/Transport/Inventory.cs b/Src/VTEX/Transport/Inventory.cs index d1d4bef..55f43bf 100644 --- a/Src/VTEX/Transport/Inventory.cs +++ b/Src/VTEX/Transport/Inventory.cs @@ -14,7 +14,7 @@ public sealed class Inventory /// /// The sku identifier. [JsonProperty("skuid")] - public int SKUId { get; set; } + public int SkuId { get; set; } /// /// Gets or sets the balances. diff --git a/Src/VTEX/Transport/LogisticsInfo.cs b/Src/VTEX/Transport/LogisticsInfo.cs index 462d16d..95c8952 100644 --- a/Src/VTEX/Transport/LogisticsInfo.cs +++ b/Src/VTEX/Transport/LogisticsInfo.cs @@ -121,13 +121,13 @@ public sealed class LogisticsInfo public PickupStoreInfo PickupStoreInfo { get; set; } /// - /// Gets or sets the addres identifier. + /// Gets or sets the address identifier. /// /// - /// The addres identifier. + /// The address identifier. /// [JsonProperty("addressId")] - public string AddresId { get; set; } + public string AddressId { get; set; } /// /// Gets or sets the name of the polygon. diff --git a/Src/VTEX/Transport/PCIPayment.cs b/Src/VTEX/Transport/PCIPayment.cs index f4b4a2a..387813b 100644 --- a/Src/VTEX/Transport/PCIPayment.cs +++ b/Src/VTEX/Transport/PCIPayment.cs @@ -1,6 +1,5 @@ namespace VTEX.Transport { - using CrispyWaffle.Extensions; using CrispyWaffle.Serialization; using System; using System.Collections.Generic; @@ -8,10 +7,10 @@ using System.Linq; /// - /// Class PCIPayment. This class cannot be inherited. + /// Class PCI payment. This class cannot be inherited. /// [Serializer(SerializerFormat.JSON)] - public sealed class PCIPayment + public sealed class PciPayment { #region Public methods @@ -20,9 +19,9 @@ public sealed class PCIPayment /// /// Name of the field. /// - public PCIPaymentField GetFieldByName([Localizable(false)] string fieldName) + public PciPaymentField GetFieldByName([Localizable(false)] string fieldName) { - return Fields.SingleOrDefault(f => f.Name.Equals(fieldName, StringExtensions.Comparison)); + return Fields.SingleOrDefault(f => f.Name.Equals(fieldName, StringComparison.InvariantCultureIgnoreCase)); } #endregion @@ -199,7 +198,7 @@ public PCIPaymentField GetFieldByName([Localizable(false)] string fieldName) /// Gets or sets the fields. /// /// The fields. - public IReadOnlyCollection Fields { get; set; } + public IReadOnlyCollection Fields { get; set; } /// /// Gets or sets the sheets. diff --git a/Src/VTEX/Transport/PCIPaymentField.cs b/Src/VTEX/Transport/PCIPaymentField.cs index 10c0413..d9c0985 100644 --- a/Src/VTEX/Transport/PCIPaymentField.cs +++ b/Src/VTEX/Transport/PCIPaymentField.cs @@ -4,7 +4,7 @@ namespace VTEX.Transport /// /// Class PCIPaymentField. This class cannot be inherited. /// - public sealed class PCIPaymentField + public sealed class PciPaymentField { /// /// Gets or sets the name. diff --git a/Src/VTEX/Transport/Price.cs b/Src/VTEX/Transport/Price.cs index ce9b90e..00bb6cb 100644 --- a/Src/VTEX/Transport/Price.cs +++ b/Src/VTEX/Transport/Price.cs @@ -87,7 +87,10 @@ public decimal? ListPrice set { if (!value.HasValue) + { return; + } + _listPrice = value.Value; _listPriceSet = true; } diff --git a/Src/VTEX/Transport/ResponseReceipt.cs b/Src/VTEX/Transport/ResponseReceipt.cs index 1e4178f..9552b5a 100644 --- a/Src/VTEX/Transport/ResponseReceipt.cs +++ b/Src/VTEX/Transport/ResponseReceipt.cs @@ -32,7 +32,10 @@ public string DateInternal set { if (!string.IsNullOrWhiteSpace(value)) + { _date = DateTime.Parse(value); + } + _dateSet = true; } } diff --git a/Src/VTEX/Transport/TrackingEvent.cs b/Src/VTEX/Transport/TrackingEvent.cs index 45dc6e4..ad30a84 100644 --- a/Src/VTEX/Transport/TrackingEvent.cs +++ b/Src/VTEX/Transport/TrackingEvent.cs @@ -70,7 +70,10 @@ public string DateInternal set { if (!string.IsNullOrWhiteSpace(value)) + { _date = DateTime.Parse(value); + } + _dateSet = true; } } diff --git a/Src/VTEX/VTEX.csproj b/Src/VTEX/VTEX.csproj index 3964a56..40fc109 100644 --- a/Src/VTEX/VTEX.csproj +++ b/Src/VTEX/VTEX.csproj @@ -1,7 +1,7 @@ - D1E5B509-0934-4E15-B78D-D3A88AC8CB16 + {D1E5B509-0934-4E15-B78D-D3A88AC8CB16} netstandard2.0;netstandard2.1 true Guilherme Branco Stracini @@ -22,7 +22,7 @@ - + diff --git a/Src/VTEX/VTEXContext.cs b/Src/VTEX/VTEXContext.cs index f054386..f6229ba 100644 --- a/Src/VTEX/VTEXContext.cs +++ b/Src/VTEX/VTEXContext.cs @@ -1,4 +1,5 @@ -using VTEX.Health; +using System.Globalization; +using VTEX.Health; namespace VTEX { @@ -52,12 +53,21 @@ public VTEXContext(string accountName, string appKey, string appToken, string co { _wrapper = new VTEXWrapper(accountName); if (string.IsNullOrWhiteSpace(appKey)) + { throw new ArgumentNullException(nameof(appKey)); + } + if (string.IsNullOrWhiteSpace(appToken)) + { throw new ArgumentNullException(nameof(appToken)); + } + _wrapper.SetRestCredentials(appKey, appToken); if (string.IsNullOrWhiteSpace(cookie)) + { return; + } + _wrapper.SetVtexIdClientAuthCookie(cookie); } @@ -82,20 +92,41 @@ private OrdersList GetOrdersListInternal(string status = null, DateTime? startDa var currentPage = 1; var queryString = new Dictionary { { @"page", @"0" }, { @"per_page", @"50" } }; if (!string.IsNullOrWhiteSpace(status)) + { queryString.Add(@"f_status", status); + } + if (!string.IsNullOrWhiteSpace(salesChannel)) + { queryString.Add(@"f_salesChannel", salesChannel); + } + if (!string.IsNullOrWhiteSpace(affiliatedId)) + { queryString.Add(@"f_affiliateId", affiliatedId); + } + if (!string.IsNullOrWhiteSpace(paymentSystemName)) + { queryString.Add(@"f_paymentNames", paymentSystemName); + } + if (startDate.HasValue && endDate.HasValue) + { queryString.Add(@"f_creationDate", $@"creationDate:[{startDate.Value.ToUniversalTime():s}Z TO {endDate.Value.ToUniversalTime():s}Z]"); + } + if (!string.IsNullOrWhiteSpace(genericQuery)) + { queryString.Add(@"q", genericQuery); + } + queryString.Add(@"orderBy", @"creationDate,asc"); while (GetOrderListsValueInternal(queryString, currentPage, ref result)) + { currentPage++; + } + LogConsumer.Info("{0} orders found", result.List.Length); return result; } @@ -117,18 +148,29 @@ private bool GetOrderListsValueInternal( try { LogConsumer.Trace("Getting page {0} of orders list", currentPage); - queryString[@"page"] = currentPage.ToString(StringExtensions.Culture); + queryString[@"page"] = currentPage.ToString(CultureInfo.InvariantCulture); - json = _wrapper.ServiceInvokerAsync(HttpRequestMethod.GET, PlatformConstants.OMS_ORDERS, CancellationToken.None, queryString).Result; + json = _wrapper.ServiceInvokerAsync(HttpRequestMethod.GET, PlatformConstants.OmsOrders, CancellationToken.None, queryString).Result; var temp = SerializerFactory.GetSerializer().Deserialize(json); if (result == null) + { result = temp; + } else + { result.List = result.List.Concat(temp.List).ToArray(); + } + if (temp.Paging.Pages == 1 || temp.Paging.CurrentPage >= temp.Paging.Pages) + { return false; + } + if (currentPage == 1) + { LogConsumer.Trace("{0} pages of orders list", temp.Paging.Pages); + } + return true; } catch (JsonSerializationException e) @@ -159,9 +201,12 @@ private IEnumerable GetOrdersInternal(IEnumerable ordersIds) private Order GetOrderInternal(string orderId) { LogConsumer.Trace("Getting order {0}", orderId); - var json = _wrapper.ServiceInvokerAsync(HttpRequestMethod.GET, $"{PlatformConstants.OMS_ORDERS}/{orderId}", CancellationToken.None).Result; + var json = _wrapper.ServiceInvokerAsync(HttpRequestMethod.GET, $"{PlatformConstants.OmsOrders}/{orderId}", CancellationToken.None).Result; if (json == null) + { return null; + } + try { var order = SerializerFactory.GetSerializer().Deserialize(json); @@ -173,13 +218,21 @@ private Order GetOrderInternal(string orderId) if (payment != null && payment.PaymentSystem == 0 && !string.IsNullOrWhiteSpace(order.AffiliateId)) + { LogConsumer.Info(@"Marketplace {0}", order.AffiliateId); - else if (transaction.TransactionId != null && !transaction.TransactionId.Equals(@"NO-PAYMENT", StringExtensions.Comparison)) + } + else if (transaction.TransactionId != null && !transaction.TransactionId.Equals(@"NO-PAYMENT", StringComparison.InvariantCultureIgnoreCase)) + { LogConsumer.Info(@"Bank bill {0}", order.Sequence); + } else if (order.Totals.Sum(t => t.Value) == 0) + { LogConsumer.Warning("Promotion / discount coupon - order subsidized"); + } else + { throw new InvalidPaymentDataException(orderId); + } #endregion @@ -190,9 +243,14 @@ private Order GetOrderInternal(string orderId) var client = SearchAsync(@"userId", order.ClientProfileData.UserProfileId, CancellationToken.None).Result; if (client != null && !string.IsNullOrWhiteSpace(client.Email)) + { order.ClientProfileData.Email = client.Email; - if (order.ClientProfileData.Email.IndexOf(@"ct.vtex", StringExtensions.Comparison) != -1) + } + + if (order.ClientProfileData.Email.IndexOf(@"ct.vtex", StringComparison.InvariantCultureIgnoreCase) != -1) + { order.ClientProfileData.Email = @"pedido@editorainovacao.com.br"; + } } #endregion @@ -230,11 +288,14 @@ public IEnumerable GetFeed(int maxLot = 20) { //VTEX limitation if (maxLot > 20) + { maxLot = 20; + } + LogConsumer.Trace("Getting up to {0} events in order feed", maxLot); var json = _wrapper.ServiceInvokerAsync( HttpRequestMethod.GET, - $"{PlatformConstants.OMS_FEED}", + $"{PlatformConstants.OmsFeed}", CancellationToken.None, new Dictionary { { @"maxLot", maxLot.ToString() } }) .Result; @@ -251,7 +312,7 @@ public void CommitFeed(OrderFeed feed) var data = (string)new OrderFeedCommit { CommitToken = feed.CommitToken }.GetSerializer(); _wrapper.ServiceInvokerAsync( HttpRequestMethod.POST, - $"{PlatformConstants.OMS_FEED}confirm", + $"{PlatformConstants.OmsFeed}confirm", CancellationToken.None, data: data).Wait(); } @@ -288,7 +349,10 @@ public IEnumerable GetOrders(OrderStatus status) { var ordersIds = GetOrdersList(status).Select(order => order.OrderId).ToList(); if (ordersIds.Any()) + { return GetOrdersInternal(ordersIds); + } + LogConsumer.Warning("No orders with status {0} found", status.GetHumanReadableValue()); return new Order[0]; } @@ -316,7 +380,10 @@ public IEnumerable GetOrders(DateTime startDate, DateTime endDate) { var ordersIds = GetOrdersList(startDate, endDate).Select(order => order.OrderId).ToList(); if (ordersIds.Any()) + { return GetOrdersInternal(ordersIds); + } + LogConsumer.Warning("No orders between {0:G} and {1:G} found", startDate, endDate); return new Order[0]; } @@ -346,7 +413,10 @@ public IEnumerable GetOrders(OrderStatus status, DateTime startDate, Date { var ordersIds = GetOrdersList(status, startDate, endDate).Select(order => order.OrderId).ToList(); if (ordersIds.Any()) + { return GetOrdersInternal(ordersIds); + } + LogConsumer.Warning("No order with status {0} between {1:G} and {2:G} found", status.GetHumanReadableValue(), startDate, endDate); return new Order[0]; } @@ -374,7 +444,10 @@ public IEnumerable GetOrders(OrderStatus status, string affiliatedId) { var ordersIds = GetOrdersList(status, affiliatedId).Select(order => order.OrderId).ToList(); if (ordersIds.Any()) + { return GetOrdersInternal(ordersIds); + } + LogConsumer.Warning("No order with status {0} and affiliated {1} found", status.GetHumanReadableValue(), affiliatedId); return new Order[0]; } @@ -400,7 +473,10 @@ public IEnumerable GetOrders(string query) { var ordersIds = GetOrdersList(query).Select(order => order.OrderId).ToList(); if (ordersIds.Any()) + { return GetOrdersInternal(ordersIds); + } + LogConsumer.Warning("No orders with term '{0}' found", query); return new Order[0]; } @@ -429,11 +505,17 @@ public async Task CancelOrderAsync(string orderId) var source = new CancellationTokenSource(new TimeSpan(0, 5, 0)); var order = GetOrder(orderId); if (order.Status == OrderStatus.CANCELED) + { return string.Empty; + } + if (order.Status != OrderStatus.PAYMENT_PENDING && order.Status != OrderStatus.AWAITING_AUTHORIZATION_TO_DISPATCH) + { throw new InvalidOperationException( $"Order {orderId} cannot be canceled because isn't in pending payment status on VTEX"); - var json = await _wrapper.ServiceInvokerAsync(HttpRequestMethod.POST, $"{PlatformConstants.OMS_ORDERS}/{orderId}/cancel", source.Token); + } + + var json = await _wrapper.ServiceInvokerAsync(HttpRequestMethod.POST, $"{PlatformConstants.OmsOrders}/{orderId}/cancel", source.Token).ConfigureAwait(false); var receipt = SerializerFactory.GetSerializer().Deserialize(json); LogConsumer.Info("Order {0} successfully canceled. Receipt: {1}", order.Sequence, receipt.Receipt); return receipt.Receipt; @@ -458,7 +540,7 @@ public async Task ChangeOrderStatusAsync(string orderId, OrderStatus newStatus) { LogConsumer.Info("Changing order {0} status to {1}", orderId, newStatus.GetHumanReadableValue()); var source = new CancellationTokenSource(new TimeSpan(0, 5, 0)); - var json = await _wrapper.ServiceInvokerAsync(HttpRequestMethod.POST, $"{PlatformConstants.OMS_ORDERS}/{orderId}/changestate/{newStatus.GetInternalValue()}", source.Token); + var json = await _wrapper.ServiceInvokerAsync(HttpRequestMethod.POST, $"{PlatformConstants.OmsOrders}/{orderId}/changestate/{newStatus.GetInternalValue()}", source.Token).ConfigureAwait(false); LogConsumer.Info(json); } catch (AggregateException e) @@ -485,15 +567,18 @@ public async Task NotifyOrderPaidAsync(string orderId) var order = GetOrder(orderId); if (order.Status != OrderStatus.PAYMENT_PENDING && order.Status != OrderStatus.AWAITING_AUTHORIZATION_TO_DISPATCH) + { return; + } + if (order.Status == OrderStatus.AWAITING_AUTHORIZATION_TO_DISPATCH) { - await ChangeOrderStatusAsync(order.OrderId, OrderStatus.AUTHORIZE_FULFILLMENT); + await ChangeOrderStatusAsync(order.OrderId, OrderStatus.AUTHORIZE_FULFILLMENT).ConfigureAwait(false); return; } var paymentId = order.PaymentData.Transactions.First().Payments.First().Id; _wrapper.ServiceInvokerAsync(HttpRequestMethod.POST, - $"{PlatformConstants.OMS_ORDERS}/{order.OrderId}/payments/{paymentId}/payment-notification", + $"{PlatformConstants.OmsOrders}/{order.OrderId}/payments/{paymentId}/payment-notification", source.Token).Wait(source.Token); } @@ -536,7 +621,7 @@ public async Task NotifyOrderShippedAsync( $"vtex-shipping-notification-{orderId}-{notification.InvoiceNumber}.js"); var json = await _wrapper.ServiceInvokerAsync( HttpRequestMethod.POST, - $"{PlatformConstants.OMS_INVOICES}/{orderId}/invoice", + $"{PlatformConstants.OmsInvoices}/{orderId}/invoice", token, data: (string)notification.GetSerializer()) .ConfigureAwait(false); @@ -567,11 +652,11 @@ public async ValueTask NotifyOrderDelivered(Tracking tracking) var source = new CancellationTokenSource(new TimeSpan(0, 5, 0)); LogConsumer.Debug(tracking, $"vtex-tracking-info-{tracking.OrderId}-{tracking.InvoiceNumber}.js"); var json = await _wrapper.ServiceInvokerAsync(HttpRequestMethod.PUT, - string.Format(PlatformConstants.OMS_TRACKING, + string.Format(PlatformConstants.OmsTracking, tracking.OrderId, tracking.InvoiceNumber), source.Token, - data: (string)tracking.GetSerializer()); + data: (string)tracking.GetSerializer()).ConfigureAwait(false); var receipt = SerializerFactory.GetSerializer().Deserialize(json); LogConsumer.Trace(receipt.Receipt); return receipt.Receipt; @@ -597,7 +682,7 @@ public void UpdateOrderInvoice(string orderId, string invoiceId, ShippingNotific var source = new CancellationTokenSource(new TimeSpan(0, 5, 0)); LogConsumer.Debug(notification, $"vtex-shipping-notification-{orderId}-{invoiceId}.js"); var json = _wrapper.ServiceInvokerAsync(HttpRequestMethod.PATCH, - $"{PlatformConstants.OMS_ORDERS}/{orderId}/invoice/{invoiceId}", + $"{PlatformConstants.OmsOrders}/{orderId}/invoice/{invoiceId}", source.Token, data: (string)notification.GetSerializer()).Result; var receipt = SerializerFactory.GetSerializer().Deserialize(json); LogConsumer.Trace(receipt.Receipt); @@ -622,7 +707,7 @@ public void ChangeOrder(string orderId, ChangeOrder change) LogConsumer.Debug(change, $"vtex-change-order-{orderId}.js"); var json = _wrapper.ServiceInvokerAsync( HttpRequestMethod.POST, - $"{PlatformConstants.OMS_ORDERS}/{orderId}/changes", + $"{PlatformConstants.OmsOrders}/{orderId}/changes", CancellationToken.None, data: (string)change.GetSerializer()).Result; var receipt = SerializerFactory.GetSerializer().Deserialize(json); @@ -651,7 +736,7 @@ public IEnumerable GetTransactionInteractions(string tra { LogConsumer.Info("Getting interactions of transaction {0}", transactionId); var json = _wrapper.ServiceInvokerAsync(HttpRequestMethod.GET, - $"{PlatformConstants.PCI_TRANSACTIONS}/{transactionId}/interactions", + $"{PlatformConstants.PciTransactions}/{transactionId}/interactions", CancellationToken.None, restEndpoint: RequestEndpoint.PAYMENTS).Result; return SerializerFactory.GetSerializer>().Deserialize(json); @@ -672,7 +757,7 @@ public IEnumerable GetTransactionInteractions(string tra /// The sku identifier. /// The stock. /// Int32. - public async Task GetSKUReservationsAsync(int skuId, Warehouse stock) + public async Task GetSkuReservationsAsync(int skuId, Warehouse stock) { try { @@ -680,7 +765,7 @@ public async Task GetSKUReservationsAsync(int skuId, Warehouse stock) var source = new CancellationTokenSource(new TimeSpan(0, 5, 0)); var json = await _wrapper.ServiceInvokerAsync( HttpRequestMethod.GET, - $"{PlatformConstants.LOG_RESERVATIONS}/{stock.GetInternalValue()}/{skuId}", + $"{PlatformConstants.LogReservations}/{stock.GetInternalValue()}/{skuId}", source.Token).ConfigureAwait(false); var reservations = SerializerFactory.GetSerializer().Deserialize(json); LogConsumer.Debug(reservations, $"vtex-sku-reservations-{skuId}.js"); @@ -700,12 +785,12 @@ public async Task GetSKUReservationsAsync(int skuId, Warehouse stock) /// /// The sku identifier. /// Inventory. - public async Task GetSKUInventoryAsync(int skuId) + public async Task GetSkuInventoryAsync(int skuId) { LogConsumer.Info("Getting inventory of SKU {0}", skuId); var source = new CancellationTokenSource(new TimeSpan(0, 5, 0)); var json = await _wrapper.ServiceInvokerAsync(HttpRequestMethod.GET, - $"{PlatformConstants.LOG_INVENTORY}/{skuId}", + $"{PlatformConstants.LogInventory}/{skuId}", source.Token, restEndpoint: RequestEndpoint.LOGISTICS).ConfigureAwait(false); var inventory = SerializerFactory.GetSerializer().Deserialize(json); LogConsumer.Debug(inventory, $"vtex-sku-inventory-{skuId}.js"); @@ -716,17 +801,23 @@ public async Task GetSKUInventoryAsync(int skuId) /// Updates the sku stock. /// /// The stock information. - /// + /// - public async Task UpdateSKUStockAsync(StockInfo stockInfo) + public async Task UpdateSkuStockAsync(StockInfo stockInfo) { try { if (stockInfo.Quantity < 0) + { stockInfo.Quantity = 0; + } + stockInfo.DateUtcOnBalanceSystem = null; if (!stockInfo.UnlimitedQuantity) - stockInfo.Quantity += await GetSKUReservationsAsync(stockInfo.ItemId, stockInfo.WareHouseEnum).ConfigureAwait(false); + { + stockInfo.Quantity += await GetSkuReservationsAsync(stockInfo.ItemId, stockInfo.WareHouseEnum).ConfigureAwait(false); + } + LogConsumer.Info("Updating inventory of SKU {0} on warehouse {1} with {2} units", stockInfo.ItemId, stockInfo.WareHouseEnum.GetHumanReadableValue(), @@ -735,13 +826,13 @@ public async Task UpdateSKUStockAsync(StockInfo stockInfo) var data = @"[" + (string)stockInfo.GetSerializer() + @"]"; LogConsumer.Debug(stockInfo, $"vtex-sku-stock-{stockInfo.ItemId}.js"); await _wrapper.ServiceInvokerAsync(HttpRequestMethod.POST, - PlatformConstants.LOG_WAREHOUSES, + PlatformConstants.LogWarehouses, source.Token, data: data).ConfigureAwait(false); } catch (Exception e) { - throw new UpdateStockInfoSKUException(stockInfo.ItemId, e); + throw new UpdateStockInfoSkuException(stockInfo.ItemId, e); } } @@ -763,7 +854,7 @@ public async Task GetPriceAsync(int skuId) { var json = await _wrapper.ServiceInvokerAsync( HttpRequestMethod.GET, - $@"{PlatformConstants.PRICING}/{skuId}", + $@"{PlatformConstants.Pricing}/{skuId}", source.Token, restEndpoint: RequestEndpoint.API) .ConfigureAwait(false); @@ -772,7 +863,10 @@ public async Task GetPriceAsync(int skuId) catch (UnexpectedApiResponseException e) { if (e.StatusCode == 404) + { return new Price(); + } + throw; } } @@ -796,7 +890,10 @@ public async Task UpdatePriceAsync(Price price, int skuId, CancellationToken tok var oldPrice = await GetPriceAsync(skuId).ConfigureAwait(false); if (oldPrice?.FixedPrices != null && oldPrice.FixedPrices.Any()) + { await DeletePriceAsync(skuId, token).ConfigureAwait(false); + } + LogConsumer.Info("Updating the price of sku {0} to {1} (list price: {2})", skuId, price.CostPrice.ToMonetary(), @@ -805,7 +902,7 @@ public async Task UpdatePriceAsync(Price price, int skuId, CancellationToken tok : "no"); await _wrapper.ServiceInvokerAsync( HttpRequestMethod.PUT, - $@"{PlatformConstants.PRICING}/{skuId}", + $@"{PlatformConstants.Pricing}/{skuId}", token, data: (string)price.GetSerializer(), restEndpoint: RequestEndpoint.API) @@ -813,7 +910,7 @@ await _wrapper.ServiceInvokerAsync( } catch (Exception e) { - throw new UpdatePriceInfoSKUException(skuId, e); + throw new UpdatePriceInfoSkuException(skuId, e); } } @@ -829,7 +926,7 @@ public async Task DeletePriceAsync(int skuId, CancellationToken token) LogConsumer.Info("Deleting the price of sku {0}", skuId); await _wrapper.ServiceInvokerAsync( HttpRequestMethod.DELETE, - $@"{PlatformConstants.PRICING}/{skuId}", + $@"{PlatformConstants.Pricing}/{skuId}", token, restEndpoint: RequestEndpoint.API) .ConfigureAwait(false); @@ -859,10 +956,13 @@ public IEnumerable GetBridgeFacets([Localizable(false)]string query {@"_where", query} }; if (!string.IsNullOrWhiteSpace(keywords)) + { queryString.Add(@"_keywords", $@"*{keywords}*"); + } + var json = _wrapper.ServiceInvokerAsync( HttpRequestMethod.GET, - $"{PlatformConstants.BRIDGE_SEARCH}/facets", + $"{PlatformConstants.BridgeSearch}/facets", source.Token, queryString, restEndpoint: RequestEndpoint.BRIDGE).Result; @@ -909,9 +1009,12 @@ public IEnumerable GetBridgeItems( {@"limit", limit.ToString()} }; if (!string.IsNullOrWhiteSpace(keywords)) + { queryString.Add(@"_keywords", $@"*{keywords}*"); + } + var json = _wrapper.ServiceInvokerAsync(HttpRequestMethod.GET, - PlatformConstants.BRIDGE_SEARCH, + PlatformConstants.BridgeSearch, source.Token, queryString, restEndpoint: RequestEndpoint.BRIDGE).Result; @@ -951,7 +1054,10 @@ public IEnumerable GetAllBridgeItems( var result = new List(total); var pages = total / perPage + 1; for (var x = 0; x < pages; x++) + { result.AddRange(GetBridgeItems(query, sort, keywords, x * perPage, perPage)); + } + return result; } @@ -994,15 +1100,18 @@ public async Task> GetPlatformStatusAsync(Cancellati /// The transaction identifier. /// [Pure] - public List GetOrderPayments(string transactionId) + public List GetOrderPayments(string transactionId) { var json = _wrapper.ServiceInvokerAsync(HttpRequestMethod.GET, - $"{PlatformConstants.PCI_TRANSACTIONS}/{transactionId}/payments", + $"{PlatformConstants.PciTransactions}/{transactionId}/payments", CancellationToken.None, restEndpoint: RequestEndpoint.PAYMENTS).Result; if (json == null) - return new List(); - var data = SerializerFactory.GetCustomSerializer>(SerializerFormat.JSON).Deserialize(json); + { + return new List(); + } + + var data = SerializerFactory.GetCustomSerializer>(SerializerFormat.JSON).Deserialize(json); LogConsumer.Debug(data, $"vtex-order-payemnts-{transactionId}.js"); return data; } @@ -1025,7 +1134,7 @@ public async Task GetSpecificationFieldAsync(int fieldId, Ca LogConsumer.Info("Getting field for the field id {0}", fieldId); var json = await _wrapper.ServiceInvokerAsync( HttpRequestMethod.GET, - $@"{PlatformConstants.CATALOG_PUB}/specification/fieldGet/{fieldId}", + $@"{PlatformConstants.CatalogPub}/specification/fieldGet/{fieldId}", token) .ConfigureAwait(false); var field = SerializerFactory.GetSerializer().Deserialize(json); @@ -1047,7 +1156,7 @@ public async Task> GetSpecificationFieldVal LogConsumer.Info("Getting field values for the field id {0}", fieldId); var json = await _wrapper.ServiceInvokerAsync( HttpRequestMethod.GET, - $@"{PlatformConstants.CATALOG_PUB}/specification/fieldvalue/{fieldId}", + $@"{PlatformConstants.CatalogPub}/specification/fieldvalue/{fieldId}", token) .ConfigureAwait(false); var fieldValues = SerializerFactory.GetSerializer>().Deserialize(json); @@ -1090,7 +1199,7 @@ public async Task UpdateProductSpecificationsAsync( var data = (string)specifications.GetSerializer(); await _wrapper.ServiceInvokerAsync( HttpRequestMethod.POST, - $@"{PlatformConstants.CATALOG}/products/{productId}/specification", + $@"{PlatformConstants.Catalog}/products/{productId}/specification", token, data: data) .ConfigureAwait(false); @@ -1109,7 +1218,7 @@ public async Task InsertSpecificationFieldValueAsync(SpecificationFieldValue fie var data = (string)fieldValue.GetSerializer(); await _wrapper.ServiceInvokerAsync( HttpRequestMethod.POST, - $@"{PlatformConstants.CATALOG}/specification/fieldValue", + $@"{PlatformConstants.Catalog}/specification/fieldValue", token, data: data) .ConfigureAwait(false); @@ -1140,7 +1249,9 @@ public async Task SearchAsync( where TDataEntity : class, IDataEntity, new() { if (string.IsNullOrWhiteSpace(searchedValue)) + { throw new ArgumentNullException(nameof(searchedValue)); + } var queryString = new Dictionary { @@ -1160,7 +1271,10 @@ public async Task SearchAsync( .ConfigureAwait(false); var entity = SerializerFactory.GetSerializer>().Deserialize(json).FirstOrDefault(); if (entity == null) + { return null; + } + LogConsumer.Debug(entity, $@"vtex-masterdata-entity-{entityName}-{searchedField}-{searchedValue}.js"); return entity; } diff --git a/Src/VTEX/VTEXWrapper.cs b/Src/VTEX/VTEXWrapper.cs index 6557599..c067806 100644 --- a/Src/VTEX/VTEXWrapper.cs +++ b/Src/VTEX/VTEXWrapper.cs @@ -59,7 +59,10 @@ private static string InternalUserAgent get { if (!string.IsNullOrWhiteSpace(_internalUserAgent)) + { return _internalUserAgent; + } + var assembly = System.Reflection.Assembly.GetAssembly(typeof(VTEXWrapper)).GetName(); _internalUserAgent = $@"{assembly.Name}/{assembly.Version}"; return _internalUserAgent; @@ -135,7 +138,10 @@ private async Task ServiceInvokerInternal( using var client = new HttpClient(handler); ConfigureClient(client, requiresAuthentication); if (cookie != null) + { cookieContainer.Add(uriBuilder.Uri, cookie); + } + response = await RequestInternalAsync(method, token, data, client, uriBuilder) .ConfigureAwait(false); token.ThrowIfCancellationRequested(); @@ -148,15 +154,19 @@ private async Task ServiceInvokerInternal( var ex = e.InnerExceptions.FirstOrDefault() ?? e.InnerException ?? e; exr = HandleException(ex, response, uriBuilder.Uri, method, data, result); if (isRetry) + { throw exr; + } } catch (Exception e) { exr = HandleException(e, response, uriBuilder.Uri, method, data, result); if (isRetry) + { throw exr; + } } - return await ServiceInvokerInternal(method, endpoint, token, data, uriBuilder, cookie, requiresAuthentication, true); + return await ServiceInvokerInternal(method, endpoint, token, data, uriBuilder, cookie, requiresAuthentication, true).ConfigureAwait(false); } /// @@ -179,7 +189,10 @@ private Exception HandleException( { var statusCode = 0; if (response != null) + { statusCode = (int)response.StatusCode; + } + var ex = new UnexpectedApiResponseException(uri, method.ToString(), data, result, statusCode, exception); if (statusCode == 429 || statusCode == 503) @@ -194,7 +207,10 @@ private Exception HandleException( statusCode != 408 && statusCode != 500 && statusCode != 502) + { throw ex; + } + LogConsumer.Warning("Retrying the {0} request", method.ToString()); TelemetryAnalytics.TrackHit($"VTEX_handle_exception_retrying_{method.ToString()}_request"); return ex; @@ -212,7 +228,10 @@ private void ConfigureClient(HttpClient client, bool requiresAuthentication) client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(@"application/json")); client.DefaultRequestHeaders.TryAddWithoutValidation(@"User-Agent", $@"guiBranco-VTEX-SDK-dotnet {InternalUserAgent} +https://github.com/guibranco/VTEX-SDK-dotnet"); if (!requiresAuthentication) + { return; + } + client.DefaultRequestHeaders.Add(@"X-VTEX-API-AppKey", _appKey); client.DefaultRequestHeaders.Add(@"X-VTEX-API-AppToken", _appToken); } @@ -237,7 +256,10 @@ private static async Task RequestInternalAsync( HttpResponseMessage response; StringContent content = null; if (!string.IsNullOrWhiteSpace(data)) + { content = new StringContent(data, Encoding.UTF8, @"application/json"); + } + switch (method) { case HttpRequestMethod.DELETE: @@ -328,7 +350,10 @@ public async Task ServiceInvokerAsync( host = @"logistics.vtexcommercestable.com.br"; endpoint = $@"api/{endpoint}"; if (queryString == null) + { queryString = new Dictionary(); + } + queryString.Add(@"an", _accountName); break; case RequestEndpoint.API: @@ -340,7 +365,10 @@ public async Task ServiceInvokerAsync( host = $@"{_accountName}.myvtex.com"; endpoint = $@"api/{endpoint}"; if (!string.IsNullOrWhiteSpace(_authCookie)) + { cookie = new Cookie("VtexIdclientAutCookie", _authCookie); + } + break; case RequestEndpoint.HEALTH: protocol = @"http"; @@ -355,7 +383,10 @@ public async Task ServiceInvokerAsync( var query = string.Empty; if (queryString != null && queryString.Count > 0) + { query = new QueryStringBuilder().AddRange(queryString).ToString(); + } + var builder = new UriBuilder(protocol, host, port, endpoint) { Query = query.Replace(@"?", string.Empty) diff --git a/Tests/VTEX.Tests/Health/VtexHealthClientTests.cs b/Tests/VTEX.Tests/Health/VtexHealthClientTests.cs index 429237f..78c41f5 100644 --- a/Tests/VTEX.Tests/Health/VtexHealthClientTests.cs +++ b/Tests/VTEX.Tests/Health/VtexHealthClientTests.cs @@ -36,7 +36,7 @@ public async Task ValidateHealthClient() clientMock.Setup(c => c.GetPlatformStatuesAsync(It.IsAny())) .ReturnsAsync(fixtures); - var result = await clientMock.Object.GetPlatformStatuesAsync(CancellationToken.None); + var result = await clientMock.Object.GetPlatformStatuesAsync(CancellationToken.None).ConfigureAwait(false); Assert.NotNull(result); diff --git a/Tests/VTEX.Tests/VTEX.Tests.csproj b/Tests/VTEX.Tests/VTEX.Tests.csproj index 73c14a9..0c9fdc3 100644 --- a/Tests/VTEX.Tests/VTEX.Tests.csproj +++ b/Tests/VTEX.Tests/VTEX.Tests.csproj @@ -8,15 +8,15 @@ - + runtime; build; native; contentfiles; analyzers all - - + + - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/VTEX.sln b/VTEX.sln index 30c8957..3157a06 100644 --- a/VTEX.sln +++ b/VTEX.sln @@ -3,26 +3,26 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.29920.165 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Src", "Src", "{6ECBC782-CB7F-46F8-8D66-66C9E22B0CCC}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{C4DD4B0B-84DE-474B-897D-3960034AB956}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VTEX", "Src\VTEX\VTEX.csproj", "{D1E5B509-0934-4E15-B78D-D3A88AC8CB16}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VTEX.Tests", "Tests\VTEX.Tests\VTEX.Tests.csproj", "{2FD2F4CE-DCAB-4F78-8A20-A22CD7F74CFB}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{5BF19C4C-3D84-4618-8A7B-044C0B15187F}" ProjectSection(SolutionItems) = preProject appveyor.yml = appveyor.yml README.md = README.md EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VTEX.Health", "Src\VTEX.Health\VTEX.Health.csproj", "{931C39A1-583E-4264-AC7C-508C7B1FC15E}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Src", "Src", "{6ECBC782-CB7F-46F8-8D66-66C9E22B0CCC}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{C4DD4B0B-84DE-474B-897D-3960034AB956}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VTEX", "Src\VTEX\VTEX.csproj", "{D1E5B509-0934-4E15-B78D-D3A88AC8CB16}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VTEX.API", "Src\VTEX.API\VTEX.API.csproj", "{35950C06-05C0-4448-BBE3-3A71C34B8FD5}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VTEX.Core", "Src\VTEX.Core\VTEX.Core.csproj", "{D6864E5A-45B5-4CD1-8EC5-15E10A3B8F1B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VTEX.Health", "Src\VTEX.Health\VTEX.Health.csproj", "{931C39A1-583E-4264-AC7C-508C7B1FC15E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VTEX.Tests", "Tests\VTEX.Tests\VTEX.Tests.csproj", "{2FD2F4CE-DCAB-4F78-8A20-A22CD7F74CFB}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/VTEX.sln.DotSettings b/VTEX.sln.DotSettings new file mode 100644 index 0000000..ed90e5d --- /dev/null +++ b/VTEX.sln.DotSettings @@ -0,0 +1,8 @@ + + True + True + True + True + True + True + True \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index 75d579c..af64022 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.1.{build} +version: 2.2.{build} skip_tags: true image: Visual Studio 2019 configuration: Release @@ -66,19 +66,30 @@ build_script: after_build: - xcopy %CD%\Src\%SOLUTION_NAME%\bin\Release\netstandard2.1\*.* %CD%\Build\ + - copy %CD%\Src\%SOLUTION_NAME%\bin\Release\%SOLUTION_NAME%.%APPVEYOR_BUILD_VERSION%.nupkg %SOLUTION_NAME%.%APPVEYOR_BUILD_VERSION%.nupkg +- copy %CD%\Src\%SOLUTION_NAME%.Health\bin\Release\%SOLUTION_NAME%.Health.%APPVEYOR_BUILD_VERSION%.nupkg %SOLUTION_NAME%.Health.%APPVEYOR_BUILD_VERSION%.nupkg + - rd /s /q %CD%\Src\%SOLUTION_NAME%\bin\Release\ + - xcopy %CD%\Tests\%SOLUTION_NAME%.Tests\*.xml %CD%\Coverage\ - xcopy %CD%\Tests\%SOLUTION_NAME%.Tests\*.json %CD%\Coverage\ + - cd %CD% + - 7z a -tzip -mx9 "%SOLUTION_NAME%.%APPVEYOR_BUILD_VERSION%.zip" Build - 7z a -tzip -mx9 "%SOLUTION_NAME%.%APPVEYOR_BUILD_VERSION%.Coverage.zip" Coverage artifacts: - path: $(SOLUTION_NAME).%APPVEYOR_BUILD_VERSION%.zip name: ZipFile + - path: $(SOLUTION_NAME).%APPVEYOR_BUILD_VERSION%.nupkg - name: Package + name: PackageMain + +- path: $(SOLUTION_NAME).Health.%APPVEYOR_BUILD_VERSION%.nupkg + name: PackageHealth + - path: $(SOLUTION_NAME).%APPVEYOR_BUILD_VERSION%.Coverage.zip name: Coverage @@ -87,7 +98,14 @@ deploy: name: NuGet on: branch: master - artifact: Package + artifact: PackageMain + +- provider: Environment + name: NuGet + on: + branch: master + artifact: PackageHealth + - provider: GitHub on: branch: master