aboutyou-sdk 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. checksums.yaml +15 -0
  2. data/lib/aboutyou-sdk.rb +545 -0
  3. data/lib/aboutyou-sdk/Client.rb +125 -0
  4. data/lib/aboutyou-sdk/Constants.rb +48 -0
  5. data/lib/aboutyou-sdk/Criteria/ProductFields.rb +54 -0
  6. data/lib/aboutyou-sdk/Criteria/ProductSearchCriteria.rb +436 -0
  7. data/lib/aboutyou-sdk/Factory/DefaultModelFactory.rb +454 -0
  8. data/lib/aboutyou-sdk/Model/AbstractModel.rb +26 -0
  9. data/lib/aboutyou-sdk/Model/App.rb +35 -0
  10. data/lib/aboutyou-sdk/Model/Autocomplete.rb +92 -0
  11. data/lib/aboutyou-sdk/Model/Basket.rb +262 -0
  12. data/lib/aboutyou-sdk/Model/Basket/AbstractBasketItem.rb +76 -0
  13. data/lib/aboutyou-sdk/Model/Basket/BasketItem.rb +100 -0
  14. data/lib/aboutyou-sdk/Model/Basket/BasketSet.rb +192 -0
  15. data/lib/aboutyou-sdk/Model/Basket/BasketSetItem.rb +46 -0
  16. data/lib/aboutyou-sdk/Model/Basket/BasketVariantItem.rb +137 -0
  17. data/lib/aboutyou-sdk/Model/CategoriesResult.rb +15 -0
  18. data/lib/aboutyou-sdk/Model/Category.rb +126 -0
  19. data/lib/aboutyou-sdk/Model/CategoryManager/DefaultCategoryManager.rb +172 -0
  20. data/lib/aboutyou-sdk/Model/CategoryTree.rb +35 -0
  21. data/lib/aboutyou-sdk/Model/Facet.rb +105 -0
  22. data/lib/aboutyou-sdk/Model/FacetGroup.rb +110 -0
  23. data/lib/aboutyou-sdk/Model/FacetGroupSet.rb +247 -0
  24. data/lib/aboutyou-sdk/Model/FacetManager/DefaultFacetManager.rb +79 -0
  25. data/lib/aboutyou-sdk/Model/Image.rb +134 -0
  26. data/lib/aboutyou-sdk/Model/ImageSize.rb +21 -0
  27. data/lib/aboutyou-sdk/Model/InitiateOrder.rb +50 -0
  28. data/lib/aboutyou-sdk/Model/Order.rb +17 -0
  29. data/lib/aboutyou-sdk/Model/Product.rb +543 -0
  30. data/lib/aboutyou-sdk/Model/ProductSearchResult.rb +125 -0
  31. data/lib/aboutyou-sdk/Model/ProductSearchResult/FacetCount.rb +26 -0
  32. data/lib/aboutyou-sdk/Model/ProductSearchResult/FacetCounts.rb +38 -0
  33. data/lib/aboutyou-sdk/Model/ProductSearchResult/PriceRange.rb +49 -0
  34. data/lib/aboutyou-sdk/Model/ProductSearchResult/SaleCounts.rb +58 -0
  35. data/lib/aboutyou-sdk/Model/ProductSearchResult/TermsCount.rb +27 -0
  36. data/lib/aboutyou-sdk/Model/ProductsEansResult.rb +43 -0
  37. data/lib/aboutyou-sdk/Model/ProductsResult.rb +52 -0
  38. data/lib/aboutyou-sdk/Model/ResultError.rb +24 -0
  39. data/lib/aboutyou-sdk/Model/Variant.rb +255 -0
  40. data/lib/aboutyou-sdk/Model/VariantsResult.rb +102 -0
  41. data/lib/aboutyou-sdk/Query.rb +261 -0
  42. data/lib/aboutyou-sdk/QueryBuilder.rb +440 -0
  43. data/tests/Sinatra-test/Main.rb +5 -0
  44. data/tests/testApiClient.rb +35 -0
  45. data/tests/testAutocomplete.rb +40 -0
  46. data/tests/testCatFilter.rb +35 -0
  47. data/tests/testCatTree.rb +37 -0
  48. data/tests/testFacets.rb +36 -0
  49. data/tests/testProdCatLongestPath.rb +34 -0
  50. data/tests/testProductSearchResult.rb +35 -0
  51. data/tests/testProductsByIds.rb +34 -0
  52. data/tests/testVariantsByIds.rb +34 -0
  53. metadata +122 -0
