sage_world 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: fcb4b99fb543e5ee93f2d56470fb7c4b5672315b17cf38ea49982890fc9f5b13
4
+ data.tar.gz: 406cf8b2f6d3e1d3a736cdcbca3d9ec281f3af38ea305c66e14a0fdf819732df
5
+ SHA512:
6
+ metadata.gz: 9c4279ae9ddc891e2cc9de3603aac221d23365d9fd77a7f91fcdb1f715cdccdf6fc959c6eabb856e3aac5b29eb6516ef1cf28bca57407b38e7f4aaca2e0fd15f
7
+ data.tar.gz: 9fe3145ed1b1fccbdefadb345d579facdd7eb440681ee4b2740295263c0aa6e43eecc96b8d93126d42dad38b75fcb1e5f9319223ff6cc7aa37823f3b54a07d76
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+ /Gemfile.lock
13
+ /*.gem
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at abhishek.kanojia@vinsol.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in sage_world.gemspec
6
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Abhishek Kanojia
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,272 @@
1
+ # SageWorld
2
+
3
+ SageWorld provides an easier way to use sageworld api in rails application.
4
+ https://www.sageworld.com/
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'sage_world', '~> 0.1.0'
12
+ ```
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install sage_world
21
+
22
+ ### #Installation
23
+ Run `rails g sage_world:install` to generate sage_world initializer file.
24
+ This will generate `config/initializer/sage_world_initializer.rb` which contains the following code.
25
+ ```ruby
26
+ SageWorld.config do |config|
27
+ # Sage Account ID
28
+ config.account_id = ENV['sage_api_account']
29
+ # Sage Login
30
+ config.login = ENV['sage_api_login']
31
+ # Sage Password
32
+ config.password = ENV['sage_api_password']
33
+ # Sage Api Version
34
+ config.version = ENV['sage_api_version']
35
+ # Sage End Point
36
+ config.end_point = ENV['sage_api_end_point']
37
+ # Optional Logging
38
+ config.log_data = true # logs request response to log/sage_world.log
39
+ end
40
+ ```
41
+
42
+ ### #Usage
43
+ SageWorld provides operations on following entities.
44
+ - Category List - Available product categories.
45
+ - Suppliers List - Available suppliers.
46
+ - Supplier Details - Supplier details.
47
+ - Products Search - Search product
48
+ - Product Details - Product details
49
+ - Product Theme List - Available Product themes
50
+
51
+ ### Category List
52
+ ```ruby
53
+ response = SageWorld::Api::CategoryList.get
54
+ # default result is sorted by name.
55
+ # Sorting Results
56
+
57
+ ## Sort-By name
58
+ response = SageWorld::Api::CategoryList.get({ sort: "name"})
59
+
60
+ ## Sort-By category number
61
+ response = SageWorld::Api::CategoryList.get({ sort: "catnum"})
62
+ ```
63
+
64
+ ### Supplier List
65
+
66
+ ```ruby
67
+ response = SageWorld::Api::SupplierList.get
68
+ # default result is sorted by name.
69
+ # Sorting Results
70
+ # Supplier list can be sorted by sageid, company or line
71
+
72
+ ## Sort-By sage_id
73
+ response = SageWorld::Api::SupplierList.get({ sort: "sageid" })
74
+
75
+ ## Sort-By company
76
+ response = SageWorld::Api::SupplierList.get({ sort: "company" })
77
+
78
+ # Sort-By line
79
+ response = SageWorld::Api::SupplierList.get({ sort: "line" })
80
+
81
+ # AllLines => if set to 1 will return AllLines with every supplier
82
+ response = SageWorld::Api::SupplierList.get({ alllines: 1 })
83
+ ```
84
+
85
+ ### Supplier Details
86
+
87
+ ```ruby
88
+ supplier = SageWorld::Api::Supplier.new(supplier_id)
89
+ response = supplier.details
90
+ response.body => { product_details: { ..} }
91
+
92
+ # Options
93
+
94
+ # ExtraReturnFields => specifies additional fields to be returned. If you would like to return the general information for a supplier, then include GENINFO in this field. Otherwise leave it blank.
95
+
96
+ supplier = SageWorld::Api::Supplier.new("22")
97
+ e.g response = supplier.details({ extra_return_fields: "geninfo" })
98
+ ```
99
+
100
+
101
+ ### Product Search
102
+
103
+ ```ruby
104
+ # Keyword for searching is mandatory.
105
+ #
106
+ response = SageWorld::Api::Product.search("mug", { })
107
+ response.body #=> returns hash response.
108
+
109
+ # Searching Options
110
+ # Basic searching can be combined with multiple options available to narrow down the searching scope.
111
+ # Following are the options that can be used along with searching.
112
+
113
+
114
+ # Categories => string
115
+ # by category name
116
+ response = SageWorld::Api::Product.search("Ceramic mug", { categories: "Mugs" })
117
+
118
+ # by category number
119
+ response = SageWorld::Api::Product.search("Ceramic mug", { categories: "232" })
120
+
121
+ # Keywords => string
122
+ # Every product has some product keywords. searching can be narrowed down using keywords
123
+ response = SageWorld::Api::Product.search("Ceramic mug", { categories: "Mugs", keywords: "Tshirt" })
124
+
125
+
126
+ # Themes => string
127
+ # Every product has some product theme associated to it.
128
+ response = SageWorld::Api::Product.search("Ceramic mug", { categories: "Mugs", themes: "Household" })
129
+
130
+
131
+ # SPC => string
132
+ # Search by SPC
133
+ response = SageWorld::Api::Product.search("Ceramic mug", { categories: "Mugs", themes: "Household", spc: "ISUP-SJKHS" })
134
+
135
+ # ItemNum => string
136
+ # Search by ItemNum
137
+ response = SageWorld::Api::Product.search("Ceramic mug", { categories: "Mugs", themes: "Household", item_num: "5000" })
138
+
139
+ # ItemName => string
140
+ # Search by ItemName
141
+ response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug" })
142
+
143
+ # PriceLow => currency
144
+ # Search by Lowest Price in USD ( US dollars )
145
+ response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", price_low: 2 })
146
+
147
+ # PriceHigh => currency
148
+ # Search by Highest Price in USD ( US dollars )
149
+ response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", price_high: 2 })
150
+
151
+ # Qty => integer
152
+ # Search by Quantity
153
+ response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", qty: 2 })
154
+
155
+ # Verified => bool
156
+ # whether product is verified
157
+ response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", verified: true })
158
+
159
+ # Recyclable => 0 or 1
160
+ # whether product is recyclable
161
+ response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", recyclable: 0 })
162
+
163
+ # EnvFriendly => 0 or 1
164
+ # whether product is Environment Friendly
165
+ response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", env_friendly: 1 })
166
+
167
+ # NewProduct => 0 or 1
168
+ # whether product is a new product
169
+ response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", new_product: 1 })
170
+
171
+ # UnionShop => 0 or 1
172
+ # whether product is a new product
173
+ response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", union_shop: 1 })
174
+
175
+ # ProdTime => integer
176
+ # Minimumproduction timein working days or '0' forany
177
+ response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", prod_time: 1 })
178
+
179
+ # MadeIn => string
180
+ # Countrymadein. Blankforall or two-digitcountrycode
181
+ response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", made_in: "us" })
182
+
183
+ # LineName => string
184
+ # Specific Supplier'sLine Name
185
+ response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", line_name: "Sunset Hill Stoneware" })
186
+
187
+ # Sort => "Blank", "PRICE", "PRICEHIGHLOW", "BESTMATCH", "POPULARITY", "PREFGROUPS"
188
+ # Blank: Indicates thatthe defaultsortwill be used (as specified in WebStore Settings)
189
+ # PRICE: Pricesortingin lowestto highest order.
190
+ # PRICEHIGHLOW: Pricesortingin highestto lowest order.
191
+ # BESTMATCH: Sort bythe bestmatch based on thecriteria.
192
+ # POPULARITY: Sorttheitems in terms of popularity, with most popular first.
193
+ # PREFGROUP: Sort by preferencegroups.
194
+
195
+ response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", sort: "PRICE" })
196
+
197
+ # ExtraReturnFields => Comma separated fields name
198
+ # Return additional fields in theresponsestring
199
+
200
+ # Can be from the following :
201
+ # "itemnum" - will return the product’s actual item number.
202
+ # "category" - will return the productcategory name.
203
+ # "description" - will return the description for the item.
204
+ # "colors" - will return thecolor options for the item.
205
+ # "themes" - will return the themes for the item.
206
+ # "netprices" - will return theextended price information, including net pricing, published (catalog) pricing and published.
207
+ # "suppid" - will return the supplier’s Sage.
208
+ # "line" - will return the line name.
209
+ # "company" - will return the company name of the supplier.
210
+ # "prodtime" - will return the production timefor the item.
211
+
212
+ e.g response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", extra_return_fields: "description, themes, prodtime" })
213
+
214
+ # StartNum => integer && MaxRecs => integer
215
+ # Record number to startwith (1=FIRST) & MaxRecs => Maxrecords to return per page
216
+
217
+ # The StartNumand MaxRecs fieldsare used to return asubset of thetotalsearch results. Thisallowsyou to implement“records
218
+ # per page”functionality. Ifyou do notwish to usethesefields, leave both empty. However, ifyou do wantto usethis functionality,
219
+ # the StartNumshould contain thestartingrecord number for this requestand the MaxRecs should contain the number of records
220
+ # to return.Forexample, ifasearch returns110total productsand you would liketo displayrecords1-20,you would enter “1”for
221
+ # StartNumand “20”for MaxRecs. Then, to showrecords21-40,enter “21”as the StartNumand “20”again for MaxRecs.
222
+
223
+ response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", start_num: 1, max_recs: 20 })
224
+
225
+ # MaxTotalItems => integer
226
+ # Maxitems to find (<=1000)
227
+ response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", max_total_items: 100 })
228
+ ```
229
+
230
+ ### Product Details
231
+
232
+ ```ruby
233
+ product = SageWorld::Api::Product.new("Product_id_or_spc")
234
+ response = product.details
235
+ response.body # => returns hash having details of product.
236
+ ```
237
+
238
+ ### Product Theme List
239
+
240
+ ```ruby
241
+ # Get Product theme list.
242
+ response = SageWorld::Api::ProductThemeList.get # => return SageWorld::ResponseHandler object.
243
+ response.body #=> { .. }
244
+ ```
245
+
246
+ ### Hash details finder
247
+ The api response is going to be hash which can be accessed directly via using hash[:key] or for every key that is defined there is a method defined on `response` object which makes it easier to get to nested field.
248
+ ```ruby
249
+ For Example:
250
+ response # =>
251
+ {
252
+ Response: {
253
+ "CategoryList": {
254
+ "Category": ['category 1', 'category2']
255
+ }
256
+ }
257
+ }
258
+
259
+ response.category #=> ['category 1', 'category2']
260
+ response.category_list #=>
261
+ # {
262
+ # "Category": ['category 1', 'category2']
263
+ # }
264
+ ```
265
+
266
+ ## Contributing
267
+
268
+ Bug reports and pull requests are welcome on GitHub at https://github.com/vinsol/sageworld-catalog. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
269
+
270
+ ## License
271
+
272
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "sage_world"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,26 @@
1
+ module SageWorld
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+
5
+ def create_initializer_file
6
+ create_file "config/initializers/sage_world_initializer.rb", <<~FILE
7
+ SageWorld.config do |config|
8
+ # Sage Account ID
9
+ config.account_id = ENV['sage_api_account']
10
+ # Sage Login
11
+ config.login = ENV['sage_api_login']
12
+ # Sage Password
13
+ config.password = ENV['sage_api_password']
14
+ # Sage Api Version
15
+ config.version = ENV['sage_api_version']
16
+ # Sage End Point
17
+ config.end_point = ENV['sage_api_end_point']
18
+ # Optional Logging
19
+ config.log_data = true # logs request response to log/sage_world.log
20
+ end
21
+ FILE
22
+ end
23
+
24
+ end
25
+ end
26
+ end
data/lib/sage_world.rb ADDED
@@ -0,0 +1,21 @@
1
+ require "sage_world/auth"
2
+ require "sage_world/client"
3
+ require "sage_world/constants"
4
+ require "sage_world/configuration"
5
+ require "sage_world/request"
6
+ require "sage_world/version"
7
+ Gem.find_files("sage_world/**/**/*.rb").each { |path| require path }
8
+ require "sage_world/response_handler"
9
+
10
+ module SageWorld
11
+
12
+ class << self
13
+ attr_accessor :configuration
14
+ end
15
+
16
+ def self.config
17
+ @configuration ||= Configuration.new
18
+ yield(configuration) if block_given?
19
+ end
20
+
21
+ end
@@ -0,0 +1,7 @@
1
+ module SageWorld
2
+ module Api
3
+ class Base
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,38 @@
1
+ module SageWorld
2
+ module Api
3
+ class CategoryList < SageWorld::Api::Base
4
+ # Usage:
5
+
6
+ # Without params:
7
+
8
+ # response = SageWorld::Api::CategoryList.get => return SageWorld::ResponseHandler object.
9
+ # On SageWorld::ResponseHandler object one can call following methods depending upon requirements.
10
+ # response.body => returns the response in hash format.
11
+
12
+ # With params:
13
+
14
+ # Sorting results
15
+ # Category list can be sorted by Category Name or Category Number.
16
+ # By Default Category list is sorted by Name.
17
+ # response = SageWorld::Api::CategoryList.get({ sort: "name"}) => sorts category list by name
18
+ # response = SageWorld::Api::CategoryList.get({ sort: "catnum"}) => sorts category list by category number
19
+
20
+ def self.get(params = {})
21
+ if @existing_params == params
22
+ @response
23
+ else
24
+ @existing_params = params
25
+ response = SageWorld::Client.new(list_builder(params)).send_request
26
+ @response = SageWorld::ResponseHandler.new(response)
27
+ end
28
+ end
29
+
30
+ private_class_method def self.list_builder(params)
31
+ {
32
+ category_list: params
33
+ }
34
+ end
35
+
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,31 @@
1
+ module SageWorld
2
+ module Api
3
+ module FindHelper
4
+
5
+ module InstanceMethods
6
+ # SageWorld Api provides helper method on SageWorld::ResponseHandler
7
+ # which can return the key in nested hash or array and return its value.
8
+ #
9
+ # e.g response = SageWorld::Api::Product.search("mugs")
10
+ # Find in hash provides an easy way to do
11
+ # response.body[:xml_data_stream_response][:search_results][:items][:item] => simplifies to
12
+ # response.find_in_hash("Item") => returns array of items.
13
+
14
+ def find_in_hash(lookup_key, haystack = body)
15
+ if haystack.respond_to?(:key?) && haystack.key?(lookup_key)
16
+ haystack[lookup_key]
17
+ elsif haystack.respond_to?(:each)
18
+ data = nil
19
+ haystack.find{ |*nested_haystack| data = find_in_hash(lookup_key, nested_haystack.last) }
20
+ data
21
+ end
22
+ end
23
+ end
24
+
25
+ def self.included(klass)
26
+ klass.send(:include, InstanceMethods)
27
+ end
28
+ end
29
+ end
30
+ end
31
+
@@ -0,0 +1,184 @@
1
+ # Summary
2
+ # Sage world product api provides you 2 basic operations for
3
+ # => search -> returns collection of searched products.
4
+ # => details -> return details of product.
5
+
6
+ module SageWorld
7
+ module Api
8
+ class Product < SageWorld::Api::Base
9
+
10
+ DEFAULT_SEARCH_PARAMS = {
11
+ quick_search: ''
12
+ }.freeze
13
+
14
+ def initialize(product_id)
15
+ @product_id = product_id
16
+ end
17
+
18
+ # Product Details
19
+ # Usage:
20
+ # product = SageWorld::Api::Product.new("Product_id_or_spc")
21
+ # response = product.details
22
+ # response.body => product details as hash
23
+
24
+ def details(options = {})
25
+ if @existing_options == options
26
+ @response
27
+ else
28
+ @existing_options = options
29
+ response = SageWorld::Client.new(find_product_params(@product_id ,options)).send_request
30
+ @response = SageWorld::ResponseHandler.new(response)
31
+ end
32
+ end
33
+
34
+ # Search
35
+ #
36
+ # Usage:
37
+ #
38
+ # Keyword for searching is mandatory.
39
+ #
40
+ # response = SageWorld::Api::Product.search("mug", { })
41
+ # response.body => returns hash response.
42
+
43
+ # Searching Options
44
+ # Basic searching can be combined with multiple options available to narrow down the searching scope.
45
+ # Following are the options that can be used along with searching.
46
+ #
47
+
48
+ # Categories => string
49
+ # by category name
50
+ # e.g response = SageWorld::Api::Product.search("Ceramic mug", { categories: "Mugs" })
51
+
52
+ # by category number
53
+ # e.g response = SageWorld::Api::Product.search("Ceramic mug", { categories: "232" })
54
+
55
+ # Keywords => string
56
+ # Every product has some product keywords. searching can be narrowed down using keywords
57
+ # e.g response = SageWorld::Api::Product.search("Ceramic mug", { categories: "Mugs", keywords: "Tshirt" })
58
+
59
+ # Themes => string
60
+ # Every product has some product theme associated to it.
61
+ # e.g response = SageWorld::Api::Product.search("Ceramic mug", { categories: "Mugs", themes: "Household" })
62
+
63
+ # SPC => string
64
+ # Search by SPC
65
+ # e.g response = SageWorld::Api::Product.search("Ceramic mug", { categories: "Mugs", themes: "Household", spc: "ISUP-SJKHS" })
66
+
67
+ # ItemNum => string
68
+ # Search by ItemNum
69
+ # e.g response = SageWorld::Api::Product.search("Ceramic mug", { categories: "Mugs", themes: "Household", item_num: "5000" })
70
+
71
+ # ItemName => string
72
+ # Search by ItemName
73
+ # e.g response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug" })
74
+
75
+ # PriceLow => currency
76
+ # Search by Lowest Price in USD ( US dollars )
77
+ # e.g response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", price_low: 2 })
78
+
79
+ # PriceHigh => currency
80
+ # Search by Highest Price in USD ( US dollars )
81
+ # e.g response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", price_high: 2 })
82
+
83
+ # Qty => integer
84
+ # Search by Quantity
85
+ # e.g response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", qty: 2 })
86
+
87
+ # Verified => bool
88
+ # whether product is verified
89
+ # e.g response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", verified: true })
90
+
91
+ # Recyclable => 0 or 1
92
+ # whether product is recyclable
93
+ # e.g response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", recyclable: 0 })
94
+
95
+ # EnvFriendly => 0 or 1
96
+ # whether product is Environment Friendly
97
+ # e.g response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", env_friendly: 1 })
98
+
99
+ # NewProduct => 0 or 1
100
+ # whether product is a new product
101
+ # e.g response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", new_product: 1 })
102
+
103
+ # UnionShop => 0 or 1
104
+ # whether product is a new product
105
+ # e.g response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", union_shop: 1 })
106
+
107
+ # ProdTime => integer
108
+ # Minimumproduction timein working days or '0' forany
109
+ # e.g response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", prod_time: 1 })
110
+
111
+ # MadeIn => string
112
+ # Countrymadein. Blankforall or two-digitcountrycode
113
+ # e.g response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", made_in: "us" })
114
+
115
+ # LineName => string
116
+ # Specific Supplier'sLine Name
117
+ # e.g response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", line_name: "Sunset Hill Stoneware" })
118
+
119
+ # Sort => "Blank", "PRICE", "PRICEHIGHLOW", "BESTMATCH", "POPULARITY", "PREFGROUPS"
120
+ # Blank: Indicates thatthe defaultsortwill be used (as specified in WebStore Settings)
121
+ # PRICE: Pricesortingin lowestto highest order.
122
+ # PRICEHIGHLOW: Pricesortingin highestto lowest order.
123
+ # BESTMATCH: Sort bythe bestmatch based on thecriteria.
124
+ # POPULARITY: Sorttheitems in terms of popularity, with most popular first.
125
+ # PREFGROUP: Sort by preferencegroups.
126
+
127
+ # e.g response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", sort: "PRICE" })
128
+
129
+ # ExtraReturnFields => Comma separated fields name
130
+ # Return additional fields in theresponsestring
131
+
132
+ # Can be from the following :
133
+ # "itemnum" - will return the product’s actual item number.
134
+ # "category" - will return the productcategory name.
135
+ # "description" - will return the description for the item.
136
+ # "colors" - will return thecolor options for the item.
137
+ # "themes" - will return the themes for the item.
138
+ # "netprices" - will return theextended price information, including net pricing, published (catalog) pricing and published.
139
+ # "suppid" - will return the supplier’s Sage.
140
+ # "line" - will return the line name.
141
+ # "company" - will return the company name of the supplier.
142
+ # "prodtime" - will return the production timefor the item.
143
+
144
+ # e.g response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", extra_return_fields: "description, themes, prodtime" })
145
+
146
+ # StartNum => integer && MaxRecs => integer
147
+ # Record number to startwith (1=FIRST) & MaxRecs => Maxrecords to return per page
148
+
149
+ # The StartNumand MaxRecs fieldsare used to return asubset of thetotalsearch results. Thisallowsyou to implement“records
150
+ # per page”functionality. Ifyou do notwish to usethesefields, leave both empty. However, ifyou do wantto usethis functionality,
151
+ # the StartNumshould contain thestartingrecord number for this requestand the MaxRecs should contain the number of records
152
+ # to return.Forexample, ifasearch returns110total productsand you would liketo displayrecords1-20,you would enter “1”for
153
+ # StartNumand “20”for MaxRecs. Then, to showrecords21-40,enter “21”as the StartNumand “20”again for MaxRecs.
154
+
155
+ # e.g response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", start_num: 1, max_recs: 20 })
156
+
157
+ # MaxTotalItems => integer
158
+ # Maxitems to find (<=1000)
159
+ # e.g response = SageWorld::Api::Product.search("Ceramic mug", { pr_name: "13 Ceramic Mug", max_total_items: 100 })
160
+
161
+ def self.search(keyword, options = {})
162
+ options[:quick_search] = keyword
163
+ params = DEFAULT_SEARCH_PARAMS.merge(options)
164
+ response = SageWorld::Client.new(search_product_params(params)).send_request
165
+ SageWorld::ResponseHandler.new(response)
166
+ end
167
+
168
+ private def find_product_params(product_id, options)
169
+ {
170
+ product_detail: {
171
+ product_id: product_id
172
+ }
173
+ }.merge(options)
174
+ end
175
+
176
+ private_class_method def self.search_product_params(params)
177
+ {
178
+ search: params
179
+ }
180
+ end
181
+
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,30 @@
1
+ module SageWorld
2
+ module Api
3
+ class ProductThemeList < SageWorld::Api::Base
4
+
5
+ # Usage:
6
+
7
+ # response = SageWorld::Api::ProductThemeList.get => return SageWorld::ResponseHandler object.
8
+
9
+ # On SageWorld::ResponseHandler object one can call following methods depending upon requirements.
10
+ # response.body => returns the response in hash format.
11
+
12
+ def self.get(params = {})
13
+ if @existing_params == params
14
+ @response
15
+ else
16
+ @existing_params = params
17
+ response = SageWorld::Client.new(list_builder(params)).send_request
18
+ @response = SageWorld::ResponseHandler.new(response)
19
+ end
20
+ end
21
+
22
+ private_class_method def self.list_builder(params)
23
+ {
24
+ theme_list: params
25
+ }
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,42 @@
1
+ module SageWorld
2
+ module Api
3
+ class Supplier < SageWorld::Api::Base
4
+
5
+ def initialize(supplier_id)
6
+ @supplier_id = supplier_id
7
+ end
8
+
9
+ # Example Usage:
10
+ #
11
+ # supplier = SageWorld::Api::Supplier.new("222")
12
+ # response = supplier.details
13
+ # response.body => details as hash
14
+ #
15
+ #
16
+ # Options
17
+ # ExtraReturnFields => specifies additional fields to be returned. If you would like to return the general information for a supplier,
18
+ # then include GENINFO in this field. Otherwise leave it blank.
19
+ # supplier = SageWorld::Api::Supplier.new("22")
20
+ # e.g response = supplier.details({ extra_return_fields: "geninfo" })
21
+
22
+ def details(options = {})
23
+ if @existing_options == options
24
+ @response
25
+ else
26
+ @existing_options = options
27
+ response = SageWorld::Client.new(find_supplier_params(@supplier_id, options)).send_request
28
+ @response = SageWorld::ResponseHandler.new(response)
29
+ end
30
+ end
31
+
32
+ private def find_supplier_params(supplier_id, options)
33
+ {
34
+ supplier_info: {
35
+ supp_id: supplier_id
36
+ }
37
+ }.merge(options)
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,41 @@
1
+ module SageWorld
2
+ module Api
3
+ class SupplierList < SageWorld::Api::Base
4
+
5
+ # Example Usage:
6
+ #
7
+ # response = SageWorld::Api::SupplierList.get()
8
+ # response.body => list as hash
9
+
10
+ #
11
+ # Options
12
+ #
13
+ # Sorting
14
+ # Supplier list can be sorted by sageid, company or line
15
+ # e.g response = SageWorld::Api::SupplierList.get({ sort: "sageid" })
16
+ # sort by company response = SageWorld::Api::SupplierList.get({ sort: "company" })
17
+ # sort by line response = SageWorld::Api::SupplierList.get({ sort: "line" })
18
+
19
+ # AllLines => if set to 1 will return AllLines with every supplier
20
+ # e.g response = SageWorld::Api::SupplierList.get({ alllines: 1 })
21
+ #
22
+
23
+ def self.get(params = {})
24
+ if @existing_params == params
25
+ @response
26
+ else
27
+ @existing_params = params
28
+ response = SageWorld::Client.new(list_builder(params)).send_request
29
+ @response = SageWorld::ResponseHandler.new(response)
30
+ end
31
+ end
32
+
33
+ private_class_method def self.list_builder(params)
34
+ {
35
+ supplier_list: params
36
+ }
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,65 @@
1
+ require 'gyoku'
2
+
3
+ module SageWorld
4
+ class Auth
5
+
6
+ attr_reader :request_body
7
+
8
+ def initialize(params)
9
+ validate_configuration
10
+ @login_id = SageWorld.configuration.login
11
+ @password = SageWorld.configuration.password
12
+ @version = SageWorld.configuration.version
13
+ @account_id = SageWorld.configuration.account_id
14
+ @params = params
15
+ end
16
+
17
+ def to_xml
18
+ if request_body
19
+ Gyoku.xml(request_body, key_converter: lambda { |key| key.camelize(:upper) })
20
+ end
21
+ end
22
+
23
+ def request_body
24
+ { XML_data_stream_request: body[:XML_data_stream_request].merge(@params) }
25
+ end
26
+
27
+ private def body
28
+ {
29
+ XML_data_stream_request: {
30
+ version: @version,
31
+ auth: {
32
+ acct_id: @account_id,
33
+ login_id: @login_id,
34
+ password: @password
35
+ }
36
+ }
37
+ }
38
+ end
39
+
40
+ private def validate_configuration
41
+ check_configuration_presence
42
+ check_end_point_presence
43
+ check_credentials_presence
44
+ check_account_presence
45
+ end
46
+
47
+ private def check_configuration_presence
48
+ raise SageWorld::InvalidConfigurationError.new unless SageWorld.configuration.present?
49
+ end
50
+
51
+ private def check_end_point_presence
52
+ raise SageWorld::InvalidConfigurationError.new(SageWorld::Constants::END_POINT_MISSING_ERROR) unless SageWorld.configuration.end_point
53
+ end
54
+
55
+ private def check_credentials_presence
56
+ raise SageWorld::InvalidConfigurationError.new(SageWorld::Constants::INVALID_CREDENTIALS) unless SageWorld.configuration.login
57
+ raise SageWorld::InvalidConfigurationError.new(SageWorld::Constants::INVALID_CREDENTIALS) unless SageWorld.configuration.password
58
+ end
59
+
60
+ private def check_account_presence
61
+ raise SageWorld::InvalidConfigurationError.new(SageWorld::Constants::ACCOUNT_ID_MISSING_ERROR) unless SageWorld.configuration.account_id
62
+ end
63
+
64
+ end
65
+ end
@@ -0,0 +1,17 @@
1
+ module SageWorld
2
+ class Client
3
+
4
+ def initialize(builder)
5
+ @request = SageWorld::Request.new(builder)
6
+ end
7
+
8
+ def send_request
9
+ @request.make_request
10
+ end
11
+
12
+ private def http
13
+ @request.http
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,7 @@
1
+ module SageWorld
2
+ class Configuration
3
+
4
+ attr_accessor :account_id, :login, :password, :end_point, :version, :log_data
5
+
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ module SageWorld
2
+ module Constants
3
+
4
+ ROOT_KEY = 'XMLDataStreamResponse'
5
+ ERROR_KEY = 'ErrMsg'
6
+
7
+ END_POINT_MISSING_ERROR = 'SageWorld: End point missing in configuration.'
8
+ INVALID_CREDENTIALS = 'SageWorld: Invalid Login Id or Password in configuration.'
9
+ ACCOUNT_ID_MISSING_ERROR = 'SageWorld: Account id missing in configuration.'
10
+
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ module SageWorld
2
+ class GeneralError < StandardError
3
+
4
+ DEFAULT_MESSAGE = 'Error occured while fetching data.'
5
+
6
+ def initialize(message = DEFAULT_MESSAGE)
7
+ super
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module SageWorld
2
+ class InvalidConfigurationError < StandardError
3
+
4
+ INVALID_CONFIGURATION = 'SageWorld configuration not found.'.freeze
5
+
6
+ def initialize(message = INVALID_CONFIGURATION)
7
+ super
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,48 @@
1
+ require 'faraday'
2
+ require 'faraday_middleware'
3
+
4
+ module SageWorld
5
+ class Request
6
+
7
+ attr_reader :url, :connection
8
+
9
+ def initialize(params)
10
+ @params = params
11
+ @auth ||= SageWorld::Auth.new(params)
12
+ @url ||= URI(SageWorld.configuration.end_point)
13
+ end
14
+
15
+ private def make_connection
16
+ @connection ||= Faraday.new(@url) do |builder|
17
+
18
+ builder.response :xml, :content_type => /\bxml$/
19
+
20
+ builder.response :json, :content_type => /\bjson$/
21
+
22
+ builder.response :xml, :content_type => /\bhtml$/
23
+
24
+ # Enable logging if enabled
25
+ if SageWorld.configuration.log_data
26
+ builder.response :logger, ::Logger.new("#{Rails.root}/log/sage_world.log"), bodies: true do |logger|
27
+ logger.filter(/(\<LoginId\>)(\w+)/,'\1[REMOVED]')
28
+ logger.filter(/(\<Password\>)(\w+)/,'\1[REMOVED]')
29
+ logger.filter(/(\<AcctId\>)(\w+)/,'\1[REMOVED]')
30
+ end
31
+ end
32
+
33
+ builder.adapter Faraday.default_adapter
34
+ end
35
+ end
36
+
37
+ def make_request
38
+ @connection ||= make_connection
39
+
40
+ if @connection
41
+ @connection.post do |request|
42
+ request.body = @auth.to_xml
43
+ end
44
+ end
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,29 @@
1
+ module SageWorld
2
+ class ResponseHandler
3
+
4
+ include SageWorld::Api::FindHelper
5
+
6
+ attr_reader :response
7
+
8
+ def initialize(response)
9
+ validate_response(response)
10
+ @response = response
11
+ end
12
+
13
+ def body
14
+ @response.body.with_indifferent_access
15
+ end
16
+
17
+ def method_missing(method_name)
18
+ key_name = method_name.to_s.camelize
19
+ find_in_hash(key_name)
20
+ end
21
+
22
+ private def validate_response(response)
23
+ if response.body[SageWorld::Constants::ROOT_KEY].key?(SageWorld::Constants::ERROR_KEY)
24
+ raise SageWorld::GeneralError.new(response.body[SageWorld::Constants::ROOT_KEY][SageWorld::Constants::ERROR_KEY])
25
+ end
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,3 @@
1
+ module SageWorld
2
+ VERSION = "0.1.1"
3
+ end
@@ -0,0 +1,34 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "sage_world/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "sage_world"
8
+ spec.version = SageWorld::VERSION
9
+ spec.authors = ["Abhishek Kanojia", "Vinsol Team"]
10
+ spec.email = ["abhishek.kanojia@vinsol.com", "info@vinsol.com"]
11
+
12
+ spec.summary = %q{Ruby Wrapper for SageWorld catalog api.}
13
+ spec.description = %q{Ruby Wrapper for SageWorld catalog.}
14
+ spec.homepage = "https://github.com/vinsol/sageworld-catalog"
15
+ spec.license = "MIT"
16
+
17
+ # Specify which files should be added to the gem when it is released.
18
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
19
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
20
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
21
+ end
22
+ spec.bindir = "exe"
23
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ spec.require_paths = ["lib"]
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.16"
27
+ spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency "rspec", "~> 3.0"
29
+
30
+ spec.add_dependency 'faraday'
31
+ spec.add_dependency 'faraday_middleware'
32
+ spec.add_dependency 'multi_xml'
33
+ spec.add_dependency 'gyoku', '>= 1.3.1'
34
+ end
metadata ADDED
@@ -0,0 +1,173 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sage_world
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Abhishek Kanojia
8
+ - Vinsol Team
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2018-12-17 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.16'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.16'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '10.0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '10.0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '3.0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '3.0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: faraday
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: faraday_middleware
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: multi_xml
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: gyoku
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: 1.3.1
105
+ type: :runtime
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: 1.3.1
112
+ description: Ruby Wrapper for SageWorld catalog.
113
+ email:
114
+ - abhishek.kanojia@vinsol.com
115
+ - info@vinsol.com
116
+ executables: []
117
+ extensions: []
118
+ extra_rdoc_files: []
119
+ files:
120
+ - ".gitignore"
121
+ - ".rspec"
122
+ - CODE_OF_CONDUCT.md
123
+ - Gemfile
124
+ - Gemfile.lock
125
+ - LICENSE.txt
126
+ - README.md
127
+ - Rakefile
128
+ - bin/console
129
+ - bin/setup
130
+ - lib/generators/sage_world/install_generator.rb
131
+ - lib/sage_world.rb
132
+ - lib/sage_world/api/base.rb
133
+ - lib/sage_world/api/category_list.rb
134
+ - lib/sage_world/api/concerns/find_helper.rb
135
+ - lib/sage_world/api/product.rb
136
+ - lib/sage_world/api/product_theme_list.rb
137
+ - lib/sage_world/api/supplier.rb
138
+ - lib/sage_world/api/supplier_list.rb
139
+ - lib/sage_world/auth.rb
140
+ - lib/sage_world/client.rb
141
+ - lib/sage_world/configuration.rb
142
+ - lib/sage_world/constants.rb
143
+ - lib/sage_world/exceptions/general_exception.rb
144
+ - lib/sage_world/exceptions/invalid_configuration_error.rb
145
+ - lib/sage_world/request.rb
146
+ - lib/sage_world/response_handler.rb
147
+ - lib/sage_world/version.rb
148
+ - sage_world.gemspec
149
+ homepage: https://github.com/vinsol/sageworld-catalog
150
+ licenses:
151
+ - MIT
152
+ metadata: {}
153
+ post_install_message:
154
+ rdoc_options: []
155
+ require_paths:
156
+ - lib
157
+ required_ruby_version: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - ">="
160
+ - !ruby/object:Gem::Version
161
+ version: '0'
162
+ required_rubygems_version: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ requirements: []
168
+ rubyforge_project:
169
+ rubygems_version: 2.7.7
170
+ signing_key:
171
+ specification_version: 4
172
+ summary: Ruby Wrapper for SageWorld catalog api.
173
+ test_files: []