carousel-ruby-api 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.travis.yml +26 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +95 -0
- data/Rakefile +7 -0
- data/carousel.gemspec +26 -0
- data/lib/carousel/client.rb +114 -0
- data/lib/carousel/country.rb +223 -0
- data/lib/carousel/inventory.rb +13 -0
- data/lib/carousel/order.rb +51 -0
- data/lib/carousel/request.rb +27 -0
- data/lib/carousel/response.rb +28 -0
- data/lib/carousel/shipping.rb +15 -0
- data/lib/carousel/tracking.rb +23 -0
- data/lib/carousel/version.rb +3 -0
- data/lib/carousel.rb +9 -0
- data/spec/lib/client_spec.rb +95 -0
- data/spec/lib/order_spec.rb +35 -0
- data/spec/lib/soap_spec.rb +39 -0
- data/spec/spec_helper.rb +129 -0
- metadata +154 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9ea03c1d2f3784982a657f21471e6ad591f34dc9
|
4
|
+
data.tar.gz: 3434dcc47b424e2a7058cee5abb74f0b099ec0d2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 73c45e3e3644978a9dcaf03e336d2796c87cb09182171af087ed98977640d63858bf944b779870d4a665c4b9bf706d324fb3bc237ca31421b23d0efe091a2344
|
7
|
+
data.tar.gz: 51b60c69a795adee15dc13baad5d5fa8b876c4140baa6a246a4b9af4d58d3c3668fc006fe8f695f8766585e3ac6f7d7fdb494538fd54ca46cbb5b7c300629e79
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 2.0.0
|
4
|
+
|
5
|
+
matrix:
|
6
|
+
allow_failures:
|
7
|
+
- rvm: rbx-19mode
|
8
|
+
|
9
|
+
services:
|
10
|
+
- redis
|
11
|
+
|
12
|
+
script:
|
13
|
+
- bundle exec rake
|
14
|
+
|
15
|
+
# addons:
|
16
|
+
# code_climate:
|
17
|
+
# repo_token: f0884115cadbe82b33756e38a9cd32d5129304746a17126d6c7da02e7a69910a
|
18
|
+
|
19
|
+
notifications:
|
20
|
+
email:
|
21
|
+
- justin@jgrubbs.net
|
22
|
+
|
23
|
+
gemfile:
|
24
|
+
- Gemfile
|
25
|
+
|
26
|
+
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Justin Grubbs
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
# Carousel
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/jGRUBBS/carousel-ruby-api.svg?branch=master)](https://travis-ci.org/jGRUBBS/carousel-ruby-api)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/jGRUBBS/carousel-ruby-api.png)](https://codeclimate.com/github/jGRUBBS/carousel-ruby-api)
|
5
|
+
|
6
|
+
Ruby library for interfacing with the Carousel Fulfillment API
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
gem 'carousel-ruby-api'
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install carousel-ruby-api
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
Send order request
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
|
28
|
+
order = {
|
29
|
+
shipping_address: {
|
30
|
+
first_name: "John",
|
31
|
+
last_name: "Smith",
|
32
|
+
address1: "123 Here Now",
|
33
|
+
address2: "2nd Floor",
|
34
|
+
city: "New York",
|
35
|
+
country: "US",
|
36
|
+
zipcode: "10012",
|
37
|
+
phone: "123-123-1234"
|
38
|
+
},
|
39
|
+
billing_address: {
|
40
|
+
first_name: "John",
|
41
|
+
last_name: "Smith",
|
42
|
+
address1: "123 Here Now",
|
43
|
+
address2: "2nd Floor",
|
44
|
+
city: "New York",
|
45
|
+
state: "NY",
|
46
|
+
country: "US",
|
47
|
+
zipcode: "10012",
|
48
|
+
phone: "123-123-1234"
|
49
|
+
},
|
50
|
+
number: "R123123123",
|
51
|
+
orderdate: "2014-06-16",
|
52
|
+
line_items: [
|
53
|
+
{
|
54
|
+
price: "127.23",
|
55
|
+
quantity: "1",
|
56
|
+
sku: "123332211"
|
57
|
+
}
|
58
|
+
],
|
59
|
+
gift_message: "Happy B-Day!"
|
60
|
+
shipping_method: "next-day", # or "express" or "standard"
|
61
|
+
shipping_cost: "20.00",
|
62
|
+
invoice_url: "http://example.com/R123123123/invoice"
|
63
|
+
}
|
64
|
+
|
65
|
+
client = Carousel::Client.new("username", "password")
|
66
|
+
response = client.send_order_request(order)
|
67
|
+
|
68
|
+
if response.success?
|
69
|
+
# DO SOMETHING
|
70
|
+
else
|
71
|
+
# QUEUE REQUEST, STORE AND RAISE ERRORS
|
72
|
+
end
|
73
|
+
|
74
|
+
```
|
75
|
+
|
76
|
+
Get inventory
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
|
80
|
+
client = Carousel::Client.new("username", "password")
|
81
|
+
inventory = client.get_inventory
|
82
|
+
|
83
|
+
inventory.each do |stock|
|
84
|
+
...
|
85
|
+
end
|
86
|
+
|
87
|
+
```
|
88
|
+
|
89
|
+
## Contributing
|
90
|
+
|
91
|
+
1. Fork it
|
92
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
93
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
94
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
95
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/carousel.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require 'carousel/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |spec|
|
5
|
+
spec.name = "carousel-ruby-api"
|
6
|
+
spec.version = Carousel::VERSION
|
7
|
+
spec.authors = ["Justin Grubbs"]
|
8
|
+
spec.email = ["justin@sellect.com"]
|
9
|
+
spec.description = %q{Ruby Library for Carousel Fulfillment API}
|
10
|
+
spec.summary = %q{This is a library for interfacing with the Carousel Fulfillment API}
|
11
|
+
spec.homepage = "http://sellect.com"
|
12
|
+
spec.license = "MIT"
|
13
|
+
|
14
|
+
spec.files = `git ls-files`.split($/)
|
15
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
16
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
17
|
+
spec.require_paths = ["lib"]
|
18
|
+
|
19
|
+
spec.add_dependency "builder"
|
20
|
+
spec.add_dependency "xml-simple"
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
23
|
+
spec.add_development_dependency "rake"
|
24
|
+
spec.add_development_dependency "rspec"
|
25
|
+
spec.add_development_dependency "debugger"
|
26
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'net/https'
|
2
|
+
require 'xmlsimple'
|
3
|
+
|
4
|
+
module Carousel
|
5
|
+
class Client
|
6
|
+
|
7
|
+
TEST_HOST = "web.carousel.eu"
|
8
|
+
TEST_PATH = "carouselwms"
|
9
|
+
LIVE_HOST = "web.carousel.eu"
|
10
|
+
LIVE_PATH = "carouselwms"
|
11
|
+
PORT = 443
|
12
|
+
|
13
|
+
attr_accessor :username, :password, :response, :type, :request_uri, :path
|
14
|
+
|
15
|
+
def initialize(username, password, options = {})
|
16
|
+
raise "Username is required" unless username
|
17
|
+
raise "Password is required" unless password
|
18
|
+
|
19
|
+
@username = username
|
20
|
+
@password = password
|
21
|
+
@options = default_options.merge!(options)
|
22
|
+
end
|
23
|
+
|
24
|
+
def send_order_request(order)
|
25
|
+
request = order_request(order)
|
26
|
+
@path = build_path(Order::PATH)
|
27
|
+
post(request)
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_inventory
|
31
|
+
request = Inventory.new(self).build_inventory_request
|
32
|
+
@path = build_path(Inventory::PATH)
|
33
|
+
post(request).response['stock']
|
34
|
+
end
|
35
|
+
|
36
|
+
def order_request(order)
|
37
|
+
@path = build_path(Order::PATH)
|
38
|
+
Order.new(self).build_order_request(order)
|
39
|
+
end
|
40
|
+
|
41
|
+
def build_path(path)
|
42
|
+
"/#{env_path}/default.asp#{path}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def upcs(inventory)
|
46
|
+
inventory.collect { |s| s["stockid"][0] }
|
47
|
+
end
|
48
|
+
|
49
|
+
def mapped_inventory(upcs, inventory)
|
50
|
+
inventory.collect do |stock|
|
51
|
+
if upcs.include?(stock["stockid"][0])
|
52
|
+
{ quantity: stock["qty"][0].to_i }
|
53
|
+
end
|
54
|
+
end.compact
|
55
|
+
end
|
56
|
+
|
57
|
+
def request_uri
|
58
|
+
"https://#{host}#{@path}"
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
def default_options
|
63
|
+
{
|
64
|
+
verbose: true,
|
65
|
+
test_mode: false
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
69
|
+
def testing?
|
70
|
+
@options[:test_mode]
|
71
|
+
end
|
72
|
+
|
73
|
+
def verbose?
|
74
|
+
@options[:verbose]
|
75
|
+
end
|
76
|
+
|
77
|
+
def env_path
|
78
|
+
testing? ? TEST_PATH : LIVE_PATH
|
79
|
+
end
|
80
|
+
|
81
|
+
def host
|
82
|
+
testing? ? TEST_HOST : LIVE_HOST
|
83
|
+
end
|
84
|
+
|
85
|
+
def log(message)
|
86
|
+
return unless verbose?
|
87
|
+
puts message
|
88
|
+
end
|
89
|
+
|
90
|
+
def http
|
91
|
+
@http ||= Net::HTTP.new(host, PORT)
|
92
|
+
end
|
93
|
+
|
94
|
+
def request(xml_request)
|
95
|
+
request = Net::HTTP::Post.new(@path)
|
96
|
+
request.body = xml_request
|
97
|
+
request.content_type = 'application/xml'
|
98
|
+
http.use_ssl = true
|
99
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
100
|
+
http.request(request)
|
101
|
+
end
|
102
|
+
|
103
|
+
def post(xml_request)
|
104
|
+
response = request(xml_request)
|
105
|
+
parse_response(response.body)
|
106
|
+
end
|
107
|
+
|
108
|
+
def parse_response(xml_response)
|
109
|
+
log(xml_response)
|
110
|
+
@response = Response.new(xml_response, @type)
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,223 @@
|
|
1
|
+
module Carousel
|
2
|
+
class Country
|
3
|
+
|
4
|
+
COUNTRY_MAP = {
|
5
|
+
"IE" => "IU", # Eire
|
6
|
+
"BA" => "BA", # Bosnia Herzegovina
|
7
|
+
"AD" => "AD", # Andorra
|
8
|
+
"AE" => "AE", # United Arab Emirates
|
9
|
+
"AF" => "AF", # Afghanistan
|
10
|
+
"AG" => "AG", # Antigua
|
11
|
+
"AI" => "AI", # Anguilla
|
12
|
+
"AL" => "AL", # Albania
|
13
|
+
"AM" => "AM", # Armenia
|
14
|
+
"AN" => "AN", # Netherlands Antilles
|
15
|
+
"AO" => "AO", # Angola
|
16
|
+
"AR" => "AR", # Argentina
|
17
|
+
"AS" => "PU", # American Samoa
|
18
|
+
"AT" => "AT", # Austria
|
19
|
+
"AU" => "AU", # Australia
|
20
|
+
"AW" => "UB", # Aruba
|
21
|
+
"AZ" => "AZ", # Azerbaijan
|
22
|
+
"BB" => "BB", # Barbados
|
23
|
+
"BD" => "BD", # Bangladesh
|
24
|
+
"BE" => "BE", # Belgium
|
25
|
+
"BF" => "BK", # Burkina
|
26
|
+
"BG" => "BG", # Bulgaria
|
27
|
+
"BH" => "BH", # Bahrain
|
28
|
+
"BI" => "BI", # Burundi
|
29
|
+
"BJ" => "BJ", # Benin
|
30
|
+
"BM" => "BM", # Bermuda
|
31
|
+
"BN" => "BN", # Brunei
|
32
|
+
"BO" => "BO", # Bolivia
|
33
|
+
"BR" => "BR", # Brazil
|
34
|
+
"BS" => "BS", # Bahamas
|
35
|
+
"BT" => "BT", # Bhutan
|
36
|
+
"BW" => "BW", # Botswana
|
37
|
+
"BY" => "BY", # Belarus
|
38
|
+
"BZ" => "BZ", # Belize
|
39
|
+
"CA" => "CA", # Canada
|
40
|
+
"CF" => "CF", # Central African Republic
|
41
|
+
"CG" => "CG", # Congo
|
42
|
+
"CG" => "CD", # Congo
|
43
|
+
"CH" => "CH", # Switzerland
|
44
|
+
"CK" => "CK", # Cook Islands
|
45
|
+
"CL" => "CL", # Chile
|
46
|
+
"CM" => "CM", # Cameroon
|
47
|
+
"CN" => "CN", # China
|
48
|
+
"CO" => "CO", # Colombia
|
49
|
+
"CR" => "CR", # Costa Rica
|
50
|
+
"CU" => "CU", # Cuba
|
51
|
+
"CV" => "CV", # Cape Verde
|
52
|
+
"CY" => "CY", # Cyprus
|
53
|
+
"CZ" => "CZ", # Czech Republic
|
54
|
+
"DE" => "DE", # Germany
|
55
|
+
"DJ" => "DJ", # Djibouti
|
56
|
+
"DK" => "DK", # Denmark
|
57
|
+
"DM" => "DM", # Dominica
|
58
|
+
"DO" => "DO", # Dominican Republic
|
59
|
+
"DZ" => "DZ", # Algeria
|
60
|
+
"EC" => "EC", # Ecuador inc Galapagos Isl.
|
61
|
+
"EE" => "EE", # Estonia
|
62
|
+
"EG" => "EG", # Egypt
|
63
|
+
"ER" => "ER", # Eritrea
|
64
|
+
"ES" => "ES", # Spain
|
65
|
+
"ET" => "ET", # Ethiopia
|
66
|
+
"FI" => "FI", # Finland
|
67
|
+
"FJ" => "FJ", # Fiji
|
68
|
+
"FK" => "FK", # Falkland Islands
|
69
|
+
"FM" => "FM", # Micronesia
|
70
|
+
"FO" => "FO", # Faroe Islands
|
71
|
+
"FR" => "FR", # France
|
72
|
+
"GA" => "GA", # Gabon
|
73
|
+
"GB" => "UK", # United Kingdom
|
74
|
+
"GD" => "GD", # Grenada
|
75
|
+
"GE" => "GE", # Georgia
|
76
|
+
"GF" => "GF", # French Guiana
|
77
|
+
"GH" => "GH", # Ghana
|
78
|
+
"GI" => "GI", # Gibraltar
|
79
|
+
"GL" => "GL", # Greenland
|
80
|
+
"GM" => "GM", # Gambia
|
81
|
+
"GN" => "GN", # Guinea
|
82
|
+
"GP" => "LU", # Guadeloupe
|
83
|
+
"GQ" => "GQ", # Equatorial Guinea
|
84
|
+
"GR" => "GR", # Greece
|
85
|
+
"GT" => "GT", # Guatemala
|
86
|
+
"GU" => "GU", # Guam
|
87
|
+
"GY" => "GY", # Guyana
|
88
|
+
"HK" => "HK", # Hong Kong
|
89
|
+
"HN" => "HN", # Honduras
|
90
|
+
"HR" => "HR", # Croatia
|
91
|
+
"HT" => "HT", # Haiti
|
92
|
+
"HU" => "HU", # Hungary
|
93
|
+
"ID" => "ID", # Indonesia
|
94
|
+
"IL" => "IL", # Israel
|
95
|
+
"IN" => "IN", # India
|
96
|
+
"IQ" => "IQ", # Iraq
|
97
|
+
"IR" => "IR", # Iran
|
98
|
+
"IS" => "IS", # Iceland
|
99
|
+
"IT" => "IT", # Italy
|
100
|
+
"JM" => "JM", # Jamaica
|
101
|
+
"JO" => "JO", # Jordan
|
102
|
+
"JP" => "JP", # Japan
|
103
|
+
"KE" => "KE", # Kenya
|
104
|
+
"KG" => "KG", # Kyrgyzstan
|
105
|
+
"KH" => "KH", # Cambodia
|
106
|
+
"KI" => "KI", # Kiribati
|
107
|
+
"KM" => "KM", # Comoros
|
108
|
+
"KN" => "KT", # St. Kitts
|
109
|
+
"KP" => "FP", # North Korea
|
110
|
+
"KR" => "KR", # South Korea
|
111
|
+
"KW" => "KW", # Kuwait
|
112
|
+
"KY" => "KY", # Cayman Islands
|
113
|
+
"KZ" => "KZ", # Kazakhstan
|
114
|
+
"LB" => "LB", # Lebanon
|
115
|
+
"LC" => "LC", # St Lucia
|
116
|
+
"LI" => "LI", # Liechtenstein
|
117
|
+
"LK" => "LK", # Sri Lanka
|
118
|
+
"LR" => "LY", # Libya
|
119
|
+
"LR" => "LR", # Liberia
|
120
|
+
"LS" => "LS", # Lesotho
|
121
|
+
"LT" => "LT", # Lithuania
|
122
|
+
"LU" => "LX", # Luxembourg
|
123
|
+
"LV" => "LV", # Latvia
|
124
|
+
"MA" => "MA", # Morocco
|
125
|
+
"MC" => "MC", # Monaco
|
126
|
+
"MD" => "MD", # Moldova
|
127
|
+
"MG" => "MG", # Madagascar
|
128
|
+
"MH" => "MH", # Marshall Islands
|
129
|
+
"MK" => "MK", # Macedonia
|
130
|
+
"ML" => "ML", # Mali
|
131
|
+
"MN" => "MN", # Mongolia
|
132
|
+
"MO" => "MO", # Macao
|
133
|
+
"MQ" => "MQ", # Martinique
|
134
|
+
"MR" => "MR", # Mauritania
|
135
|
+
"MS" => "MS", # Montserrat
|
136
|
+
"MT" => "MT", # Malta
|
137
|
+
"MU" => "MU", # Mauritius
|
138
|
+
"MV" => "MV", # Maldives
|
139
|
+
"MW" => "MW", # Malawi
|
140
|
+
"MX" => "MX", # Mexico
|
141
|
+
"MY" => "MY", # Malaysia
|
142
|
+
"MZ" => "MZ", # Mozambique
|
143
|
+
"NA" => "NM", # Namibia
|
144
|
+
"NC" => "NC", # New Caledonia + Depen.
|
145
|
+
"NE" => "NE", # Niger
|
146
|
+
"NF" => "OK", # Norfolk Islands
|
147
|
+
"NG" => "NG", # Nigeria
|
148
|
+
"NI" => "NI", # Nicaragua
|
149
|
+
"NL" => "NL", # Netherlands
|
150
|
+
"NO" => "NO", # Norway
|
151
|
+
"NP" => "NP", # Nepal
|
152
|
+
"NR" => "NR", # Nauru
|
153
|
+
"NU" => "NU", # Niue
|
154
|
+
"NZ" => "NZ", # New Zealand
|
155
|
+
"OM" => "OM", # Oman
|
156
|
+
"PA" => "PA", # Panama
|
157
|
+
"PE" => "PE", # Peru
|
158
|
+
"PF" => "PF", # French Polynesia
|
159
|
+
"PG" => "PG", # Papua New Guinea
|
160
|
+
"PH" => "PH", # Philippines
|
161
|
+
"PK" => "PK", # Pakistan
|
162
|
+
"PL" => "PD", # Poland
|
163
|
+
"PR" => "PR", # Puerto Rico
|
164
|
+
"PT" => "PT", # Portugal
|
165
|
+
"PY" => "PY", # Paraguay
|
166
|
+
"QA" => "QA", # Qatar
|
167
|
+
"RE" => "RE", # Reunion
|
168
|
+
"RO" => "RO", # Romania
|
169
|
+
"RS" => "NT", # Serbia
|
170
|
+
"RU" => "RU", # Russia
|
171
|
+
"RW" => "RW", # Rwanda
|
172
|
+
"SA" => "SA", # Saudi Arabia
|
173
|
+
"SB" => "SB", # Solomon Islands
|
174
|
+
"SC" => "SC", # Seychelles
|
175
|
+
"SD" => "SD", # Sudan
|
176
|
+
"SE" => "SE", # Sweden
|
177
|
+
"SG" => "SG", # Singapore
|
178
|
+
"SI" => "SI", # Slovenia
|
179
|
+
"SK" => "VV", # Slovakia
|
180
|
+
"SL" => "SL", # Sierra Leone
|
181
|
+
"SM" => "SM", # San Marino
|
182
|
+
"SN" => "SN", # Senegal
|
183
|
+
"SR" => "SR", # Surinam
|
184
|
+
"SV" => "SV", # El Salvador
|
185
|
+
"SY" => "SY", # Syria
|
186
|
+
"SZ" => "SZ", # Swaziland
|
187
|
+
"TC" => "TC", # Turks and Caicos Islands
|
188
|
+
"TD" => "TD", # Chad
|
189
|
+
"TG" => "TG", # Togo
|
190
|
+
"TH" => "TH", # Thailand
|
191
|
+
"TJ" => "TJ", # Tajikistan
|
192
|
+
"TM" => "TM", # Turkmenistan
|
193
|
+
"TN" => "TN", # Tunisia
|
194
|
+
"TR" => "TR", # Turkey
|
195
|
+
"TT" => "TT", # Trinidad and Tobago
|
196
|
+
"TV" => "TV", # Tuvalu
|
197
|
+
"TW" => "TW", # Taiwan
|
198
|
+
"TZ" => "TZ", # Tanzania
|
199
|
+
"UA" => "UA", # Ukraine
|
200
|
+
"UG" => "UG", # Uganda
|
201
|
+
"US" => "US", # United States of America
|
202
|
+
"UY" => "UY", # Uruguay
|
203
|
+
"UZ" => "UZ", # Uzbekistan
|
204
|
+
"VC" => "VC", # St Vincent
|
205
|
+
"VE" => "VE", # Venezuela
|
206
|
+
"VI" => "VI", # Virgin Islands of USA
|
207
|
+
"VN" => "VN", # Vietnam
|
208
|
+
"VU" => "VU", # Vanuatu
|
209
|
+
"WF" => "WF", # Wallis and Futuna Islands
|
210
|
+
"YE" => "YE", # Yemen
|
211
|
+
"ZA" => "ZA", # South Africa
|
212
|
+
"ZM" => "ZM", # Zambia
|
213
|
+
"ZW" => "ZW", # Zimbabwe
|
214
|
+
"IM" => "IM", # Isle of Man
|
215
|
+
"JE" => "JE" # Jersey
|
216
|
+
}
|
217
|
+
|
218
|
+
def self.map(code)
|
219
|
+
COUNTRY_MAP[code] || code
|
220
|
+
end
|
221
|
+
|
222
|
+
end
|
223
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Carousel
|
2
|
+
class Order < Request
|
3
|
+
|
4
|
+
PATH = "?action=order"
|
5
|
+
|
6
|
+
def build_order_request(order)
|
7
|
+
construct_xml "orders" do |xml|
|
8
|
+
|
9
|
+
xml.order do
|
10
|
+
|
11
|
+
build_user xml
|
12
|
+
|
13
|
+
xml.customerref order[:number]
|
14
|
+
xml.ordernumber order[:number]
|
15
|
+
xml.shippingmethod Shipping.map(order[:shipping_method])
|
16
|
+
xml.giftnote order[:gift_message] if order[:gift_message].present?
|
17
|
+
|
18
|
+
build_address xml, order[:shipping_address], :shipping
|
19
|
+
build_address xml, order[:billing_address], :billing
|
20
|
+
build_line_items xml, order
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def build_address(xml, address, type)
|
30
|
+
prefix = type == :billing ? 'inv' : ''
|
31
|
+
xml.tag! "#{prefix}name", "#{address[:first_name]} #{address[:last_name]}"
|
32
|
+
xml.tag! "#{prefix}addressline1", address[:address1]
|
33
|
+
xml.tag! "#{prefix}addressline2", address[:address2]
|
34
|
+
xml.tag! "#{prefix}towncity", address[:city]
|
35
|
+
xml.tag! "#{prefix}postcode", address[:zipcode]
|
36
|
+
xml.tag! "#{prefix}country", Country.map(address[:country])
|
37
|
+
xml.tag! "#{prefix}contactphone", address[:phone]
|
38
|
+
end
|
39
|
+
|
40
|
+
def build_line_items(xml, order)
|
41
|
+
order[:line_items].each do |line_item|
|
42
|
+
xml.tag! 'orderline', :number => order[:number] do
|
43
|
+
xml.ordernumber order[:number]
|
44
|
+
xml.sku line_item[:sku]
|
45
|
+
xml.qty line_item[:quantity]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'builder'
|
2
|
+
|
3
|
+
module Carousel
|
4
|
+
class Request
|
5
|
+
|
6
|
+
def initialize(client)
|
7
|
+
@client = client
|
8
|
+
end
|
9
|
+
|
10
|
+
def construct_xml(type)
|
11
|
+
@client.type = type
|
12
|
+
xml = ::Builder::XmlMarkup.new :indent => 2
|
13
|
+
xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
|
14
|
+
xml.tag! type do
|
15
|
+
yield(xml) if block_given?
|
16
|
+
end
|
17
|
+
xml.target!
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
def build_user(xml)
|
22
|
+
xml.user @client.username
|
23
|
+
xml.password @client.password
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Carousel
|
2
|
+
class Response
|
3
|
+
|
4
|
+
attr_accessor :response
|
5
|
+
|
6
|
+
def initialize(raw_response, type)
|
7
|
+
@raw_response = raw_response
|
8
|
+
@response = parse_response(raw_response)
|
9
|
+
@type = type
|
10
|
+
end
|
11
|
+
|
12
|
+
def failure?
|
13
|
+
!success?
|
14
|
+
end
|
15
|
+
|
16
|
+
def success?
|
17
|
+
# FIXME: needs to give actual boolean parsed from response
|
18
|
+
# @response.parsed["#{@type}_response"]["#{@type}_result"][:status] == '0001'
|
19
|
+
true
|
20
|
+
end
|
21
|
+
|
22
|
+
def parse_response(xml_response)
|
23
|
+
return nil if xml_response.blank?
|
24
|
+
XmlSimple.xml_in(xml_response)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Carousel
|
2
|
+
class Tracking
|
3
|
+
|
4
|
+
attr_accessor :carrier
|
5
|
+
|
6
|
+
FEDEX = "http://www.fedexuk.net/accounts/QuickTrack.aspx?consignment=:tracking_number"
|
7
|
+
CAROUSEL = "https://web.carousel.eu/easyweb/default.asp?action=clienttrack&type=Carousel&acct1=BEC01&reference=:tracking_number"
|
8
|
+
|
9
|
+
def initialize(carrier, tracking_number)
|
10
|
+
@carrier = carrier
|
11
|
+
@tracking_number = tracking_number
|
12
|
+
end
|
13
|
+
|
14
|
+
def carrier_destination
|
15
|
+
self.class.const_get(carrier.upcase)
|
16
|
+
end
|
17
|
+
|
18
|
+
def url
|
19
|
+
carrier_destination.gsub(':tracking_number', @tracking_number)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
data/lib/carousel.rb
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Carousel::Client do
|
4
|
+
before do
|
5
|
+
@client = Carousel::Client.new("the_username", "the_password")
|
6
|
+
end
|
7
|
+
|
8
|
+
describe '#send_order_request' do
|
9
|
+
it 'should send order request and return parsed respose' do
|
10
|
+
Carousel::Order.any_instance.should_receive(:build_order_request).with(order_hash)
|
11
|
+
@client.should_receive(:post)
|
12
|
+
@client.send_order_request(order_hash)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'private#default_options' do
|
17
|
+
it 'should return a hash' do
|
18
|
+
@client.send(:default_options).should be_a Hash
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'private#testing?' do
|
23
|
+
it 'should return boolean for test mode' do
|
24
|
+
@client.send(:testing?).should be_false
|
25
|
+
@client.instance_variable_set(:@options, { test_mode: true })
|
26
|
+
@client.send(:testing?).should be_true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'private#verbose?' do
|
31
|
+
it 'should return boolean for verbose mode' do
|
32
|
+
@client.send(:verbose?).should be_true
|
33
|
+
@client.instance_variable_set(:@options, { verbose: false })
|
34
|
+
@client.send(:verbose?).should be_false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe 'private#host' do
|
39
|
+
it 'should' do
|
40
|
+
@client.stub(:testing?).and_return(false)
|
41
|
+
@client.send(:host).should == Carousel::Client::LIVE_HOST
|
42
|
+
@client.stub(:testing?).and_return(true)
|
43
|
+
@client.send(:host).should == Carousel::Client::TEST_HOST
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'private#path' do
|
48
|
+
it 'should' do
|
49
|
+
@client.stub(:testing?).and_return(false)
|
50
|
+
@client.send(:path).should == Carousel::Client::LIVE_PATH
|
51
|
+
@client.stub(:testing?).and_return(true)
|
52
|
+
@client.send(:path).should == Carousel::Client::TEST_PATH
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe 'private#log' do
|
57
|
+
context 'not in verbose mode' do
|
58
|
+
it 'should not log message' do
|
59
|
+
@client.stub(:verbose?).and_return(false)
|
60
|
+
@client.should_not_receive(:puts)
|
61
|
+
@client.send(:log, "message")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
context 'in verbose mode' do
|
65
|
+
it 'should' do
|
66
|
+
@client.stub(:verbose?).and_return(true)
|
67
|
+
@client.should_receive(:puts).with("message")
|
68
|
+
@client.send(:log, "message")
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe 'private#post' do
|
74
|
+
it 'should use net http to post xml request' do
|
75
|
+
path = @client.send(:path)
|
76
|
+
xml_request = "xml_request"
|
77
|
+
response = Carousel::Response.new("<xml>body</xml>", "new_request")
|
78
|
+
header = {'Content-Type' => 'text/xml'}
|
79
|
+
Net::HTTP.any_instance.should_receive(:post).with(path, xml_request, header).and_return(response)
|
80
|
+
@client.should_receive(:parse_response).with(response, nil)
|
81
|
+
@client.should_receive(:log).with(response)
|
82
|
+
@client.send(:post, xml_request)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe 'private#parse_response' do
|
87
|
+
it 'should use xml simple to parse the response' do
|
88
|
+
xml_response = "xml_response"
|
89
|
+
XmlSimple.should_receive(:xml_in).with(xml_response)
|
90
|
+
response = @client.send(:parse_response, xml_response)
|
91
|
+
response.should be_a Carousel::Response
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Carousel::Order do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@client = Carousel::Client.new("the_username", "the_password")
|
7
|
+
@order_client = Carousel::Order.new(@client)
|
8
|
+
@xml = Builder::XmlMarkup.new
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '#build_order_request' do
|
12
|
+
it 'should' do
|
13
|
+
response = @order_client.build_order_request(order_hash)
|
14
|
+
@client.type.should == "new_order_entry"
|
15
|
+
request_body = xml_order_request_string(order_hash)
|
16
|
+
response.should == xml_string("new_order_entry", request_body)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'private#build_address' do
|
21
|
+
it 'should build the proper address xml' do
|
22
|
+
type = "CUSTOMER"
|
23
|
+
request = @order_client.send(:build_address, @xml, type, order_hash[:shipping_address])
|
24
|
+
request.should == xml_address_string(type, order_hash[:shipping_address])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe 'private#build_line_items' do
|
29
|
+
it 'should build the proper line items xml' do
|
30
|
+
request = @order_client.send(:build_line_items, @xml, order_hash)
|
31
|
+
request.should == xml_line_items_string(order_hash)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Carousel::Request do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@client = Carousel::Client.new("the_username", "the_password")
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '#construct_xml' do
|
10
|
+
it 'should build the main xml with header, user, and supplied body' do
|
11
|
+
request_type = "new_order_request"
|
12
|
+
soap_client = Carousel::Request.new(@client)
|
13
|
+
soap_request = soap_client.construct_xml request_type do |xml|
|
14
|
+
xml.test "test"
|
15
|
+
end
|
16
|
+
soap_request.should == xml_string(request_type, "<test>test</test>")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#build_header' do
|
21
|
+
it 'should build xml header' do
|
22
|
+
request_type = "new_order_request"
|
23
|
+
soap_client = Carousel::Request.new(@client)
|
24
|
+
xml = Builder::XmlMarkup.new
|
25
|
+
soap_request = soap_client.build_header(xml, request_type)
|
26
|
+
soap_request.should == xml_header_string(request_type)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#build_user' do
|
31
|
+
it 'should' do
|
32
|
+
soap_client = Carousel::Request.new(@client)
|
33
|
+
xml = Builder::XmlMarkup.new
|
34
|
+
soap_request = soap_client.build_user(xml)
|
35
|
+
soap_request.should == xml_user_string
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
|
+
require 'bundler/setup'
|
8
|
+
Bundler.require(:default, :development)
|
9
|
+
require 'hashie'
|
10
|
+
require 'carousel'
|
11
|
+
|
12
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
13
|
+
RSpec.configure do |config|
|
14
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
15
|
+
config.run_all_when_everything_filtered = true
|
16
|
+
config.filter_run :focus
|
17
|
+
config.order = 'random'
|
18
|
+
end
|
19
|
+
|
20
|
+
def xml_string(type, body)
|
21
|
+
xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
|
22
|
+
xml += "<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\">"
|
23
|
+
xml += xml_header_string(type)
|
24
|
+
xml += "<s:Body><#{type} xmlns=\"SII\">"
|
25
|
+
xml += xml_user_string
|
26
|
+
xml += body
|
27
|
+
xml += "</#{type}></s:Body></s:Envelope>"
|
28
|
+
end
|
29
|
+
|
30
|
+
def xml_header_string(type)
|
31
|
+
xml = "<s:Header><a:Action s:mustUnderstand=\"1\">SII/ISIIService/#{type}</a:Action>"
|
32
|
+
xml += "<a:MessageID>urn:uuid:56b55a70-8bbc-471d-94bb-9ca060bcf99f</a:MessageID>"
|
33
|
+
xml += "<a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo>"
|
34
|
+
xml += "<a:To s:mustUnderstand=\"1\">https://www.carousel.us/webservices/SIIService.svc</a:To></s:Header>"
|
35
|
+
end
|
36
|
+
|
37
|
+
def xml_user_string
|
38
|
+
xml = "<user xmlns:b=\"http://schemas.datacontract.org/2004/07/\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">"
|
39
|
+
xml += "<b:user_name><![CDATA[the_username]]></b:user_name><b:user_password><![CDATA[the_password]]></b:user_password></user>"
|
40
|
+
end
|
41
|
+
|
42
|
+
def xml_address_string(type, address)
|
43
|
+
full_name = "#{address[:first_name]} #{address[:last_name]}"
|
44
|
+
xml = "<b:#{type}_NAME><![CDATA[#{full_name}]]></b:#{type}_NAME>"
|
45
|
+
xml += "<b:#{type}_ADDRESS_1><![CDATA[#{address[:address1]}]]></b:#{type}_ADDRESS_1>"
|
46
|
+
xml += "<b:#{type}_ADDRESS_2><![CDATA[#{address[:address2]}]]></b:#{type}_ADDRESS_2>"
|
47
|
+
xml += "<b:#{type}_ADDRESS_3><![CDATA[#{address[:address3]}]]></b:#{type}_ADDRESS_3>"
|
48
|
+
xml += "<b:#{type}_ADDRESS_CITY>#{address[:city]}</b:#{type}_ADDRESS_CITY>"
|
49
|
+
xml += "<b:#{type}_ADDRESS_COUNTRY>#{address[:country]}</b:#{type}_ADDRESS_COUNTRY>"
|
50
|
+
xml += "<b:#{type}_ADDRESS_STATE>#{address[:state]}</b:#{type}_ADDRESS_STATE>"
|
51
|
+
xml += "<b:#{type}_ADDRESS_ZIP>#{address[:zipcode]}</b:#{type}_ADDRESS_ZIP>"
|
52
|
+
xml += "<b:#{type}_TELEPHONE>#{address[:phone]}</b:#{type}_TELEPHONE>"
|
53
|
+
end
|
54
|
+
|
55
|
+
def xml_line_items_string(order)
|
56
|
+
xml = "<b:Order_Details>"
|
57
|
+
order[:line_items].each do |line_item|
|
58
|
+
xml += "<b:Order_Detail_New>"
|
59
|
+
xml += "<b:PRICE>#{line_item[:price]}</b:PRICE>"
|
60
|
+
xml += "<b:QUANTITY>#{line_item[:quantity]}</b:QUANTITY>"
|
61
|
+
xml += "<b:SIZE>#{line_item[:size]}</b:SIZE>"
|
62
|
+
xml += "<b:sku>#{line_item[:sku]}</b:sku>"
|
63
|
+
xml += "</b:Order_Detail_New>"
|
64
|
+
end
|
65
|
+
xml += "</b:Order_Details>"
|
66
|
+
end
|
67
|
+
|
68
|
+
def xml_order_request_string(order)
|
69
|
+
xml = "<ohn xmlns:b=\"http://schemas.datacontract.org/2004/07/\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">"
|
70
|
+
xml += "<b:SERVICE>90</b:SERVICE>"
|
71
|
+
xml += "<b:USER1><![CDATA[http://example.com/R123123123/invoice]]></b:USER1>"
|
72
|
+
xml += "<b:CARRIER>FEDEX</b:CARRIER>"
|
73
|
+
xml += "<b:CUSTOMER_CODE/><b:DELIVERY_GIFT_WRAP/>"
|
74
|
+
xml += "<b:DELIVERY_MESSAGE><![CDATA[Happy Birthday!]]></b:DELIVERY_MESSAGE>"
|
75
|
+
xml += "<b:EMAIL>someone@somehwere.com</b:EMAIL>"
|
76
|
+
xml += "<b:ORDER_ID>R123123123</b:ORDER_ID>"
|
77
|
+
xml += "<b:ORDER_TYPE>OO</b:ORDER_TYPE>"
|
78
|
+
xml += "<b:DELIVERY_FROM i:nil=\"true\"/><b:DELIVERY_TO i:nil=\"true\"/>"
|
79
|
+
xml += "<b:DELIVERY_ID i:nil=\"true\"/><b:FREIGHT_ACCOUNT i:nil=\"true\"/>"
|
80
|
+
xml += xml_address_string("CUSTOMER", order[:billing_address])
|
81
|
+
xml += xml_address_string("DELIVERY", order[:shipping_address])
|
82
|
+
xml += xml_line_items_string(order)
|
83
|
+
xml += "</ohn>"
|
84
|
+
end
|
85
|
+
|
86
|
+
def order_hash
|
87
|
+
{
|
88
|
+
carrier: "FEDEX",
|
89
|
+
billing_address: {
|
90
|
+
first_name: "John",
|
91
|
+
last_name: "Smith",
|
92
|
+
address1: "123 Here Now",
|
93
|
+
address2: "2nd Floor",
|
94
|
+
address3: "",
|
95
|
+
city: "New York",
|
96
|
+
state: "New York",
|
97
|
+
country: "US",
|
98
|
+
zipcode: "10012",
|
99
|
+
phone: "123-123-1234"
|
100
|
+
},
|
101
|
+
shipping_address: {
|
102
|
+
first_name: "John",
|
103
|
+
last_name: "Smith",
|
104
|
+
address1: "123 Here Now",
|
105
|
+
address2: "2nd Floor",
|
106
|
+
address3: "",
|
107
|
+
city: "New York",
|
108
|
+
state: "New York",
|
109
|
+
country: "US",
|
110
|
+
zipcode: "10012",
|
111
|
+
phone: "123-123-1234"
|
112
|
+
},
|
113
|
+
gift_wrap: "true",
|
114
|
+
gift_message: "Happy Birthday!",
|
115
|
+
email: "someone@somehwere.com",
|
116
|
+
number: "R123123123",
|
117
|
+
type: "OO",
|
118
|
+
line_items: [
|
119
|
+
{
|
120
|
+
price: "127.23",
|
121
|
+
quantity: "1",
|
122
|
+
sku: "123332211",
|
123
|
+
size: "XS"
|
124
|
+
}
|
125
|
+
],
|
126
|
+
shipping_code: "90",
|
127
|
+
invoice_url: "http://example.com/R123123123/invoice"
|
128
|
+
}
|
129
|
+
end
|
metadata
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: carousel-ruby-api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Justin Grubbs
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-08-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: builder
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: xml-simple
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: debugger
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: Ruby Library for Carousel Fulfillment API
|
98
|
+
email:
|
99
|
+
- justin@sellect.com
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- .gitignore
|
105
|
+
- .rspec
|
106
|
+
- .travis.yml
|
107
|
+
- Gemfile
|
108
|
+
- LICENSE.txt
|
109
|
+
- README.md
|
110
|
+
- Rakefile
|
111
|
+
- carousel.gemspec
|
112
|
+
- lib/carousel.rb
|
113
|
+
- lib/carousel/client.rb
|
114
|
+
- lib/carousel/country.rb
|
115
|
+
- lib/carousel/inventory.rb
|
116
|
+
- lib/carousel/order.rb
|
117
|
+
- lib/carousel/request.rb
|
118
|
+
- lib/carousel/response.rb
|
119
|
+
- lib/carousel/shipping.rb
|
120
|
+
- lib/carousel/tracking.rb
|
121
|
+
- lib/carousel/version.rb
|
122
|
+
- spec/lib/client_spec.rb
|
123
|
+
- spec/lib/order_spec.rb
|
124
|
+
- spec/lib/soap_spec.rb
|
125
|
+
- spec/spec_helper.rb
|
126
|
+
homepage: http://sellect.com
|
127
|
+
licenses:
|
128
|
+
- MIT
|
129
|
+
metadata: {}
|
130
|
+
post_install_message:
|
131
|
+
rdoc_options: []
|
132
|
+
require_paths:
|
133
|
+
- lib
|
134
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - '>='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
|
+
requirements:
|
141
|
+
- - '>='
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: '0'
|
144
|
+
requirements: []
|
145
|
+
rubyforge_project:
|
146
|
+
rubygems_version: 2.0.6
|
147
|
+
signing_key:
|
148
|
+
specification_version: 4
|
149
|
+
summary: This is a library for interfacing with the Carousel Fulfillment API
|
150
|
+
test_files:
|
151
|
+
- spec/lib/client_spec.rb
|
152
|
+
- spec/lib/order_spec.rb
|
153
|
+
- spec/lib/soap_spec.rb
|
154
|
+
- spec/spec_helper.rb
|