aboutyou-sdk 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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,255 @@
1
+ module AboutYou
2
+ module SDK
3
+ module Model
4
+
5
+ class Variant
6
+ include AbstractModel
7
+
8
+ attr_accessor :factory
9
+ attr_accessor :product
10
+ attr_accessor :id
11
+ attr_accessor :images
12
+ attr_accessor :selectedImage
13
+ attr_accessor :aboutNumber
14
+ attr_accessor :facetGroups
15
+ attr_accessor :ean
16
+ attr_accessor :isDefault
17
+ attr_accessor :price
18
+ attr_accessor :oldPrice
19
+ attr_accessor :retailPrice
20
+ attr_accessor :additionalInfo
21
+ attr_accessor :quantity
22
+ attr_accessor :facetIds
23
+ attr_accessor :firstActiveDate
24
+ attr_accessor :firstSaleDate
25
+ attr_accessor :createdDate
26
+ attr_accessor :updatedDate
27
+ attr_accessor :color
28
+ attr_accessor :length
29
+ attr_accessor :seasonCode
30
+
31
+ ###
32
+ # @param \stdClass $jsonObject
33
+ # @param ModelFactoryInterface $factory
34
+ # @param Product $product
35
+ #
36
+ # @return static
37
+ ###
38
+ def self.createFromJson(jsonObject, factory, product)
39
+
40
+ jsonObj = jsonObject
41
+ if (!jsonObj["id"])
42
+ raise 'MalformedJsonException'
43
+ end
44
+
45
+ variant = self.new
46
+ variant.factory = factory;
47
+ variant.product = product;
48
+
49
+
50
+ variant.parseImages(jsonObj["images"])
51
+ #free memory
52
+ jsonObj["images"] = nil
53
+
54
+ variant.id = jsonObj["id"]
55
+
56
+ variant.aboutNumber = (jsonObj["about_number"]) ? jsonObj["about_number"] : nil
57
+ variant.ean = (jsonObj["ean"]) ? jsonObj["ean"] : nil
58
+ variant.isDefault = (jsonObj["default"]) ? jsonObj["default"] : nil
59
+ variant.price = (jsonObj["price"]) ? jsonObj["price"] : nil
60
+ variant.oldPrice = (jsonObj["old_price"]) ? jsonObj["old_price"] : nil
61
+ variant.retailPrice = (jsonObj["retail_price"]) ? jsonObj["retail_price"] : nil
62
+ variant.additionalInfo = (jsonObj["additional_info"]) ? jsonObj["additional_info"] : nil
63
+ variant.quantity = (jsonObj["quantity"]) ? jsonObj["quantity"] : 0
64
+ variant.firstActiveDate = (jsonObj["first_active_date"]) ? jsonObj["first_active_date"] : nil
65
+ variant.firstSaleDate = (jsonObj["first_sale_date"]) ? jsonObj["first_sale_date"] : nil
66
+ variant.createdDate = (jsonObj["created_date"]) ? jsonObj["created_date"] : nil
67
+ variant.updatedDate = (jsonObj["updated_date"]) ? jsonObj["updated_date"] : nil
68
+
69
+ variant.facetIds = variant.parseFacetIds(jsonObj)
70
+ variant.color = variant.facetGroup(AboutYou::SDK::Constants::FACET_COLOR, jsonObject)
71
+ variant.length = variant.facetGroup(AboutYou::SDK::Constants::FACET_LENGTH, jsonObject)
72
+ variant.seasonCode = variant.facetGroup(AboutYou::SDK::Constants::FACET_SEASON_CODE,jsonObject)
73
+
74
+
75
+ return variant
76
+ end
77
+
78
+
79
+ def parseImages(imageObject)
80
+ if (!self.images)
81
+ self.images = Array(nil);
82
+ if(imageObject)
83
+ imageObject.each do |image|
84
+ self.images.push(self.factory.createImage(image))
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ ###
91
+ # Get image by given hash.
92
+ #
93
+ # @param string $hash The image hash.
94
+ #
95
+ # @return Image
96
+ ###
97
+ def imageByHash(hash)
98
+
99
+ self.images.each do |image|
100
+ return image if(image.hash == hash)
101
+ end
102
+ nil
103
+ end
104
+
105
+ ###
106
+ # Select a specific image.
107
+ #
108
+ # @param string $hash The image hash or null for default image.
109
+ #
110
+ # @return void
111
+ #
112
+ # @depracted
113
+ ###
114
+ def selectImage(hash=nil)
115
+ if (hash)
116
+ self.selectedImage = imageByHash(hash);
117
+ else
118
+ self.selectedImage = nil;
119
+ end
120
+ end
121
+
122
+ ###
123
+ # Get selected or default image.
124
+ #
125
+ # @return Image
126
+ ###
127
+ def image
128
+
129
+ if (self.selectedImage)
130
+ return self.selectedImage;
131
+ elsif (self.images[0])
132
+ return self.images[0];
133
+ end
134
+ return nil;
135
+ end
136
+
137
+
138
+ def parseFacetIds(jsonObject)
139
+
140
+ ids = Array(nil)
141
+ if !(jsonObject["attributes"].empty?)
142
+ jsonObject["attributes"].each do |group, aIds|
143
+ gid = group[11..group.length] # rm prefix "attributs_"
144
+ ids.push(Hash[gid => aIds]);
145
+ end
146
+ end
147
+
148
+ return ids;
149
+ end
150
+
151
+
152
+ def generateFacetGroupSet(jsonObject)
153
+
154
+ ids = self.parseFacetIds(jsonObject)
155
+ self.facetGroups= AboutYou::SDK::Model::FacetGroupSet.new(ids)
156
+ end
157
+
158
+
159
+ ###
160
+ # @return FacetGroupSet
161
+ ###
162
+ def facetGroupSet(jsonObject)
163
+
164
+ if !(self.facetGroups)
165
+ self.generateFacetGroupSet(jsonObject);
166
+ end
167
+ return self.facetGroups;
168
+ end
169
+
170
+ ###
171
+ # @param integer $groupId
172
+ #
173
+ # @return FacetGroup|null
174
+ ###
175
+ def facetGroup(groupId, jsonObject)
176
+
177
+ return self.facetGroupSet(jsonObject).group(groupId);
178
+ end
179
+
180
+ ###
181
+ # @return FacetGroup|null
182
+ ###
183
+ def size()
184
+
185
+ ###
186
+ # @todo: Instance level caching
187
+ ###
188
+ groupId = self.sizeGroupId();
189
+
190
+ if !(groupId.empty?)
191
+ return self.facetGroup(groupId);
192
+ end
193
+ end
194
+
195
+ ###
196
+ # @return integer|null
197
+ ###
198
+ def sizeGroupId()
199
+
200
+ keys = Hash.new
201
+
202
+ groups = self.facetGroupSet().groups();
203
+
204
+ if (groups.is_a? Array)
205
+ groups.each do |group|
206
+ keys[group.name] = group.groupId();
207
+ end
208
+ end
209
+
210
+ sizeRun = self.facetGroup(AboutYou::SDK::Constants::FACET_SIZE_RUN);
211
+
212
+ if !(sizeRun.empty?)
213
+ sizeRun.facets.each do |facet|
214
+ groupName = facet.value();
215
+ if (keys.key?(groupName))
216
+ return keys[groupName];
217
+ end
218
+ end
219
+ end
220
+ if (keys.key?('size'))
221
+ return keys['size'];
222
+ end
223
+ if (keys.key?('size_run'))
224
+ return keys['size_run'];
225
+ end
226
+
227
+ return nil;
228
+ end
229
+
230
+ ###
231
+ # Returns the quantity per pack for this variant.
232
+ # By default, this returns 1. But some items can have a bigger number.
233
+ #
234
+ # @return int quantity per pack
235
+ ###
236
+ def quantityPerPack()
237
+
238
+ facetGroup = self.facetGroup(AboutYou::SDK::Constants::FACET_QUANTITY_PER_PACK);
239
+
240
+ if !(facetGroup)
241
+ return 1;
242
+ end
243
+
244
+ facets = facetGroup.facets();
245
+
246
+ if !(facets)
247
+ return 1;
248
+ end
249
+
250
+ return facets[0].value();
251
+ end
252
+ end
253
+ end
254
+ end
255
+ end
@@ -0,0 +1,102 @@
1
+ module AboutYou
2
+ module SDK
3
+ module Model
4
+ class VariantsResult
5
+
6
+ # @var Variant[] */
7
+ attr_accessor :variants
8
+ # @var array */
9
+ attr_accessor :errors
10
+
11
+ ###
12
+ #
13
+ # @param \stdClass $jsonObject
14
+ # @param \Collins\ShopApi\Model\ModelFactoryInterface $factory
15
+ # @param \Collins\ShopApi\Model\ProductSearchResult $productSearchResult
16
+ #
17
+ # @return static
18
+ ###
19
+ def self.create(variants, errors = Array(nil), productSearchResult)
20
+
21
+ variantsResult = self.new
22
+ variantsResult.variants = Hash.new
23
+ variantsResult.errors = errors;
24
+
25
+ if (productSearchResult == false || variants.count == 0)
26
+ # no variant was found
27
+ return variantsResult;
28
+ end
29
+
30
+ # get products from product-search
31
+ products = productSearchResult.products();
32
+ variants.each do |variantId, productId|
33
+ if !(products[productId])
34
+ # product was not delivered
35
+ variantsResult.errors.push(variantId)
36
+ next
37
+ end
38
+
39
+ product = products[productId];
40
+ variant = product.variantById(variantId);
41
+
42
+ if (variant.is_a? AboutYou::SDK::Model::Variant)
43
+ variantsResult.variants[variantId] = variant;
44
+ end
45
+ end
46
+
47
+ return variantsResult;
48
+ end
49
+
50
+ ###
51
+ # @return bool
52
+ ###
53
+ def hasVariantsFound()
54
+
55
+ self.variants.count > 0;
56
+ end
57
+
58
+ ###
59
+ # @return bool
60
+ ###
61
+ def hasVariantsNotFound()
62
+
63
+ self.errors.count > 0;
64
+ end
65
+
66
+ ###
67
+ # @return Variant[]
68
+ ###
69
+ def variantsFound()
70
+
71
+ self.variants;
72
+ end
73
+
74
+
75
+ ###
76
+ # @param int $id
77
+ #
78
+ #
79
+ # @return Variant|null
80
+ ###
81
+ def variantById(id)
82
+
83
+ result = nil;
84
+
85
+ if (self.variants[id])
86
+ result = self.variants[id];
87
+ end
88
+
89
+ return result;
90
+ end
91
+
92
+ ###
93
+ # @return int[]
94
+ ###
95
+ def variantsNotFound()
96
+
97
+ self.errors;
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,261 @@
1
+ require_relative 'QueryBuilder.rb'
2
+ module AboutYou
3
+ module SDK
4
+ class Query
5
+ include AboutYou::SDK::QueryBuilder
6
+
7
+ QUERY_TREE = 'category_tree';
8
+ QUERY_FACETS = 'facets';
9
+
10
+ attr_accessor :client
11
+ attr_accessor :query
12
+ attr_accessor :mapping
13
+ attr_accessor :factory
14
+ attr_accessor :ghostQuery
15
+ attr_accessor :allQuery
16
+
17
+
18
+ ###
19
+ # @param ShopApiClient $client
20
+ # @param ModelFactoryInterface $factory
21
+ # @param EventDispatcher $eventDispatcher
22
+ ###
23
+ def initialize(client, factory)
24
+ self.client = client
25
+ self.query=Array(nil)
26
+ self.ghostQuery = Array(nil)
27
+ self.allQuery = Array(nil)
28
+ self.factory=factory
29
+ self.mapping = Hash[
30
+ 'autocompletion' => 'createAutocomplete',
31
+ 'basket' => 'createBasket',
32
+ 'category' => 'createCategoriesResult',
33
+ 'category_tree' => 'createCategoryTree',
34
+ 'facets' => 'createFacetsList',
35
+ 'facet' => 'createFacetList',
36
+ 'facet_types' => 'createFacetTypes',
37
+ 'products' => 'createProductsResult',
38
+ 'products_eans' => 'createProductsEansResult',
39
+ 'product_search' => 'createProductSearchResult',
40
+ 'suggest' => 'createSuggest',
41
+ 'get_order' => 'createOrder',
42
+ 'initiate_order' => 'initiateOrder',
43
+ 'child_apps' => 'createChildApps',
44
+ 'live_variant' => 'createVariantsResult'
45
+ ]
46
+ end
47
+
48
+ ###
49
+ # @param string $searchword The prefix search word to search for.
50
+ # @param int $limit Maximum number of results.
51
+ # @param array $types Array of types to search for (Constants::TYPE_...).
52
+ #
53
+ # @return $this
54
+ #
55
+ # @throws \InvalidArgumentException
56
+ ###
57
+ def fetchAutocomplete(searchword,limit = nil,types = nil)
58
+
59
+ super(searchword, limit, types);
60
+
61
+ self.requireCategoryTree;
62
+ self.requireFacets;
63
+
64
+ return self
65
+ end
66
+
67
+ ###
68
+ # @param string $sessionId Free to choose ID of the current website visitor.
69
+ #
70
+ # @return $this
71
+ ###
72
+ def fetchBasket(sessionId)
73
+
74
+ super(sessionId);
75
+
76
+ self.requireCategoryTree;
77
+ self.requireFacets;
78
+
79
+ return self
80
+ end
81
+
82
+ ###
83
+ # @param string[]|int[] $ids
84
+ # @param array $fields
85
+ #
86
+ # @return $this
87
+ ###
88
+ def fetchProductsByIds(ids,fields = Array(nil))
89
+ super(ids, fields);
90
+ if (AboutYou::SDK::Criteria::ProductFields.requiresCategories(fields))
91
+ self.requireCategoryTree();
92
+ end
93
+ if (AboutYou::SDK::Criteria::ProductFields.requiresFacets(fields))
94
+ self.requireFacets();
95
+ end
96
+
97
+ return self;
98
+ end
99
+
100
+ ###
101
+ # @param string[] $eans
102
+ # @param array $fields
103
+ #
104
+ # @return $this
105
+ ###
106
+ def fetchProductsByEans(eans,fields = Array(nil))
107
+ super(eans, fields);
108
+
109
+ if (AboutYou::SDK::Criteria::ProductFields.requiresCategories(fields))
110
+ self.requireCategoryTree();
111
+ end
112
+ if (AboutYou::SDK::Criteria::ProductFields.requiresFacets(fields))
113
+ self.requireFacets();
114
+ end
115
+
116
+ return self;
117
+ end
118
+
119
+ ###
120
+ # @param ProductSearchCriteria $criteria
121
+ #
122
+ # @return $this
123
+ ###
124
+ def fetchProductSearch(criteria)
125
+
126
+ super(criteria);
127
+
128
+ if (criteria.requiresCategories())
129
+ self.requireCategoryTree();
130
+ end
131
+ if (criteria.requiresFacets())
132
+ self.requireFacets();
133
+ end
134
+
135
+ return self
136
+ end
137
+
138
+ def requireCategoryTree(fetchForced = false)
139
+ if !(fetchForced || self.factory.categoryManager().isEmpty())
140
+ return self
141
+ end
142
+
143
+ self.ghostQuery.push(Hash[QUERY_TREE => Hash[
144
+ 'category_tree' => Hash['version' => '2']]])
145
+
146
+ return self
147
+ end
148
+
149
+ def requireFacets(fetchForced = false)
150
+ if !(fetchForced || self.factory.facetManager.isEmpty)
151
+ return self;
152
+ end
153
+ self.ghostQuery.push(Hash[QUERY_FACETS => Hash[
154
+ 'facets' => Hash.new]])
155
+
156
+ return self;
157
+ end
158
+
159
+ ###
160
+ # @return string
161
+ ###
162
+ def queryString()
163
+ result = Array(nil)
164
+ self.ghostQuery.each do |ghostQuery|
165
+ (ghostQuery.is_a? Hash) ? result.push(ghostQuery[ghostQuery.keys[0]]) : nil
166
+ end
167
+ self.allQuery = result + self.query
168
+ return (result + self.query).to_json
169
+ end
170
+
171
+
172
+ ###
173
+ # request the queries and returns an array of the results
174
+ #
175
+ # @return array
176
+ ###
177
+ def execute()
178
+
179
+ if (self.query.empty? && self.ghostQuery.empty?)
180
+ return Array(nil);
181
+ end
182
+ queryString = queryString()
183
+ result = self.client.request(queryString);
184
+ parseResult(result, self.query.count > 1)
185
+ end
186
+
187
+ ###
188
+ # request the current query and returns the first result
189
+ #
190
+ # @return mixed
191
+ ###
192
+ def executeSingle()
193
+
194
+ result = execute();
195
+ result[-1]
196
+ end
197
+
198
+ def checkResponse(jsonResponse)
199
+
200
+ if (jsonResponse == false || !(jsonResponse.is_a? Array) || jsonResponse.count != self.allQuery.count)
201
+
202
+ raise 'UnexpectedResultException!'
203
+ end
204
+
205
+
206
+ jsonResponse.each_with_index do |responseObject, index|
207
+ currentQuery = self.allQuery[index];
208
+ responseKey = jsonResponse[index].keys[0];
209
+ queryKey = currentQuery.keys[0];
210
+ if (responseKey != queryKey)
211
+ raise 'UnexpectedResultException!
212
+ result ' + String(queryKey) + ' expected, but ' + String(responseKey) + ' given on position ' + String(index) +
213
+ ' - query: ' + currentQuery.to_json
214
+ end
215
+
216
+ if !(self.mapping.has_key?(responseKey))
217
+ raise 'UnexpectedResultException! internal error, ' + String(responseKey) + ' is unknown result'
218
+ end
219
+ end
220
+ end
221
+
222
+ def parseResult(jsonResponse, isMultiRequest=true)
223
+
224
+ self.checkResponse(jsonResponse)
225
+ results = Array(nil)
226
+ queryIds = Array(nil)
227
+ self.allQuery.each do |query|
228
+ queryIds.push(query.keys[0])
229
+ end
230
+
231
+ jsonResponse.each_with_index do |responseObject, index|
232
+ currentQuery = self.allQuery[index]
233
+ resultKey = responseObject.keys[0]
234
+ jsonObject = responseObject[resultKey]
235
+ queryKey = currentQuery.keys[0]
236
+ factory = self.factory
237
+ if (jsonObject['error_code'])
238
+ result = factory.preHandleError(jsonObject, resultKey, isMultiRequest);
239
+ if (result != false)
240
+ results.push(Hash[resultKey=> result])
241
+ next
242
+ end
243
+ end
244
+ query = currentQuery[queryKey];
245
+ queryId = queryIds[index];
246
+ if (queryId == QUERY_FACETS)
247
+ factory.updateFacetManager(jsonObject, query);
248
+ elsif (queryId == QUERY_TREE)
249
+ factory.initializeCategoryManager(jsonObject);
250
+ else
251
+ method = self.mapping[resultKey];
252
+ result = factory.send(method, jsonObject, query)
253
+ results.push(result)
254
+ end
255
+ end
256
+
257
+ return results;
258
+ end
259
+ end
260
+ end
261
+ end