eldorado 0.0.0.alpha

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 22fbc7b5eb0223ed26f464cf7140d49981931967
4
+ data.tar.gz: 91a81fc97bf1ed96f95abefa695411acc0a98d8d
5
+ SHA512:
6
+ metadata.gz: 7a08a10640fd13c529a64e0a6fc294406fa104930d90a1d13bcb0d4a587c717d343269a7e21d349260735b9a452e1d0e86049c4d93a542777de325cfac142349
7
+ data.tar.gz: 94ec2894812df92f0732a123b816c254ca75ab2a2b5113cfacf4d228845f3a2b79b18776b016b1a594c51146ec2a30c95ea737070cd7dd648dc1091abbb14e94
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'httparty'
3
+ require 'nokogiri'
4
+ require 'nokogiri/xml/document_to_hash'
5
+
6
+ require 'eldorado/error'
7
+ require 'eldorado/client'
8
+ require 'eldorado/builder'
9
+ require 'eldorado/response'
10
+ require 'eldorado/version'
@@ -0,0 +1,50 @@
1
+ module Eldorado
2
+ class Builder
3
+ def initialize(api_key, account_id)
4
+ @api_key = api_key
5
+ @account_id = account_id
6
+ end
7
+
8
+ def build(data)
9
+ doc = Nokogiri::XML::DocumentFragment.parse '<?xml version="1.0" encoding="UTF-8"?>'
10
+ Nokogiri::XML::Builder.with(doc) do |xml|
11
+ xml.key(@api_key)
12
+ xml.accountId(@account_id)
13
+ data.each_pair do |key, value|
14
+ xml_pair(xml, key, value)
15
+ end
16
+ end
17
+ doc.to_xml.strip
18
+ end
19
+
20
+ def destruct(data)
21
+ Nokogiri::XML(data).to_hash
22
+ end
23
+
24
+ private
25
+ def xml_pair(xml, key, value)
26
+ key = key.to_sym
27
+ if value.respond_to? :each_pair
28
+ xml.send(key) do
29
+ value.each_pair { |k, v| xml_pair(xml, k, v) }
30
+ end
31
+ elsif value.respond_to? :each
32
+ xml.send(key) do
33
+ value.each { |val| xml_array(xml, val) }
34
+ end
35
+ else
36
+ xml.send(key.to_sym, value)
37
+ end
38
+ end
39
+
40
+ def xml_array(xml, value)
41
+ if value.respond_to? :each_pair
42
+ value.each_pair { |k, v| xml_pair(xml, k, v) }
43
+ elsif value.respond_to? :each
44
+ value.each { |v| v }
45
+ else
46
+ value
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,133 @@
1
+ module Eldorado
2
+ class Client
3
+ include HTTParty
4
+ base_uri 'https://eldoradopartner.com'
5
+
6
+ attr_accessor :test_mode
7
+
8
+ def initialize(api_key, account_id, test_mode = false)
9
+ login(api_key, account_id)
10
+ @test_mode = test_mode
11
+ # if test_mode
12
+ # self.class.send(:debug_output, $stderr)
13
+ # end
14
+ end
15
+
16
+ def ip_address
17
+ self.class.get('/get_ip/')
18
+ end
19
+
20
+ def stock_check(skus)
21
+ if skus.is_a?(Array)
22
+ skus.map do |sku|
23
+ [sku, singular_stock_check(sku)]
24
+ end.reject(&:nil?).to_h
25
+ else
26
+ { skus => singular_stock_check(skus) }
27
+ end
28
+ end
29
+
30
+ def discounts
31
+ response = post('/discounts/', request)
32
+ if response.discounts
33
+ response.discounts["item"].map do |item|
34
+ [item["product_model"], item["discount_percent"].to_i / 100.0]
35
+ end.to_h
36
+ end
37
+ end
38
+
39
+ def order_history(source)
40
+ unless [:website, :api].include?(source)
41
+ raise Eldorado::Error.new(:order_history_type)
42
+ end
43
+ response = post('/order_history/', request(type: source))
44
+ if response.history
45
+ if response.history.is_a?(Array)
46
+ response.history
47
+ else
48
+ []
49
+ end
50
+ end
51
+ end
52
+
53
+ def open_orders
54
+ response = post('/open_orders/', request)
55
+ response.XML_OpenOrders
56
+ end
57
+
58
+ def submit_order(order)
59
+ endpoint = test_mode ? '/test/orderTest.php' : '/order/index.php'
60
+ response = post(endpoint, normalize_order(order))
61
+ response.XML_Orders
62
+ end
63
+
64
+ private
65
+
66
+ def normalize_order(order)
67
+ data = {
68
+ "Name" => fetch(order, :name),
69
+ "AddressLine1" => fetch(order, :street, :street1, :address1, :addressLine1),
70
+ "AddressLine2" => fetch(order, :street2, :address2, :addressLine2),
71
+ "City" => fetch(order, :city),
72
+ "StateCode" => fetch(order, :state, :stateCode),
73
+ "ZipCode" => fetch(order, :zip, :zipCode),
74
+ "CountryCode" => fetch(order, :country, :countryCode),
75
+ "PhoneNumber" => fetch(order, :phone, :phoneNumber),
76
+ "EnteredByCode" => "API",
77
+ "SourceCode" => "API",
78
+ "CustPONumber" => fetch(order, :custPONumber, :uniqueID, :sourceOrderNumber),
79
+ "SourceOrderNumber" => fetch(order, :sourceOrderNumber, :uniqueID),
80
+ "ShipVia" => fetch(order, :shipVia, :shipBy, :shipping),
81
+ "SpecialInstructions" => fetch(order, :specialInstructions, :instructions),
82
+ "Products" => (fetch(order, :products, :items) || []).map do |product|
83
+ {
84
+ "Product" => {
85
+ "Code" => fetch(product, :code, :sku),
86
+ "Quantity" => fetch(product, :quantity, :qty, :count)
87
+ }
88
+ }
89
+ end
90
+ }
91
+ data.delete_if { |k, v| v.nil? }
92
+ if test_mode
93
+ data["SpecialInstructions"] = "TEST ORDER DO NOT PROCESS"
94
+ end
95
+ request(data)
96
+ end
97
+
98
+ def post(path, xml)
99
+ Eldorado::Response.new(self.class.post(path, body: xml))
100
+ end
101
+
102
+ def login(*args)
103
+ @builder = Eldorado::Builder.new(*args)
104
+ end
105
+
106
+ def request(object = {})
107
+ @builder.build(object)
108
+ end
109
+
110
+ def singular_stock_check(sku)
111
+ response = post('/quantitycheck/', request(item: sku))
112
+ if response.quantity and response.quantity["amount"] != "NOT_FOUND"
113
+ response.quantity["amount"].to_i
114
+ else
115
+ 0
116
+ end
117
+ end
118
+
119
+ def fetch(hash, *keys)
120
+ keys.each do |key|
121
+ if hash[key]
122
+ return hash[key]
123
+ elsif hash[key.to_s.capitalize.to_sym]
124
+ return hash[key.to_s.capitalize.to_sym]
125
+ elsif hash[key.to_s]
126
+ return hash[key.to_s]
127
+ elsif hash[key.to_s.capitalize]
128
+ return hash[key.to_s.capitalize]
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,16 @@
1
+ module Eldorado
2
+ class Error < StandardError
3
+ def initialize(code)
4
+ @code = code
5
+ super(message)
6
+ end
7
+
8
+ def message
9
+ CODES[@code]
10
+ end
11
+
12
+ CODES = {
13
+ order_history_type: "Order history type must either be :website or :api.",
14
+ }
15
+ end
16
+ end
@@ -0,0 +1,49 @@
1
+ require 'ostruct'
2
+
3
+ module Eldorado
4
+ class Response
5
+ attr_accessor :data
6
+
7
+ def initialize(data)
8
+ @data = data.data rescue data
9
+ end
10
+
11
+ def method_missing(method, *args, &block)
12
+ method = method.to_s
13
+ if method.end_with?('=')
14
+ data.send(:[]=, method, *args)
15
+ else
16
+ response = data.send(:[], method)
17
+ if response.is_a?(Hash)
18
+ self.class.new(response)
19
+ else
20
+ response
21
+ end
22
+ end
23
+ end
24
+
25
+ def self.new_from(http_response, key)
26
+ new(http_response.parsed_response.try(:[], key))
27
+ end
28
+
29
+ def inspect
30
+ data.inspect
31
+ end
32
+
33
+ def successful?
34
+ data.has_key?("Success")
35
+ end
36
+
37
+ def failed?
38
+ !successful?
39
+ end
40
+
41
+ def log
42
+ if successful?
43
+ "[Success] #{data['Success']}"
44
+ else
45
+ "[Failure] #{data}"
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,3 @@
1
+ module Eldorado
2
+ Version = "0.0.0.alpha"
3
+ end
@@ -0,0 +1,22 @@
1
+ module Nokogiri
2
+ module XML
3
+ class Document < Nokogiri::XML::Node
4
+ def to_hash
5
+ children_to_hash(children)
6
+ end
7
+
8
+ private
9
+ def children_to_hash(children)
10
+ hash = {}
11
+ children.each do |child|
12
+ if child.children.any?
13
+ hash[child.name.to_sym] = children_to_hash(child.children)
14
+ else
15
+ hash = child.content.to_s
16
+ end
17
+ end
18
+ hash
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,24 @@
1
+ require 'test_helper'
2
+
3
+ class BuilderTest < Minitest::Test
4
+ def setup
5
+ @builder = Eldorado::Builder.new("username", "password")
6
+ end
7
+
8
+ # def test_builds_nested_hash_xml
9
+ # assert_match_xpath "/hello/there", @builder.build(hello: { there: "buddy" })
10
+ # end
11
+
12
+ # def test_builds_array_xml
13
+ # assert_match_xpath "skus/sku", @builder.build(skus: [{sku: 12345}, {sku: 67890}])
14
+ # end
15
+
16
+ def test_breaks_down_xml
17
+ assert_equal @builder.destruct("<hello><there>buddy</there></hello>"), { hello: { there: "buddy" } }
18
+ end
19
+
20
+ # def test_builds_honey_order
21
+ # order = Eldorado::Order.new(reference: "TEST")
22
+ # assert_match_xpath "order/reference", @builder.build(order: order)
23
+ # end
24
+ end
@@ -0,0 +1,34 @@
1
+ require 'test_helper'
2
+
3
+ class ClientTest < Minitest::Test
4
+ def setup
5
+ api_key = ENV.fetch('PARTNER_KEY', '8bad7f1db3fbcecc366fff3da4101363')
6
+ account_id = ENV.fetch('PARTNER_ID', '4119F')
7
+ @client = Eldorado::Client.new(api_key, account_id, true)
8
+ end
9
+
10
+ def test_ip_address
11
+ assert_equal 4, @client.ip_address.split('.').count
12
+ end
13
+
14
+ def test_discounts
15
+ sample = @client.discounts.first
16
+ assert_type String, sample.first
17
+ assert_type Float, sample.last
18
+ end
19
+
20
+ def test_order_history
21
+ assert_type Array, @client.order_history(:website)
22
+ assert_type Array, @client.order_history(:api)
23
+ assert_raises Eldorado::Error do
24
+ @client.order_history(:brick_and_mortar)
25
+ end
26
+ end
27
+
28
+ def test_stock_check
29
+ assert_type Integer, @client.stock_check('SK2189')
30
+ multiple = @client.stock_check(['SK2189', 'SK2257'])
31
+ assert_type Hash, multiple
32
+ assert_equal 2, multiple.length
33
+ end
34
+ end
@@ -0,0 +1,41 @@
1
+ require 'test_helper'
2
+
3
+ class OrderTest < Minitest::Test
4
+ def setup
5
+ @order = Eldorado::Order.new
6
+ end
7
+
8
+ def teardown
9
+ @order = nil
10
+ end
11
+
12
+ def test_update
13
+ @order.update(last: "Shreve", items: [:item, :item])
14
+ assert_equal "Shreve", @order.last
15
+ assert_equal [:item, :item], @order.items
16
+ end
17
+
18
+ def test_validity
19
+ assert @order.invalid?
20
+ @order.required_attributes.each do |attr|
21
+ @order.send("#{attr}=".to_sym, "hello")
22
+ end
23
+ assert @order.valid?
24
+ end
25
+
26
+ def test_present_attributes
27
+ @order.update(last: "Shreve", first: "Jacob")
28
+ assert_equal @order.present_attributes, [:last, :first]
29
+ end
30
+
31
+ def test_shipping_options_as_hash
32
+ @order.shipping = { carrier: :USPS, service: "first class" }
33
+ assert_equal "P003", @order.shipping
34
+ end
35
+
36
+ def test_shipping_option_from_api_code
37
+ shipping_option = Eldorado::Order.shipping_option_from_api_code("P003")
38
+ assert_equal "usps", shipping_option[:carrier]
39
+ assert_equal "first class", shipping_option[:service]
40
+ end
41
+ end
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class EldoradoTest < Minitest::Test
4
+ def test_version_exists
5
+ assert defined? Eldorado::Version
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ require 'test_helper'
2
+
3
+ class DocumentToHashTest < Minitest::Test
4
+ def setup
5
+ @document = Nokogiri::XML("<hello><there>buddy</there></hello")
6
+ end
7
+
8
+ def test_document_to_hash
9
+ assert_equal @document.to_hash, { hello: { there: "buddy" } }
10
+ end
11
+ end
@@ -0,0 +1,32 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), '..','lib'))
2
+ require 'Eldorado'
3
+
4
+ def valid_order
5
+ Eldorado::Order.new({
6
+ items: [
7
+ { item: { sku: 1234, qty: 1 } },
8
+ { item: { sku: 5678, qty: 1 } }
9
+ ],
10
+ last: "Shreve",
11
+ first: "Jacob",
12
+ address1: "1234 East St.",
13
+ city: "Fowlerville",
14
+ state: "MI",
15
+ zip: 48836,
16
+ country: "US",
17
+ phone: "(123) 456-7890",
18
+ emailaddress: "jacob@example.com",
19
+ instructions: "Leave the package behind the wooden bear"
20
+ })
21
+ end
22
+
23
+ def assert_type(expected, instance)
24
+ assert instance.is_a?(expected), "Expected to find instance of #{expected.name}. Instead found #{instance.class.name} #{instance}"
25
+ end
26
+
27
+ def assert_match_xpath(expected, actual, message = nil)
28
+ expected = "#{expected}"
29
+ doc = Nokogiri::XML(actual)
30
+ nodes = doc.xpath(expected)
31
+ assert !nodes.empty?, message || "Expected to find xpath #{expected} in response:\n#{actual}"
32
+ end
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: eldorado
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0.alpha
5
+ platform: ruby
6
+ authors:
7
+ - Jacob Evan Shreve
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-05-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: httparty
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.13'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.13.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '0.13'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 0.13.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: nokogiri
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.6'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 1.6.1
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '1.6'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 1.6.1
53
+ - !ruby/object:Gem::Dependency
54
+ name: guard-minitest
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '2'
60
+ type: :development
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '2'
67
+ description: |2
68
+ Eldorado is a wrapper for the Eldorado.net API which easily enables
69
+ placing orders, checking order statuses, and stock checking.
70
+ email: jacob@sugutoys.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - lib/eldorado.rb
76
+ - lib/eldorado/builder.rb
77
+ - lib/eldorado/client.rb
78
+ - lib/eldorado/error.rb
79
+ - lib/eldorado/response.rb
80
+ - lib/eldorado/version.rb
81
+ - lib/nokogiri/xml/document_to_hash.rb
82
+ - test/eldorado/builder_test.rb
83
+ - test/eldorado/client_test.rb
84
+ - test/eldorado/order_test.rb
85
+ - test/eldorado_test.rb
86
+ - test/nokogiri/xml/document_to_hash_test.rb
87
+ - test/test_helper.rb
88
+ homepage: http://github.com/SuguToys/eldorado
89
+ licenses:
90
+ - MIT
91
+ metadata: {}
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">"
104
+ - !ruby/object:Gem::Version
105
+ version: 1.3.1
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 2.4.5
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: A wrapper for the Eldorado.net API
112
+ test_files:
113
+ - test/eldorado/builder_test.rb
114
+ - test/eldorado/client_test.rb
115
+ - test/eldorado/order_test.rb
116
+ - test/eldorado_test.rb
117
+ - test/nokogiri/xml/document_to_hash_test.rb
118
+ - test/test_helper.rb