diff --git a/src/Meplato.Store2.Tests/Products/ScrollTests.cs b/src/Meplato.Store2.Tests/Products/ScrollTests.cs index 21090ef..8a3922f 100644 --- a/src/Meplato.Store2.Tests/Products/ScrollTests.cs +++ b/src/Meplato.Store2.Tests/Products/ScrollTests.cs @@ -86,5 +86,37 @@ public async Task ScrollUpdate() Assert.NotNull(product.Updated); } } + + [Test] + public async Task ScrollDifferentialUpdate() + { + var service = GetProductsService(); + Assert.NotNull(service); + + MockFromFile("products.scroll.differential.success"); + var response = await service.Scroll().Pin("AD8CCDD5F9").Area("work").Version(3).Mode("diff").Do(); + Assert.NotNull(response); + Assert.AreEqual("store#products", response.Kind); + Assert.IsNotNull(response.PageToken); + Assert.IsNotEmpty(response.PageToken); + Assert.IsTrue(response.TotalItems > 0); + if (response.Items != null) + foreach (var product in response.Items) + { + Assert.NotNull(product); + Assert.IsNotNull(product.Id); + Assert.IsNotEmpty(product.Id); + Assert.IsNotNull(product.Kind); + Assert.IsNotEmpty(product.Kind); + Assert.IsNotNull(product.SelfLink); + Assert.IsNotEmpty(product.SelfLink); + Assert.IsNotNull(product.Spn); + Assert.IsNotEmpty(product.Spn); + Assert.IsNotNull(product.Mode); + Assert.IsNotEmpty(product.Mode); + Assert.NotNull(product.Created); + Assert.NotNull(product.Updated); + } + } } } \ No newline at end of file diff --git a/src/Meplato.Store2.Tests/TestData/products.scroll.differential.success b/src/Meplato.Store2.Tests/TestData/products.scroll.differential.success new file mode 100644 index 0000000..da59a2d --- /dev/null +++ b/src/Meplato.Store2.Tests/TestData/products.scroll.differential.success @@ -0,0 +1,311 @@ +HTTP/1.1 200 OK +Cache-Control: private, no-cache +Content-Type: application/json; charset=utf-8 +Last-Modified: Tue, 31 Mar 2015 14:54:37 GMT +P3p: CP="This is not a P3P policy!" +Vary: Cookie +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +X-Ua-Compatible: IE=edge +X-Xss-Protection: 1; mode=block +Date: Tue, 31 Mar 2015 14:54:37 GMT + +{ + "kind": "store#products", + "selfLink": "https://store2.meplato.com/api/v2/catalogs/AD8CCDD5F9/work/products/scroll?pretty=1\u0026pageToken=c2NhbjsyOzc1OTpFUDU3a3FNelNPdWlzR1dnZFNsTFJBOzc2MDpFUDU3a3FNelNPdWlzR1dnZFNsTFJBOzE7dG90YWxfaGl0czo5ODYyMTs=", + "nextLink": "https://store2.meplato.com/api/v2/catalogs/AD8CCDD5F9/work/products/scroll?pageToken=c2NhbjsyOzc1OTpFUDU3a3FNelNPdWlzR1dnZFNsTFJBOzc2MDpFUDU3a3FNelNPdWlzR1dnZFNsTFJBOzE7dG90YWxfaGl0czo5ODYyMTs%3D\u0026pretty=1", + "pageToken": "c2NhbjsyOzc1OTpFUDU3a3FNelNPdWlzR1dnZFNsTFJBOzc2MDpFUDU3a3FNelNPdWlzR1dnZFNsTFJBOzE7dG90YWxfaGl0czo5ODYyMTs=", + "totalItems": 3, + "items": [ + { + "kind": "store#product", + "selfLink": "https://store2.meplato.com/api/v2/catalogs/AD8CCDD5F9/work/products/50763599?pretty=1", + "id": "50763599@12", + "merchantId": 8, + "projectId": 1, + "catalogId": 12, + "spn": "50763599", + "name": "Heller BOHRER SORT. IN KASETTE 9TLG. 273824", + "description": "Bohrerkassette\n\n 9-teilig, bestehend aus:\nBeton-/Steinbohrer Power 3000\n4/5/6/8 mm\nHSS-G-Super-Stahlbohrer 900\n3/4/5/6/8 mm", + "keywords": null, + "categories": [], + "eclasses": [ + { + "version": "5.1", + "code": "21010100" + } + ], + "unspscs": [], + "scalePrices": [], + "currency": "EUR", + "priceQty": 1, + "ou": "PK", + "cuPerOu": 1, + "cu": "PCE", + "leadtime": 5, + "quantityMin": 1, + "quantityMax": null, + "quantityInterval": 1, + "taxCode": "0.190000", + "conditions": null, + "gtin": "4010159273824 ", + "bpn": "", + "mpn": "4010159273824", + "manufacturer": "ITW Heller GmbH", + "manufactcode": "", + "image": "50763599.jpg", + "thumbnail": "", + "datasheet": "", + "safetysheet": "", + "hazmats": [ + { + "kind": "Gefahrgut", + "text": "NONE" + } + ], + "matgroup": "", + "erpGroupSupplier": "", + "extSchemaType": "", + "extCategoryId": "", + "extCategory": "", + "custField1": "", + "custField2": "", + "custField3": "", + "custField4": "", + "custField5": "", + "references": [ + { + "kind": "others", + "spn": "505533", + "qty": 1 + }, + { + "kind": "others", + "spn": "518929", + "qty": 1 + }, + { + "kind": "others", + "spn": "518930", + "qty": 1 + }, + { + "kind": "others", + "spn": "518931", + "qty": 1 + }, + { + "kind": "others", + "spn": "50539736", + "qty": 1 + }, + { + "kind": "others", + "spn": "50539771", + "qty": 1 + }, + { + "kind": "others", + "spn": "50581235", + "qty": 1 + }, + { + "kind": "others", + "spn": "50765466", + "qty": 1 + } + ], + "features": [], + "availability": { + "qty": 0 + }, + "messages": [], + "tags": null, + "imageURL": "https://store2.meplato.com/abc-elektronik/media?file=50763599.jpg\u0026h=230\u0026w=330", + "thumbnailURL": "https://store2.meplato.com/abc-elektronik/media?file=50763599.jpg\u0026h=90\u0026w=90", + "price": 10.92, + "extProductId": "50763599@12", + "mode": "Created", + "created": "2015-03-20T13:11:02Z", + "updated": "2015-03-20T13:11:02Z" + }, + { + "kind": "store#product", + "selfLink": "https://store2.meplato.com/api/v2/catalogs/AD8CCDD5F9/work/products/50763601?pretty=1", + "id": "50763601@12", + "merchantId": 8, + "projectId": 1, + "catalogId": 12, + "spn": "50763601", + "name": "Heller QUICK-BIT KASS. 5TLG. HOLZ 265690", + "description": "QuickBit®-Satz Holz\n\n 5-teilig\n\n Inhalt: 3, 4, 5, 6, 8 mm", + "keywords": null, + "categories": [], + "eclasses": [ + { + "version": "5.1", + "code": "21040190" + } + ], + "unspscs": [], + "scalePrices": [], + "currency": "EUR", + "priceQty": 1, + "ou": "PK", + "cuPerOu": 1, + "cu": "PCE", + "leadtime": 5, + "quantityMin": 1, + "quantityMax": null, + "quantityInterval": 1, + "taxCode": "0.190000", + "conditions": null, + "gtin": "4010159265690 ", + "bpn": "", + "mpn": "4010159265690", + "manufacturer": "ITW Heller GmbH", + "manufactcode": "", + "image": "50763601.jpg", + "thumbnail": "", + "datasheet": "", + "safetysheet": "", + "hazmats": [ + { + "kind": "Gefahrgut", + "text": "NONE" + } + ], + "matgroup": "", + "erpGroupSupplier": "", + "extSchemaType": "", + "extCategoryId": "", + "extCategory": "", + "custField1": "", + "custField2": "", + "custField3": "", + "custField4": "", + "custField5": "", + "references": [ + { + "kind": "others", + "spn": "505533", + "qty": 1 + }, + { + "kind": "others", + "spn": "518929", + "qty": 1 + }, + { + "kind": "others", + "spn": "518930", + "qty": 1 + }, + { + "kind": "others", + "spn": "518931", + "qty": 1 + }, + { + "kind": "others", + "spn": "50539736", + "qty": 1 + }, + { + "kind": "others", + "spn": "50539771", + "qty": 1 + }, + { + "kind": "others", + "spn": "50581235", + "qty": 1 + }, + { + "kind": "others", + "spn": "50765466", + "qty": 1 + } + ], + "features": [], + "availability": { + "qty": 0 + }, + "messages": [], + "tags": null, + "imageURL": "https://store2.meplato.com/abc-elektronik/media?file=50763601.jpg\u0026h=230\u0026w=330", + "thumbnailURL": "https://store2.meplato.com/abc-elektronik/media?file=50763601.jpg\u0026h=90\u0026w=90", + "price": 11.68, + "extProductId": "50763601@12", + "mode": "Updated", + "created": "2015-03-20T13:11:02Z", + "updated": "2015-03-20T15:51:32Z" + }, + { + "kind": "store#product", + "selfLink": "https://store2.meplato.com/api/v2/catalogs/AD8CCDD5F9/work/products/50763603?pretty=1", + "id": "50763603@12", + "merchantId": 0, + "projectId": 0, + "catalogId": 0, + "spn": "50763603", + "name": "", + "description": "", + "keywords": null, + "categories": null, + "eclasses": null, + "unspscs": null, + "currency": "", + "country": "", + "priceQty": 0, + "ou": "", + "cuPerOu": 0, + "cu": "", + "leadtime": null, + "quantityMin": null, + "quantityMax": null, + "quantityInterval": null, + "taxCode": "", + "taxRate": 0, + "conditions": null, + "gtin": "", + "asin": "", + "bpn": "", + "mpn": "", + "manufacturer": "", + "manufactcode": "", + "image": "", + "thumbnail": "", + "datasheet": "", + "safetysheet": "", + "blobs": null, + "hazmats": null, + "intrastat": null, + "matgroup": "", + "erpGroupSupplier": "", + "extSchemaType": "", + "extCategoryId": "", + "extCategory": "", + "extProductId": "", + "multiSupplierId": "", + "multiSupplierName": "", + "custField1": "", + "custField2": "", + "custField3": "", + "custField4": "", + "custField5": "", + "custFields": null, + "references": null, + "features": null, + "availability": null, + "messages": null, + "tags": null, + "excluded": false, + "catalogManaged": false, + "price": 0, + "mode": "Deleted", + "created": "0001-01-01T00:00:00Z", + "updated": "0001-01-01T00:00:00Z" + } + ] +} diff --git a/src/Meplato.Store2/Catalogs/Service.cs b/src/Meplato.Store2/Catalogs/Service.cs index 35a2699..72b77f3 100644 --- a/src/Meplato.Store2/Catalogs/Service.cs +++ b/src/Meplato.Store2/Catalogs/Service.cs @@ -17,7 +17,7 @@ // The file implements the Meplato Store API. // // Author: Meplato API Team -// Version: 2.1.7 +// Version: 2.1.8 // License: Copyright (c) 2015-2020 Meplato GmbH. All rights reserved. // See Terms of Service // See External documentation @@ -40,7 +40,7 @@ public class Service { #region Service public const string Title = "Meplato Store API"; - public const string Version = "2.1.7"; + public const string Version = "2.1.8"; public const string UserAgent = "meplato-csharp-client/2.0"; public const string DefaultBaseURL = "https://store.meplato.com/api/v2"; diff --git a/src/Meplato.Store2/Jobs/Service.cs b/src/Meplato.Store2/Jobs/Service.cs index bed9933..6ff3529 100644 --- a/src/Meplato.Store2/Jobs/Service.cs +++ b/src/Meplato.Store2/Jobs/Service.cs @@ -17,7 +17,7 @@ // The file implements the Meplato Store API. // // Author: Meplato API Team -// Version: 2.1.7 +// Version: 2.1.8 // License: Copyright (c) 2015-2020 Meplato GmbH. All rights reserved. // See Terms of Service // See External documentation @@ -40,7 +40,7 @@ public class Service { #region Service public const string Title = "Meplato Store API"; - public const string Version = "2.1.7"; + public const string Version = "2.1.8"; public const string UserAgent = "meplato-csharp-client/2.0"; public const string DefaultBaseURL = "https://store.meplato.com/api/v2"; diff --git a/src/Meplato.Store2/Products/Service.cs b/src/Meplato.Store2/Products/Service.cs index 0ee17cf..dcdb005 100644 --- a/src/Meplato.Store2/Products/Service.cs +++ b/src/Meplato.Store2/Products/Service.cs @@ -17,8 +17,8 @@ // The file implements the Meplato Store API. // // Author: Meplato API Team -// Version: 2.1.7 -// License: Copyright (c) 2015-2018 Meplato GmbH. All rights reserved. +// Version: 2.1.8 +// License: Copyright (c) 2015-2020 Meplato GmbH. All rights reserved. // See Terms of Service // See External documentation @@ -41,7 +41,7 @@ public class Service { #region Service public const string Title = "Meplato Store API"; - public const string Version = "2.1.7"; + public const string Version = "2.1.8"; public const string UserAgent = "meplato-csharp-client/2.0"; public const string DefaultBaseURL = "https://store.meplato.com/api/v2"; @@ -391,6 +391,14 @@ public class CreateProduct [JsonProperty("cuPerOu")] public double? CuPerOu { get; set; } + /// + /// Currency is the ISO currency code for the prices, e.g. EUR or + /// GBP. If you pass an empty currency code, it will be initialized + /// with the catalog's currency. + /// + [JsonProperty("currency")] + public string Currency { get; set; } + /// /// CustField1 is the CUST_FIELD1 of the SAP OCI specification. It /// has a maximum length of 10 characters. @@ -1374,7 +1382,8 @@ public class Product /// /// Currency is the ISO currency code for the prices, e.g. EUR or - /// GBP. + /// GBP. If you pass an empty currency code, it will be initialized + /// with the catalog's currency. /// [JsonProperty("currency")] public string Currency { get; set; } @@ -1782,6 +1791,13 @@ public class Product [JsonProperty("merchantId")] public long MerchantId { get; set; } + /// + /// Mode is only used for differential downloads and is the type of + /// change of a product (CREATED, UPDATED, DELETED). + /// + [JsonProperty("mode")] + public string Mode { get; set; } + /// /// MPN is the manufacturer part number. /// @@ -2173,6 +2189,14 @@ public class ReplaceProduct [JsonProperty("cuPerOu")] public double? CuPerOu { get; set; } + /// + /// Currency is the ISO currency code for the prices, e.g. EUR or + /// GBP. If you pass an empty currency code, it will be initialized + /// with the catalog's currency. + /// + [JsonProperty("currency")] + public string Currency { get; set; } + /// /// CustField1 is the CUST_FIELD1 of the SAP OCI specification. It /// has a maximum length of 10 characters. @@ -2999,6 +3023,7 @@ public class Unspsc #endregion // Unspsc } + /// /// UpdateProduct holds the properties of a product that need to be /// updated. @@ -5844,7 +5869,7 @@ public virtual void GetObjectData(SerializationInfo info, StreamingContext conte } #endregion // UpdateProduct } - + /// /// UpdateProductResponse is the outcome of a successful request to /// update a product. @@ -5995,6 +6020,14 @@ public class UpsertProduct [JsonProperty("cuPerOu")] public double? CuPerOu { get; set; } + /// + /// Currency is the ISO currency code for the prices, e.g. EUR or + /// GBP. If you pass an empty currency code, it will be initialized + /// with the catalog's currency. + /// + [JsonProperty("currency")] + public string Currency { get; set; } + /// /// CustField1 is the CUST_FIELD1 of the SAP OCI specification. It /// has a maximum length of 10 characters. @@ -7047,6 +7080,20 @@ public ScrollService Area(string area) return this; } + /// + /// Mode can be used in combination with version to specify if the + /// result should include all products for the specific version of + /// the catalog (full), or just the products that changed from the + /// previous version (diff). If the mode is "diff", the type of + /// change to the product can be found in the attribute "mode" and + /// has the following values: "Created", "Updated", "Deleted". + /// + public ScrollService Mode(string mode) + { + _opt["mode"] = mode; + return this; + } + /// /// PageToken must be passed in the 2nd and all consective requests /// to get the next page of results. You do not need to pass the @@ -7073,6 +7120,15 @@ public ScrollService Pin(string pin) return this; } + /// + /// Version of the catalog to be retrieved + /// + public ScrollService Version(long version) + { + _opt["version"] = version; + return this; + } + /// /// Execute the operation. /// @@ -7082,6 +7138,11 @@ public async Task Do() var parameters = new Dictionary(); // UriTemplates package wants path parameters as strings parameters["area"] = string.Format("{0}", _area); + if (_opt.ContainsKey("mode")) + { + // UriTemplates package wants query parameters as strings + parameters["mode"] = string.Format("{0}", _opt["mode"]); + } if (_opt.ContainsKey("pageToken")) { // UriTemplates package wants query parameters as strings @@ -7089,6 +7150,11 @@ public async Task Do() } // UriTemplates package wants path parameters as strings parameters["pin"] = string.Format("{0}", _pin); + if (_opt.ContainsKey("version")) + { + // UriTemplates package wants query parameters as strings + parameters["version"] = string.Format("{0}", _opt["version"]); + } // Make a copy of the header parameters and set UA var headers = new Dictionary(); @@ -7098,7 +7164,7 @@ public async Task Do() headers["Authorization"] = authorization; } - var uriTemplate = _service.BaseURL + "/catalogs/{pin}/{area}/products/scroll{?pageToken}"; + var uriTemplate = _service.BaseURL + "/catalogs/{pin}/{area}/products/scroll{?pageToken,mode,version}"; var response = await _service.Client.Execute( HttpMethod.Get, uriTemplate, diff --git a/src/Meplato.Store2/Service.cs b/src/Meplato.Store2/Service.cs index 49237ad..ac2d0ae 100644 --- a/src/Meplato.Store2/Service.cs +++ b/src/Meplato.Store2/Service.cs @@ -17,7 +17,7 @@ // The file implements the Meplato Store API. // // Author: Meplato API Team -// Version: 2.1.7 +// Version: 2.1.8 // License: Copyright (c) 2015-2020 Meplato GmbH. All rights reserved. // See Terms of Service // See External documentation @@ -39,7 +39,7 @@ public class Service { #region Service public const string Title = "Meplato Store API"; - public const string Version = "2.1.7"; + public const string Version = "2.1.8"; public const string UserAgent = "meplato-csharp-client/2.0"; public const string DefaultBaseURL = "https://store.meplato.com/api/v2";