@@ -0,0 +1,21 @@
1
+ module AboutYou
2
+ module SDK
3
+ module Model
4
+ class ImageSize
5
+ # @var integer */
6
+ @width;
7
+ attr_accessor :width
8
+
9
+ # @var integer */
10
+ @height;
11
+ attr_accessor :height
12
+
13
+ def initialize(width, height)
14
+
15
+ self.width = width;
16
+ self.height = height;
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,50 @@
1
+ module AboutYou
2
+ module SDK
3
+ module Model
4
+ class InitiateOrder
5
+
6
+ attr_accessor :url
7
+ attr_accessor :userToken
8
+ attr_accessor :appToken
9
+ attr_accessor :errorCode
10
+ attr_accessor :errorMessage
11
+
12
+ ###
13
+ # @param string $url
14
+ # @param string $userToken
15
+ # @param string $appToken
16
+ ###
17
+ def initialize(url, userToken, appToken)
18
+
19
+ self.url = url;
20
+ self.userToken = userToken;
21
+ self.appToken = appToken;
22
+ end
23
+
24
+ ###
25
+ # @param \stdClass $json
26
+ #
27
+ # @return static
28
+ ###
29
+ def self.createFromJson(jsonObject)
30
+
31
+ order = self.new(
32
+ jsonObject["url"],
33
+ jsonObject["user_token"],
34
+ jsonObject["app_token"]
35
+ );
36
+
37
+ order.parseErrorResult(jsonObject);
38
+
39
+ return order;
40
+ end
41
+
42
+ def parseErrorResult(jsonObject)
43
+
44
+ self.errorCode = (jsonObject.key?("error_code")) ? jsonObject["error_code"] : 0
45
+ self.errorCode = (jsonObject.key?("error_message")) ? jsonObject["error_message"] : nil
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,17 @@
1
+ module AboutYou
2
+ module SDK
3
+ module Model
4
+ class Order
5
+
6
+ attr_accessor :id
7
+ attr_accessor :basket;
8
+
9
+ def initialize(id, basket)
10
+
11
+ self.id = id;
12
+ self.basket = basket;
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,543 @@
1
+ module AboutYou
2
+ module SDK
3
+ module Model
4
+ class Product
5
+ include AbstractModel
6
+
7
+ attr_accessor :id
8
+ attr_accessor :factory
9
+ attr_accessor :name
10
+ attr_accessor :isSale
11
+ attr_accessor :isActive
12
+ attr_accessor :descriptionShort
13
+ attr_accessor :descriptionLong
14
+ attr_accessor :minPrice
15
+ attr_accessor :maxPrice
16
+ attr_accessor :maxSavingsPrice
17
+ attr_accessor :maxSavings
18
+ attr_accessor :maxSavingsPercentage
19
+ attr_accessor :brandId
20
+ attr_accessor :merchantId
21
+ attr_accessor :categoryIdPaths
22
+ attr_accessor :facetIds
23
+ attr_accessor :defaultImage
24
+ attr_accessor :defaultVariant
25
+ attr_accessor :selectedVariant
26
+ attr_accessor :variants
27
+ attr_accessor :inactiveVariants
28
+ attr_accessor :styles
29
+ attr_accessor :facetGroups
30
+ attr_accessor :rootCategories
31
+ attr_accessor :activeRootCategories
32
+ attr_accessor :leafCategories
33
+ attr_accessor :activeLeafCategories
34
+
35
+ ###
36
+ # @param $jsonObject
37
+ # @param ModelFactoryInterface $factory
38
+ #
39
+ # @return static
40
+ #
41
+ # @throws \Collins\ShopApi\Exception\MalformedJsonException
42
+ ###
43
+ def self.createFromJson(jsonObject, factory, appId)
44
+
45
+ product = self.new
46
+ # these are required fields
47
+ if (!jsonObject["id"] || !jsonObject["name"])
48
+ raise 'MalformedJsonException'
49
+ end
50
+ product.factory = factory
51
+
52
+ product.id = jsonObject["id"]
53
+ product.name = jsonObject["name"]
54
+
55
+ product.isSale = jsonObject["sale"] ? jsonObject["sale"] : false;
56
+ product.descriptionShort = jsonObject["description_short"] ? jsonObject["description_short"] : '';
57
+ product.descriptionLong = jsonObject["description_long"] ? jsonObject["description_long"] : '';
58
+ product.isActive = jsonObject["active"] ? jsonObject["active"] : true;
59
+ product.brandId = jsonObject["brand_id"] ? jsonObject["brand_id"] : nil;
60
+ product.merchantId = jsonObject["merchant_id"] ? jsonObject["merchant_id"] : nil;
61
+
62
+ product.minPrice = jsonObject["min_price"] ? jsonObject["min_price"] : nil;
63
+ product.maxPrice = jsonObject["max_price"] ? jsonObject["max_price"] : nil;
64
+ product.maxSavingsPrice = jsonObject["max_savings"] ? jsonObject["max_savings"] : nil;
65
+ product.maxSavingsPercentage = jsonObject["max_savings_percentage"] ? jsonObject["max_savings_percentage"] : nil;
66
+
67
+ product.defaultImage = jsonObject["default_image"] ? factory.createImage(jsonObject["default_image"]) : nil
68
+ product.defaultVariant = jsonObject["default_variant"] ? factory.createVariant(jsonObject["default_variant"], product) : nil;
69
+ product.variants = parseVariants(jsonObject, factory, product);
70
+ product.inactiveVariants = parseVariants(jsonObject, factory, product, 'inactive_variants');
71
+ product.styles = parseStyles(jsonObject, factory);
72
+
73
+ key = 'categories.' + String(appId)
74
+ product.categoryIdPaths = jsonObject[key] ? jsonObject[key] : Array(nil);
75
+
76
+ product.facetIds = product.parseFacetIds(jsonObject);
77
+
78
+ return product;
79
+ end
80
+
81
+ def self.parseVariants(jsonObject, factory, product, attributeName = 'variants')
82
+
83
+ variants = Array(nil);
84
+ if (jsonObject[attributeName])
85
+ jsonObject[attributeName].each do |jsonVariant|
86
+ variants.push(factory.createVariant(jsonVariant, product))
87
+ end
88
+ end
89
+
90
+ return variants;
91
+ end
92
+
93
+ def self.parseStyles(jsonObject, factory)
94
+
95
+ styles = Array(nil);
96
+ if (jsonObject["styles"])
97
+ jsonObject["styles"].each do |style|
98
+ styles.push(factory.createProduct(style))
99
+ end
100
+ end
101
+
102
+ return styles;
103
+ end
104
+
105
+ def parseCategoryIdPaths(jsonObject)
106
+
107
+ paths = Array(nil);
108
+
109
+ jsonObject.each do |name, categoryPaths|
110
+ if (name.index('categories') == 0)
111
+ paths = categoryPaths;
112
+ break;
113
+ end
114
+ end
115
+ return paths;
116
+ end
117
+
118
+ def parseFacetIds(jsonObject)
119
+
120
+ ids = self.parseFacetIdsInAttributesMerged(jsonObject);
121
+ if (ids === nil)
122
+ ids = self.parseFacetIdsInVariants(jsonObject);
123
+ end
124
+ if (ids === nil)
125
+ ids = self.parseFacetIdsInBrand(jsonObject);
126
+ end
127
+
128
+ return (ids != nil) ? ids : Array(nil);
129
+ end
130
+
131
+ def parseFacetIdsInAttributesMerged(jsonObject)
132
+
133
+ if (!jsonObject["attributes_merged"])
134
+ return nil
135
+ end
136
+
137
+ parseAttributesJson(jsonObject["attributes_merged"]);
138
+ end
139
+
140
+ def parseAttributesJson(attributesJsonObject)
141
+
142
+ ids = Hash.new
143
+
144
+ attributesJsonObject.each do |group, facetIds|
145
+ gid = group[11..group.length] # prefix "attributes"
146
+
147
+ # TODO: Remove Workaround for Ticket ???
148
+ facetIds = Array(facetIds)
149
+ ids[gid] = facetIds;
150
+ end
151
+
152
+ return ids;
153
+ end
154
+
155
+ def parseFacetIdsInVariants(jsonObject)
156
+
157
+ if (jsonObject["variants"])
158
+ ids = Array(nil);
159
+ jsonObject["variants"].each do |variant|
160
+ ids.push(parseAttributesJson(variant["attributes"]));
161
+ end
162
+ ids = AboutYou::SDK::Model::FacetGroupSet.mergeFacetIds(ids);
163
+
164
+ return ids;
165
+ elsif (jsonObject["default_variant"])
166
+ ids = parseAttributesJson(jsonObject["default_variant"]["attributes"]);
167
+
168
+ return ids;
169
+ end
170
+
171
+ return nil;
172
+ end
173
+
174
+ def parseFacetIdsInBrand(jsonObject)
175
+
176
+ if (!jsonObject["brand_id"])
177
+ return nil;
178
+ end
179
+
180
+ Hash['0' => jsonObject["brand_id"]];
181
+ end
182
+
183
+
184
+ def generateFacetGroupSet()
185
+
186
+ if (self.facetIds.empty?)
187
+ raise 'ShopApi\Exception\RuntimeException! To use this method, you must add the field ProductFields::ATTRIBUTES_MERGED to the "product search" or "products by ids"'
188
+ end
189
+
190
+ self.facetGroups = AboutYou::SDK::Model::FacetGroupSet.new(self.facetIds);
191
+ end
192
+
193
+ ###
194
+ # @return FacetGroupSet|null
195
+ ###
196
+ def facetGroupSet()
197
+
198
+ if (!self.facetGroups)
199
+ generateFacetGroupSet
200
+ end
201
+
202
+ self.facetGroups;
203
+ end
204
+
205
+ ###
206
+ # Returns the first active category and, if non active, then it return the first category
207
+ #
208
+ # @param bool $activeOnly return only categories that are active
209
+ #
210
+ # @return Category|null
211
+ ###
212
+ def category(active = true)
213
+
214
+ if (self.categoryIdPaths.empty?)
215
+ return;
216
+ end
217
+
218
+ self.leafCategories(active)[0]
219
+ end
220
+
221
+ ###
222
+ # @return Category|null
223
+ ###
224
+ def categoryWithLongestActivePath()
225
+
226
+ if (self.categoryIdPaths.empty?)
227
+ return nil;
228
+ end
229
+
230
+ sortedArray = self.categoryIdPaths
231
+ sortedArray.sort!{|x,y| y.count <=> x.count}
232
+ sortedArray.each do |path|
233
+ if(self.factory.categoryManager.category(path[-1]).isPathActive)
234
+ return self.factory.categoryManager.category(path[-1])
235
+ end
236
+ end
237
+ return nil;
238
+ end
239
+
240
+ ###
241
+ # Returns array of categories without subcategories. E.g. of the product is in the category
242
+ # Damen > Schuhe > Absatzschuhe and Damen > Schuhe > Stiefelleten then
243
+ # [Absatzschuhe, Stiefelleten] will be returned
244
+ #
245
+ # @param bool $activeOnly return only categories that are active
246
+ #
247
+ # @return Category[]
248
+ ###
249
+ def leafCategories(activeOnly = true)
250
+
251
+ self.fetchAndParseCategories()
252
+
253
+ activeOnly ? self.activeLeafCategories : self.leafCategories
254
+ end
255
+
256
+ def categories(activeOnly = true)
257
+
258
+ return self.rootCategories(activeOnly);
259
+ end
260
+
261
+ ###
262
+ # @param bool $activeOnly return only active categories
263
+ #
264
+ # @return Category[]
265
+ ###
266
+ def rootCategories(activeOnly = true)
267
+
268
+ fetchAndParseCategories();
269
+
270
+ activeOnly ? @activeRootCategories : @rootCategories
271
+ end
272
+
273
+ def fetchAndParseCategories()
274
+
275
+ if (@rootCategories != nil)
276
+ return;
277
+ end
278
+
279
+ self.rootCategories = Array(nil);
280
+ self.activeRootCategories = Array(nil);
281
+ self.leafCategories = Array(nil);
282
+ self.activeLeafCategories = Array(nil);
283
+
284
+ if (self.categoryIdPaths.empty?)
285
+ return;
286
+ end
287
+
288
+ # put all category ids in an array to fetch by ids
289
+ categoryIds = self.categoryIdPaths.uniq
290
+
291
+ # fetch all necessary categories from API
292
+ flattenCategories = self.shopApi().fetchCategoriesByIds(categoryIds).categories;
293
+
294
+ flattenCategories.each do |category|
295
+ parentId = category.parentId
296
+ if (parentId != nil && flattenCategories[parentId])
297
+ category.setParent(flattenCategories[parentId], true);
298
+ end
299
+ end
300
+
301
+ self.categoryIdPaths.each do |categoryIdPath|
302
+ rootId = categoryIdPath[0];
303
+ rootCategory = flattenCategories[rootId];
304
+ self.rootCategories[rootId] = rootCategory;
305
+ if (rootCategory.isActive)
306
+ self.activeRootCategories[rootId] = rootCategory;
307
+ end
308
+
309
+ leafId = categoryIdPath[-1];
310
+ leafCategory = flattenCategories[leafId];
311
+ self.leafCategories[leafId] = leafCategory;
312
+ if (leafCategory.isActive)
313
+ self.activeLeafCategories[leafId] = leafCategory;
314
+ end
315
+ end
316
+ end
317
+
318
+
319
+ ###
320
+ # Get facets of given group id.
321
+ #
322
+ # @param integer $groupId The group id.
323
+ #
324
+ # @return \Collins\ShopApi\Model\Facet[]
325
+ ###
326
+ def groupFacets(groupId)
327
+
328
+ group = self.facetGroupSet.group(groupId);
329
+ if (group)
330
+ return group.facets;
331
+ end
332
+ return Array(nil);
333
+ end
334
+
335
+ ###
336
+ # Returns all unique FacetGroups from all Variants
337
+ #
338
+ # @param integer $groupId
339
+ #
340
+ # @return FacetGroup[]
341
+ ###
342
+ def facetGroups(groupId)
343
+
344
+ allGroups = Array(nil);
345
+ self.variants.each do |variant|
346
+ groups = variant.facetGroupSet.groups;
347
+ groups.each do |group|
348
+ if (group.id == groupId)
349
+ allGroups[group.uniqueKey] = group;
350
+ end
351
+ end
352
+ end
353
+
354
+ return allGroups;
355
+ end
356
+
357
+ ###
358
+ # Returns all FacetGroups, which matches the current facet group set
359
+ # for example:
360
+ # [['color'] => 'rot'] =>
361
+ #
362
+ # @param FacetGroupSet $selectedFacetGroupSet
363
+ #
364
+ # @return FacetGroup[][]
365
+ #
366
+ # @throws \Collins\ShopApi\Exception\RuntimeException
367
+ ###
368
+ def selectableFacetGroups(selectedFacetGroupSet)
369
+
370
+ # @var FacetGroup[] $allGroups */
371
+ allGroups = Array(nil);
372
+ selectedGroupIds = selectedFacetGroupSet.groupIds();
373
+
374
+ self.variants.each do |variant|
375
+ facetGroupSet = variant.facetGroupSet();
376
+ ids = facetGroupSet.groupIds();
377
+
378
+ if (facetGroupSet.contains(selectedFacetGroupSet))
379
+ ids.each do |groupId|
380
+ if (selectedGroupIds.include?(groupId))
381
+ continue;
382
+ end
383
+
384
+ group = facetGroupSet.group(groupId);
385
+ if (group == nil)
386
+ raise 'RuntimeException! group for id ' + String(groupId) + ' not found'
387
+ end
388
+ allGroups[groupId][group.uniqueKey()] = group;
389
+ end
390
+ end
391
+ end
392
+
393
+ selectedGroupIds.each do |groupId|
394
+ ids = selectedFacetGroupSet.ids();
395
+ ids[groupId] = nil
396
+ myFacetGroupSet = FacetGroupSet.new(ids);
397
+ self.variants.each do |variant|
398
+ facetGroupSet = variant.facetGroupSet();
399
+ if (facetGroupSet.contains(myFacetGroupSet))
400
+ group = facetGroupSet.group(groupId);
401
+ allGroups[groupId][group.uniqueKey()] = group;
402
+ end
403
+ end
404
+ end
405
+
406
+ return allGroups;
407
+ end
408
+
409
+ ###
410
+ # Returns all FacetGroups, which matches the current facet group set
411
+ # for example:
412
+ # [['color'] => 'rot'] =>
413
+ #
414
+ # @param FacetGroupSet $selectedFacetGroupSet
415
+ #
416
+ # @return FacetGroup[]
417
+ ###
418
+ def excludedFacetGroups(selectedFacetGroupSet)
419
+
420
+ # @var FacetGroup[] $allGroups */
421
+ allGroups = Array(nil);
422
+ selectedGroupIds = selectedFacetGroupSet.groupIds();
423
+
424
+ self.variants.each do |variant|
425
+ facetGroupSet = variant.facetGroupSet();
426
+ if (!facetGroupSet.contains(selectedFacetGroupSet))
427
+ continue;
428
+ end
429
+
430
+ ids = facetGroupSet.groupIds();
431
+
432
+ ids.each do |groupId|
433
+ if (selectedGroupIds.include?(groupId))
434
+ continue;
435
+ end
436
+
437
+ group = facetGroupSet.group(groupId);
438
+ if (group == nil)
439
+ raise 'RuntimeException! group for id ' + String(groupId) + ' not found'
440
+ end
441
+ facets = group.facets();
442
+ if (facets.empty?)
443
+ continue;
444
+ end
445
+
446
+ if (allGroups[groupId])
447
+ allGroups[groupId] = FacetGroup.new(group.id(), group.name());
448
+ end
449
+ allGroups[groupId].addFacets(facets);
450
+ end
451
+ end
452
+
453
+ return allGroups;
454
+ end
455
+
456
+
457
+ ###
458
+ # @return \Collins\ShopApi\Model\Facet
459
+ ###
460
+ def brand()
461
+
462
+ self.facetGroupSet().facet(AboutYou::SDK::Constants::FACET_BRAND, self.brandId);
463
+ end
464
+
465
+ ###
466
+ # Get variant by id.
467
+ #
468
+ # @param integer $variantId The variant id.
469
+ #
470
+ # @return Variant
471
+ ###
472
+ def variantById(variantId)
473
+
474
+ self.variants.each do |variant|
475
+ if (variant.id==variantId)
476
+ return variant
477
+ end
478
+ end
479
+
480
+ return nil;
481
+ end
482
+
483
+ ###
484
+ # @param string $ean
485
+ #
486
+ # @return Variant[]
487
+ ###
488
+ def variantsByEan(ean)
489
+
490
+ variants = Array(nil);
491
+ self.variants.each do |variant|
492
+ if (variant.ean == ean)
493
+ variants.push(variant);
494
+ end
495
+ end
496
+
497
+ return variants;
498
+ end
499
+
500
+ ###
501
+ # This returns the first variant, which matches exactly the given facet group set
502
+ #
503
+ # @param FacetGroupSet $facetGroupSet
504
+ #
505
+ # @return Variant|null
506
+ ###
507
+ def variantByFacets(facetGroupSet)
508
+
509
+ key = facetGroupSet.uniqueKey();
510
+ self.variants.each do |variant|
511
+ if (variant.facetGroupSet().uniqueKey() == key)
512
+ return variant;
513
+ end
514
+ end
515
+
516
+ return nil;
517
+ end
518
+
519
+
520
+ ###
521
+ # This returns all variants, which matches some of the given facet
522
+ #
523
+ # @param $facetId
524
+ # @param $groupId
525
+ #
526
+ # @return Variant[]
527
+ ###
528
+ def variantsByFacetId(facetId, groupId)
529
+
530
+ variants = Array(nil);
531
+ facet = Facet.new(facetId, '', '', groupId, '');
532
+ self.variants.each do |variant|
533
+ if (variant.facetGroupSet().contains(facet))
534
+ variants.push(variant)
535
+ end
536
+ end
537
+
538
+ return variants;
539
+ end
540
+ end
541
+ end
542
+ end
543
+ end