active_fulfillment 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +6 -0
- data/Rakefile +2 -1
- data/VERSION +1 -1
- data/active_fulfillment.gemspec +53 -49
- data/lib/active_fulfillment.rb +10 -0
- data/lib/active_fulfillment/fulfillment/services/amazon.rb +52 -3
- data/lib/active_fulfillment/fulfillment/services/shipwire.rb +7 -5
- data/lib/active_fulfillment/fulfillment/services/webgistix.rb +92 -25
- data/lib/active_merchant/common/connection.rb +3 -13
- data/lib/active_merchant/common/country.rb +15 -6
- data/lib/active_merchant/common/posts_data.rb +18 -4
- data/test/fixtures/xml/amazon/tracking_response_1.xml +56 -0
- data/test/fixtures/xml/amazon/tracking_response_2.xml +38 -0
- data/test/fixtures/xml/amazon/tracking_response_error.xml +13 -0
- data/test/fixtures/xml/amazon/tracking_response_not_found.xml +13 -0
- data/test/fixtures/xml/webgistix/tracking_response.xml +14 -0
- data/test/remote/amazon_test.rb +12 -0
- data/test/remote/shipwire_test.rb +2 -2
- data/test/remote/webgistix_test.rb +13 -3
- data/test/unit/services/amazon_test.rb +43 -0
- data/test/unit/services/shipwire_test.rb +7 -4
- data/test/unit/services/webgistix_test.rb +34 -4
- metadata +12 -7
data/CHANGELOG
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
= ActiveFulfillment CHANGELOG
|
2
2
|
|
3
|
+
== Version 1.0.1 (Dec 13, 2010)
|
4
|
+
|
5
|
+
* Updated common files with changes from activemerchant [Dennis Theisen]
|
6
|
+
* Updated Webgistix USPS shipping methods (4 added, 1 removed) [Dennis Theisen]
|
7
|
+
* Changed Webgistix to treat a duplicate response as success instead of failure and to retry failed connection errors. [Dennis Theisen]
|
8
|
+
|
3
9
|
== Version 1.0.0 (July 12, 2010)
|
4
10
|
|
5
11
|
* Add inventory support to Amazon and Webgistix [Adrian Irving-Beer]
|
data/Rakefile
CHANGED
@@ -47,13 +47,14 @@ begin
|
|
47
47
|
gemspec.email = "cody@shopify.com"
|
48
48
|
gemspec.homepage = "http://github.com/shopify/active_fulfillment"
|
49
49
|
gemspec.authors = ["Cody Fauser", "James MacAulay"]
|
50
|
-
gemspec.add_dependency('activesupport', '
|
50
|
+
gemspec.add_dependency('activesupport', '>= 2.3.2')
|
51
51
|
gemspec.add_dependency('builder', '>= 2.0.0')
|
52
52
|
end
|
53
53
|
rescue LoadError
|
54
54
|
puts "Jeweler not available. Install it with: gem install jeweler"
|
55
55
|
end
|
56
56
|
|
57
|
+
desc "Update common files from active_merchant directory"
|
57
58
|
task :update_common do
|
58
59
|
STDERR.puts "Updating common include from ../active_merchant. Please make sure this is up-to-date"
|
59
60
|
system("diff -u lib/active_merchant/common.rb ../active_merchant/lib/active_merchant/common.rb | patch -p0")
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.1
|
data/active_fulfillment.gemspec
CHANGED
@@ -1,68 +1,72 @@
|
|
1
1
|
# Generated by jeweler
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{active_fulfillment}
|
8
|
-
s.version = "1.0.
|
8
|
+
s.version = "1.0.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Cody Fauser", "James MacAulay"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-12-13}
|
13
13
|
s.email = %q{cody@shopify.com}
|
14
14
|
s.files = [
|
15
15
|
"CHANGELOG",
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
16
|
+
"Rakefile",
|
17
|
+
"VERSION",
|
18
|
+
"active_fulfillment.gemspec",
|
19
|
+
"init.rb",
|
20
|
+
"lib/active_fulfillment.rb",
|
21
|
+
"lib/active_fulfillment/fulfillment/base.rb",
|
22
|
+
"lib/active_fulfillment/fulfillment/response.rb",
|
23
|
+
"lib/active_fulfillment/fulfillment/service.rb",
|
24
|
+
"lib/active_fulfillment/fulfillment/services.rb",
|
25
|
+
"lib/active_fulfillment/fulfillment/services/amazon.rb",
|
26
|
+
"lib/active_fulfillment/fulfillment/services/shipwire.rb",
|
27
|
+
"lib/active_fulfillment/fulfillment/services/webgistix.rb",
|
28
|
+
"lib/active_merchant/common.rb",
|
29
|
+
"lib/active_merchant/common/connection.rb",
|
30
|
+
"lib/active_merchant/common/country.rb",
|
31
|
+
"lib/active_merchant/common/error.rb",
|
32
|
+
"lib/active_merchant/common/post_data.rb",
|
33
|
+
"lib/active_merchant/common/posts_data.rb",
|
34
|
+
"lib/active_merchant/common/requires_parameters.rb",
|
35
|
+
"lib/active_merchant/common/utils.rb",
|
36
|
+
"lib/active_merchant/common/validateable.rb",
|
37
|
+
"lib/certs/cacert.pem",
|
38
|
+
"test/fixtures.yml",
|
39
|
+
"test/fixtures/xml/amazon/inventory_get_response.xml",
|
40
|
+
"test/fixtures/xml/amazon/inventory_list_response.xml",
|
41
|
+
"test/fixtures/xml/amazon/inventory_list_response_with_next_1.xml",
|
42
|
+
"test/fixtures/xml/amazon/inventory_list_response_with_next_2.xml",
|
43
|
+
"test/fixtures/xml/amazon/tracking_response_1.xml",
|
44
|
+
"test/fixtures/xml/amazon/tracking_response_2.xml",
|
45
|
+
"test/fixtures/xml/amazon/tracking_response_error.xml",
|
46
|
+
"test/fixtures/xml/amazon/tracking_response_not_found.xml",
|
47
|
+
"test/fixtures/xml/webgistix/tracking_response.xml",
|
48
|
+
"test/remote/amazon_test.rb",
|
49
|
+
"test/remote/shipwire_test.rb",
|
50
|
+
"test/remote/webgistix_test.rb",
|
51
|
+
"test/test_helper.rb",
|
52
|
+
"test/unit/base_test.rb",
|
53
|
+
"test/unit/services/amazon_test.rb",
|
54
|
+
"test/unit/services/shipwire_test.rb",
|
55
|
+
"test/unit/services/webgistix_test.rb"
|
51
56
|
]
|
52
57
|
s.homepage = %q{http://github.com/shopify/active_fulfillment}
|
53
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
54
58
|
s.require_paths = ["lib"]
|
55
59
|
s.rubygems_version = %q{1.3.7}
|
56
60
|
s.summary = %q{Framework and tools for dealing with shipping, tracking and order fulfillment services.}
|
57
61
|
s.test_files = [
|
58
62
|
"test/remote/amazon_test.rb",
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
63
|
+
"test/remote/shipwire_test.rb",
|
64
|
+
"test/remote/webgistix_test.rb",
|
65
|
+
"test/test_helper.rb",
|
66
|
+
"test/unit/base_test.rb",
|
67
|
+
"test/unit/services/amazon_test.rb",
|
68
|
+
"test/unit/services/shipwire_test.rb",
|
69
|
+
"test/unit/services/webgistix_test.rb"
|
66
70
|
]
|
67
71
|
|
68
72
|
if s.respond_to? :specification_version then
|
@@ -70,14 +74,14 @@ Gem::Specification.new do |s|
|
|
70
74
|
s.specification_version = 3
|
71
75
|
|
72
76
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
73
|
-
s.add_runtime_dependency(%q<activesupport>, ["
|
77
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 2.3.2"])
|
74
78
|
s.add_runtime_dependency(%q<builder>, [">= 2.0.0"])
|
75
79
|
else
|
76
|
-
s.add_dependency(%q<activesupport>, ["
|
80
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.2"])
|
77
81
|
s.add_dependency(%q<builder>, [">= 2.0.0"])
|
78
82
|
end
|
79
83
|
else
|
80
|
-
s.add_dependency(%q<activesupport>, ["
|
84
|
+
s.add_dependency(%q<activesupport>, [">= 2.3.2"])
|
81
85
|
s.add_dependency(%q<builder>, [">= 2.0.0"])
|
82
86
|
end
|
83
87
|
end
|
data/lib/active_fulfillment.rb
CHANGED
@@ -30,6 +30,16 @@ rescue LoadError
|
|
30
30
|
require 'active_support'
|
31
31
|
end
|
32
32
|
|
33
|
+
require 'active_support/core_ext/class/inheritable_attributes'
|
34
|
+
require 'active_support/core_ext/class/delegating_attributes'
|
35
|
+
require 'active_support/core_ext/time/calculations'
|
36
|
+
require 'active_support/core_ext/numeric/time'
|
37
|
+
require 'active_support/core_ext/enumerable'
|
38
|
+
begin
|
39
|
+
require 'active_support/core_ext/time/acts_like'
|
40
|
+
rescue LoadError
|
41
|
+
end
|
42
|
+
|
33
43
|
begin
|
34
44
|
require 'builder'
|
35
45
|
rescue LoadError
|
@@ -54,7 +54,8 @@ module ActiveMerchant
|
|
54
54
|
:outbound => {
|
55
55
|
:status => 'GetServiceStatus',
|
56
56
|
:create => 'CreateFulfillmentOrder',
|
57
|
-
:list => 'ListAllFulfillmentOrders'
|
57
|
+
:list => 'ListAllFulfillmentOrders',
|
58
|
+
:tracking => 'GetFulfillmentOrder'
|
58
59
|
},
|
59
60
|
:inventory => {
|
60
61
|
:get => 'GetInventorySupply',
|
@@ -113,6 +114,26 @@ module ActiveMerchant
|
|
113
114
|
response
|
114
115
|
end
|
115
116
|
end
|
117
|
+
|
118
|
+
def fetch_tracking_numbers(order_ids, options = {})
|
119
|
+
order_ids.inject(nil) do |previous, o_id|
|
120
|
+
response = commit :outbound, :tracking, build_tracking_request(o_id, options)
|
121
|
+
|
122
|
+
if !response.success?
|
123
|
+
if response.faultstring =~ /Reason: requested order not found./
|
124
|
+
response = Response.new(true, nil, {
|
125
|
+
:status => SUCCESS,
|
126
|
+
:tracking_numbers => {}
|
127
|
+
})
|
128
|
+
else
|
129
|
+
return response
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
response.tracking_numbers.merge!(previous.tracking_numbers) if previous
|
134
|
+
response
|
135
|
+
end
|
136
|
+
end
|
116
137
|
|
117
138
|
def valid_credentials?
|
118
139
|
status.success?
|
@@ -202,6 +223,15 @@ module ActiveMerchant
|
|
202
223
|
end
|
203
224
|
end
|
204
225
|
|
226
|
+
def build_tracking_request(order_id, options)
|
227
|
+
request = OPERATIONS[:outbound][:tracking]
|
228
|
+
soap_request(request) do |xml|
|
229
|
+
xml.tag! request, { 'xmlns' => SERVICES[:outbound][:xmlns] } do
|
230
|
+
xml.tag! "MerchantFulfillmentOrderId", order_id
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
205
235
|
def add_credentials(xml, request)
|
206
236
|
login = @options[:login]
|
207
237
|
timestamp = "#{Time.now.utc.strftime("%Y-%m-%dT%H:%M:%S")}Z"
|
@@ -264,7 +294,12 @@ module ActiveMerchant
|
|
264
294
|
|
265
295
|
case service
|
266
296
|
when :outbound
|
267
|
-
|
297
|
+
case op
|
298
|
+
when :tracking
|
299
|
+
parse_tracking_response(document)
|
300
|
+
else
|
301
|
+
parse_fulfillment_response(op, document)
|
302
|
+
end
|
268
303
|
when :inventory
|
269
304
|
parse_inventory_response(document)
|
270
305
|
else
|
@@ -288,7 +323,7 @@ module ActiveMerchant
|
|
288
323
|
|
289
324
|
document.each_element('//ns1:MerchantSKUSupply') do |node|
|
290
325
|
# {MerchantSKU => 'SOME-ID', InStockSupplyQuantity => '101', ...}
|
291
|
-
params = node.elements.to_a.
|
326
|
+
params = node.elements.to_a.each_with_object({}) {|elem, hash| hash[elem.name] = elem.text}
|
292
327
|
|
293
328
|
response[:stock_levels][params['MerchantSKU']] = params['InStockSupplyQuantity'].to_i
|
294
329
|
end
|
@@ -300,6 +335,20 @@ module ActiveMerchant
|
|
300
335
|
response
|
301
336
|
end
|
302
337
|
|
338
|
+
def parse_tracking_response(document)
|
339
|
+
response = {}
|
340
|
+
response[:tracking_numbers] = {}
|
341
|
+
|
342
|
+
track_node = REXML::XPath.first(document, '//ns1:FulfillmentShipmentPackage/ns1:TrackingNumber')
|
343
|
+
if track_node
|
344
|
+
id_node = REXML::XPath.first(document, '//ns1:MerchantFulfillmentOrderId')
|
345
|
+
response[:tracking_numbers][id_node.text] = track_node.text
|
346
|
+
end
|
347
|
+
|
348
|
+
response[:response_status] = SUCCESS
|
349
|
+
response
|
350
|
+
end
|
351
|
+
|
303
352
|
def parse_error(http_response)
|
304
353
|
response = {}
|
305
354
|
response[:http_code] = http_response.code
|
@@ -54,12 +54,12 @@ module ActiveMerchant
|
|
54
54
|
commit :inventory, build_inventory_request(options)
|
55
55
|
end
|
56
56
|
|
57
|
-
def fetch_tracking_numbers(
|
58
|
-
commit :tracking, build_tracking_request(
|
57
|
+
def fetch_tracking_numbers(order_ids)
|
58
|
+
commit :tracking, build_tracking_request(order_ids)
|
59
59
|
end
|
60
60
|
|
61
61
|
def valid_credentials?
|
62
|
-
response = fetch_tracking_numbers
|
62
|
+
response = fetch_tracking_numbers([])
|
63
63
|
response.message !~ INVALID_LOGIN
|
64
64
|
end
|
65
65
|
|
@@ -91,14 +91,16 @@ module ActiveMerchant
|
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
94
|
-
def build_tracking_request(
|
94
|
+
def build_tracking_request(order_ids)
|
95
95
|
xml = Builder::XmlMarkup.new
|
96
96
|
xml.instruct!
|
97
97
|
xml.declare! :DOCTYPE, :InventoryStatus, :SYSTEM, SCHEMA_URLS[:inventory]
|
98
98
|
xml.tag! 'TrackingUpdate' do
|
99
99
|
add_credentials(xml)
|
100
100
|
xml.tag! 'Server', test? ? 'Test' : 'Production'
|
101
|
-
|
101
|
+
order_ids.each do |o_id|
|
102
|
+
xml.tag! 'OrderNo', o_id
|
103
|
+
end
|
102
104
|
end
|
103
105
|
end
|
104
106
|
|
@@ -3,16 +3,26 @@ module ActiveMerchant
|
|
3
3
|
class WebgistixService < Service
|
4
4
|
SERVICE_URLS = {
|
5
5
|
:fulfillment => 'https://www.webgistix.com/XML/CreateOrder.asp',
|
6
|
-
:inventory => 'https://www.webgistix.com/XML/GetInventory.asp'
|
6
|
+
:inventory => 'https://www.webgistix.com/XML/GetInventory.asp',
|
7
|
+
:tracking => 'https://www.webgistix.com/XML/GetTracking.asp'
|
7
8
|
}
|
8
9
|
TEST_URLS = SERVICE_URLS.merge({
|
9
10
|
:fulfillment => 'https://www.webgistix.com/XML/CreateOrderTest.asp'
|
10
11
|
})
|
12
|
+
|
13
|
+
SUCCESS, DUPLICATE, FAILURE = 'True', 'Duplicate', 'False'
|
11
14
|
|
12
|
-
SUCCESS, FAILURE = 'True', 'False'
|
13
15
|
SUCCESS_MESSAGE = 'Successfully submitted the order'
|
14
16
|
FAILURE_MESSAGE = 'Failed to submit the order'
|
15
|
-
|
17
|
+
DUPLICATE_MESSAGE = 'This order has already been successfully submitted'
|
18
|
+
|
19
|
+
INVALID_LOGIN = 'Invalid Credentials'
|
20
|
+
NOT_SHIPPED = 'Not Shipped'
|
21
|
+
|
22
|
+
# If a request is detected as a duplicate only the original data will be
|
23
|
+
# used by Webgistix, and the subsequent responses will have a
|
24
|
+
# :duplicate parameter set in the params hash.
|
25
|
+
self.retry_safe = true
|
16
26
|
|
17
27
|
# The first is the label, and the last is the code
|
18
28
|
def self.shipping_methods
|
@@ -37,16 +47,18 @@ module ActiveMerchant
|
|
37
47
|
["FedEx International Economy", "FedEx International Economy"],
|
38
48
|
["FedEx International First", "FedEx International First"],
|
39
49
|
["FedEx Ground", "FedEx Ground"],
|
40
|
-
["USPS Priority Mail
|
41
|
-
["USPS Priority Mail
|
50
|
+
["USPS Priority Mail", "Priority Mail"],
|
51
|
+
["USPS Priority Mail International", "Priority Mail International"],
|
52
|
+
["USPS Priority Mail Small Flat Rate Box", "Priority Mail Small Flat Rate Box"],
|
53
|
+
["USPS Priority Mail Medium Flat Rate Box", "Priority Mail Medium Flat Rate Box"],
|
54
|
+
["USPS Priority Mail Large Flat Rate Box", "Priority Mail Large Flat Rate Box"],
|
55
|
+
["USPS Priority Mail Flat Rate Envelope", "Priority Mail Flat Rate Envelope"],
|
42
56
|
["USPS First Class Mail", "First Class"],
|
43
|
-
["USPS Express Mail & Global Express Mail", "Express"],
|
44
|
-
["USPS Flat Rate Global Express Mail", "Global Express Mail Flat Rate"],
|
45
|
-
["USPS Parcel Post", "Parcel"],
|
46
57
|
["USPS First Class International", "First Class International"],
|
47
|
-
["USPS
|
48
|
-
["USPS
|
49
|
-
["USPS
|
58
|
+
["USPS Express Mail", "Express"],
|
59
|
+
["USPS Express Mail International", "Express Mail International"],
|
60
|
+
["USPS Parcel Post", "Parcel"],
|
61
|
+
["USPS Media Mail", "Media Mail"]
|
50
62
|
].inject(ActiveSupport::OrderedHash.new){|h, (k,v)| h[k] = v; h}
|
51
63
|
end
|
52
64
|
|
@@ -65,6 +77,10 @@ module ActiveMerchant
|
|
65
77
|
def fetch_stock_levels(options = {})
|
66
78
|
commit :inventory, build_inventory_request(options)
|
67
79
|
end
|
80
|
+
|
81
|
+
def fetch_tracking_numbers(order_ids, options = {})
|
82
|
+
commit :tracking, build_tracking_request(order_ids, options)
|
83
|
+
end
|
68
84
|
|
69
85
|
def valid_credentials?
|
70
86
|
response = fulfill('', {}, [], :shipping_method => '')
|
@@ -124,7 +140,32 @@ module ActiveMerchant
|
|
124
140
|
add_credentials(xml)
|
125
141
|
end
|
126
142
|
end
|
127
|
-
|
143
|
+
|
144
|
+
#<?xml version="1.0"?>
|
145
|
+
# <TrackingXML>
|
146
|
+
# <Password>Webgistix</Password>
|
147
|
+
# <CustomerID>3</CustomerID>
|
148
|
+
# <Tracking>
|
149
|
+
# <Order>AB12345</Order>
|
150
|
+
# </Tracking>
|
151
|
+
# <Tracking>
|
152
|
+
# <Order>XY4567</Order>
|
153
|
+
# </Tracking>
|
154
|
+
# </TrackingXML>
|
155
|
+
def build_tracking_request(order_ids, options)
|
156
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
157
|
+
xml.instruct!
|
158
|
+
xml.tag! 'TrackingXML' do
|
159
|
+
add_credentials(xml)
|
160
|
+
|
161
|
+
order_ids.each do |o_id|
|
162
|
+
xml.tag! 'Tracking' do
|
163
|
+
xml.tag! 'Order', o_id
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
128
169
|
def add_credentials(xml)
|
129
170
|
xml.tag! 'CustomerID', @options[:login]
|
130
171
|
xml.tag! 'Password', @options[:password]
|
@@ -184,13 +225,15 @@ module ActiveMerchant
|
|
184
225
|
end
|
185
226
|
|
186
227
|
def success?(response)
|
187
|
-
response[:success] == SUCCESS
|
228
|
+
response[:success] == SUCCESS || response[:success] == DUPLICATE
|
188
229
|
end
|
189
230
|
|
190
231
|
def message_from(response)
|
191
|
-
|
192
|
-
|
193
|
-
|
232
|
+
if response[:duplicate]
|
233
|
+
DUPLICATE_MESSAGE
|
234
|
+
elsif success?(response)
|
235
|
+
SUCCESS_MESSAGE
|
236
|
+
elsif response[:error_0] == INVALID_LOGIN
|
194
237
|
INVALID_LOGIN
|
195
238
|
else
|
196
239
|
FAILURE_MESSAGE
|
@@ -209,18 +252,15 @@ module ActiveMerchant
|
|
209
252
|
parse_fulfillment_response(document)
|
210
253
|
when :inventory
|
211
254
|
parse_inventory_response(document)
|
255
|
+
when :tracking
|
256
|
+
parse_tracking_response(document)
|
212
257
|
else
|
213
258
|
raise ArgumentError, "Unknown action #{action}"
|
214
259
|
end
|
215
260
|
end
|
216
261
|
|
217
262
|
def parse_fulfillment_response(document)
|
218
|
-
response =
|
219
|
-
|
220
|
-
# Fetch the errors
|
221
|
-
document.root.elements.to_a("Error").each_with_index do |e, i|
|
222
|
-
response["error_#{i}".to_sym] = e.text
|
223
|
-
end
|
263
|
+
response = parse_errors(document)
|
224
264
|
|
225
265
|
# Check if completed
|
226
266
|
if completed = REXML::XPath.first(document, '//Completed')
|
@@ -231,23 +271,50 @@ module ActiveMerchant
|
|
231
271
|
response[:success] = FAILURE
|
232
272
|
end
|
233
273
|
|
274
|
+
response[:duplicate] = response[:success] == DUPLICATE
|
275
|
+
|
234
276
|
response
|
235
277
|
end
|
236
278
|
|
237
279
|
def parse_inventory_response(document)
|
238
|
-
response =
|
280
|
+
response = parse_errors(document)
|
239
281
|
response[:stock_levels] = {}
|
240
282
|
|
241
283
|
document.root.each_element('//Item') do |node|
|
242
284
|
# {ItemID => 'SOME-ID', ItemQty => '101'}
|
243
|
-
params = node.elements.to_a.
|
285
|
+
params = node.elements.to_a.each_with_object({}) {|elem, hash| hash[elem.name] = elem.text}
|
244
286
|
|
245
287
|
response[:stock_levels][params['ItemID']] = params['ItemQty'].to_i
|
246
288
|
end
|
247
289
|
|
248
|
-
response[:success] = SUCCESS
|
249
290
|
response
|
250
291
|
end
|
292
|
+
|
293
|
+
def parse_tracking_response(document)
|
294
|
+
response = parse_errors(document)
|
295
|
+
response[:tracking_numbers] = {}
|
296
|
+
|
297
|
+
document.root.each_element('//Shipment') do |node|
|
298
|
+
# {InvoiceNumber => 'SOME-ID', ShipmentTrackingNumber => 'SOME-TRACKING-NUMBER'}
|
299
|
+
params = node.elements.to_a.each_with_object({}) {|elem, hash| hash[elem.name] = elem.text}
|
300
|
+
|
301
|
+
tracking = params['ShipmentTrackingNumber']
|
302
|
+
response[:tracking_numbers][params['InvoiceNumber']] = tracking unless tracking == NOT_SHIPPED
|
303
|
+
end
|
304
|
+
|
305
|
+
response
|
306
|
+
end
|
307
|
+
|
308
|
+
def parse_errors(document)
|
309
|
+
response = {}
|
310
|
+
|
311
|
+
REXML::XPath.match(document, "//Errors/Error").to_a.each_with_index do |e, i|
|
312
|
+
response["error_#{i}".to_sym] = e.text
|
313
|
+
end
|
314
|
+
|
315
|
+
response[:success] = response.empty? ? SUCCESS : FAILURE
|
316
|
+
response
|
317
|
+
end
|
251
318
|
end
|
252
319
|
end
|
253
320
|
end
|
@@ -71,9 +71,8 @@ module ActiveMerchant
|
|
71
71
|
end
|
72
72
|
|
73
73
|
info "--> %d %s (%d %.4fs)" % [result.code, result.message, result.body ? result.body.length : 0, realtime], tag
|
74
|
-
|
75
|
-
|
76
|
-
response
|
74
|
+
debug result.body
|
75
|
+
result
|
77
76
|
rescue EOFError => e
|
78
77
|
raise ConnectionError, "The remote server dropped the connection"
|
79
78
|
rescue Errno::ECONNRESET => e
|
@@ -147,15 +146,6 @@ module ActiveMerchant
|
|
147
146
|
end
|
148
147
|
end
|
149
148
|
|
150
|
-
def handle_response(response)
|
151
|
-
case response.code.to_i
|
152
|
-
when 200...300
|
153
|
-
response.body
|
154
|
-
else
|
155
|
-
raise ResponseError.new(response)
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
149
|
def debug(message, tag = nil)
|
160
150
|
log(:debug, message, tag)
|
161
151
|
end
|
@@ -169,4 +159,4 @@ module ActiveMerchant
|
|
169
159
|
logger.send(level, message) if logger
|
170
160
|
end
|
171
161
|
end
|
172
|
-
end
|
162
|
+
end
|
@@ -46,7 +46,16 @@ module ActiveMerchant #:nodoc:
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def code(format)
|
49
|
-
@codes.
|
49
|
+
@codes.detect{|c| c.format == format}
|
50
|
+
end
|
51
|
+
|
52
|
+
def ==(other)
|
53
|
+
(@name == other.name)
|
54
|
+
end
|
55
|
+
alias eql? ==
|
56
|
+
|
57
|
+
def hash
|
58
|
+
@name.hash
|
50
59
|
end
|
51
60
|
|
52
61
|
def to_s
|
@@ -67,7 +76,6 @@ module ActiveMerchant #:nodoc:
|
|
67
76
|
{ :alpha2 => 'AW', :name => 'Aruba', :alpha3 => 'ABW', :numeric => '533' },
|
68
77
|
{ :alpha2 => 'AU', :name => 'Australia', :alpha3 => 'AUS', :numeric => '036' },
|
69
78
|
{ :alpha2 => 'AT', :name => 'Austria', :alpha3 => 'AUT', :numeric => '040' },
|
70
|
-
{ :alpha2 => 'AX', :name => 'Åland Islands', :alpha3 => 'ALA', :numeric => '248' },
|
71
79
|
{ :alpha2 => 'AZ', :name => 'Azerbaijan', :alpha3 => 'AZE', :numeric => '031' },
|
72
80
|
{ :alpha2 => 'BS', :name => 'Bahamas', :alpha3 => 'BHS', :numeric => '044' },
|
73
81
|
{ :alpha2 => 'BH', :name => 'Bahrain', :alpha3 => 'BHR', :numeric => '048' },
|
@@ -84,8 +92,8 @@ module ActiveMerchant #:nodoc:
|
|
84
92
|
{ :alpha2 => 'BW', :name => 'Botswana', :alpha3 => 'BWA', :numeric => '072' },
|
85
93
|
{ :alpha2 => 'BV', :name => 'Bouvet Island', :alpha3 => 'BVD', :numeric => '074' },
|
86
94
|
{ :alpha2 => 'BR', :name => 'Brazil', :alpha3 => 'BRA', :numeric => '076' },
|
87
|
-
{ :alpha2 => 'BN', :name => 'Brunei Darussalam', :alpha3 => 'BRN', :numeric => '096' },
|
88
95
|
{ :alpha2 => 'IO', :name => 'British Indian Ocean Territory', :alpha3 => 'IOT', :numeric => '086' },
|
96
|
+
{ :alpha2 => 'BN', :name => 'Brunei Darussalam', :alpha3 => 'BRN', :numeric => '096' },
|
89
97
|
{ :alpha2 => 'BG', :name => 'Bulgaria', :alpha3 => 'BGR', :numeric => '100' },
|
90
98
|
{ :alpha2 => 'BF', :name => 'Burkina Faso', :alpha3 => 'BFA', :numeric => '854' },
|
91
99
|
{ :alpha2 => 'BI', :name => 'Burundi', :alpha3 => 'BDI', :numeric => '108' },
|
@@ -142,15 +150,15 @@ module ActiveMerchant #:nodoc:
|
|
142
150
|
{ :alpha2 => 'GP', :name => 'Guadeloupe', :alpha3 => 'GLP', :numeric => '312' },
|
143
151
|
{ :alpha2 => 'GU', :name => 'Guam', :alpha3 => 'GUM', :numeric => '316' },
|
144
152
|
{ :alpha2 => 'GT', :name => 'Guatemala', :alpha3 => 'GTM', :numeric => '320' },
|
153
|
+
{ :alpha2 => 'GG', :name => 'Guernsey', :alpha3 => 'GGY', :numeric => '831' },
|
145
154
|
{ :alpha2 => 'GN', :name => 'Guinea', :alpha3 => 'GIN', :numeric => '324' },
|
146
155
|
{ :alpha2 => 'GW', :name => 'Guinea-Bissau', :alpha3 => 'GNB', :numeric => '624' },
|
147
156
|
{ :alpha2 => 'GY', :name => 'Guyana', :alpha3 => 'GUY', :numeric => '328' },
|
148
|
-
{ :alpha2 => 'GG', :name => 'Guernsey', :alpha3 => 'GGY', :numeric => '831' },
|
149
157
|
{ :alpha2 => 'HT', :name => 'Haiti', :alpha3 => 'HTI', :numeric => '332' },
|
158
|
+
{ :alpha2 => 'HM', :name => 'Heard Island And Mcdonald Islands', :alpha3 => 'HMD', :numeric => '334' },
|
150
159
|
{ :alpha2 => 'VA', :name => 'Holy See (Vatican City State)', :alpha3 => 'VAT', :numeric => '336' },
|
151
160
|
{ :alpha2 => 'HN', :name => 'Honduras', :alpha3 => 'HND', :numeric => '340' },
|
152
161
|
{ :alpha2 => 'HK', :name => 'Hong Kong', :alpha3 => 'HKG', :numeric => '344' },
|
153
|
-
{ :alpha2 => 'HM', :name => 'Heard Island And Mcdonald Islands', :alpha3 => 'HMD', :numeric => '334' },
|
154
162
|
{ :alpha2 => 'HU', :name => 'Hungary', :alpha3 => 'HUN', :numeric => '348' },
|
155
163
|
{ :alpha2 => 'IS', :name => 'Iceland', :alpha3 => 'ISL', :numeric => '352' },
|
156
164
|
{ :alpha2 => 'IN', :name => 'India', :alpha3 => 'IND', :numeric => '356' },
|
@@ -298,7 +306,8 @@ module ActiveMerchant #:nodoc:
|
|
298
306
|
{ :alpha2 => 'EH', :name => 'Western Sahara', :alpha3 => 'ESH', :numeric => '732' },
|
299
307
|
{ :alpha2 => 'YE', :name => 'Yemen', :alpha3 => 'YEM', :numeric => '887' },
|
300
308
|
{ :alpha2 => 'ZM', :name => 'Zambia', :alpha3 => 'ZMB', :numeric => '894' },
|
301
|
-
{ :alpha2 => 'ZW', :name => 'Zimbabwe', :alpha3 => 'ZWE', :numeric => '716' }
|
309
|
+
{ :alpha2 => 'ZW', :name => 'Zimbabwe', :alpha3 => 'ZWE', :numeric => '716' },
|
310
|
+
{ :alpha2 => 'AX', :name => 'Åland Islands', :alpha3 => 'ALA', :numeric => '248' }
|
302
311
|
]
|
303
312
|
|
304
313
|
def self.find(name)
|
@@ -25,9 +25,12 @@ module ActiveMerchant #:nodoc:
|
|
25
25
|
def ssl_post(endpoint, data, headers = {})
|
26
26
|
ssl_request(:post, endpoint, data, headers)
|
27
27
|
end
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
|
29
|
+
def ssl_request(method, endpoint, data, headers)
|
30
|
+
handle_response(raw_ssl_request(method, endpoint, data, headers))
|
31
|
+
end
|
32
|
+
|
33
|
+
def raw_ssl_request(method, endpoint, data, headers = {})
|
31
34
|
connection = Connection.new(endpoint)
|
32
35
|
connection.open_timeout = open_timeout
|
33
36
|
connection.read_timeout = read_timeout
|
@@ -42,6 +45,17 @@ module ActiveMerchant #:nodoc:
|
|
42
45
|
|
43
46
|
connection.request(method, data, headers)
|
44
47
|
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def handle_response(response)
|
52
|
+
case response.code.to_i
|
53
|
+
when 200...300
|
54
|
+
response.body
|
55
|
+
else
|
56
|
+
raise ResponseError.new(response)
|
57
|
+
end
|
58
|
+
end
|
45
59
|
|
46
60
|
end
|
47
|
-
end
|
61
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
|
2
|
+
<soapenv:Body>
|
3
|
+
<ns1:GetFulfillmentOrderResponse
|
4
|
+
xmlns:ns1="http://fba-outbound.amazonaws.com/doc/2007-08-02/">
|
5
|
+
<ns1:GetFulfillmentOrderResult>
|
6
|
+
<ns1:FulfillmentOrder>
|
7
|
+
<ns1:MerchantFulfillmentOrderId>TEST-00000001</ns1:MerchantFulfillmentOrderId>
|
8
|
+
<ns1:ReceivedDateTime>2007-08-02T08:00:00Z</ns1:ReceivedDateTime>
|
9
|
+
<ns1:ShippingSpeedCategory>Standard</ns1:ShippingSpeedCategory>
|
10
|
+
<ns1:DisplayableOrderDateTime>2007-08-02T00:00:00Z</ns1:DisplayableOrderDateTime>
|
11
|
+
<ns1:DisplayableOrderComment>Thank you for your order!</ns1:DisplayableOrderComment>
|
12
|
+
<ns1:DisplayableOrderId>TEST-00000001</ns1:DisplayableOrderId>
|
13
|
+
<ns1:DestinationAddress>
|
14
|
+
<ns1:Name>John Smith</ns1:Name>
|
15
|
+
<ns1:Line1>2412 25th Ave NW.</ns1:Line1>
|
16
|
+
<ns1:City>Seattle</ns1:City>
|
17
|
+
<ns1:StateOrProvinceCode>WA</ns1:StateOrProvinceCode>
|
18
|
+
<ns1:CountryCode>US</ns1:CountryCode>
|
19
|
+
<ns1:PostalCode>98104</ns1:PostalCode>
|
20
|
+
<ns1:PhoneNumber>206-266-1000</ns1:PhoneNumber>
|
21
|
+
</ns1:DestinationAddress>
|
22
|
+
<ns1:FulfillmentOrderStatus>Complete</ns1:FulfillmentOrderStatus>
|
23
|
+
<ns1:StatusUpdatedDateTime>2007-08-03T16:00:00Z</ns1:StatusUpdatedDateTime>
|
24
|
+
</ns1:FulfillmentOrder>
|
25
|
+
<ns1:FulfillmentOrderItem>
|
26
|
+
<ns1:MerchantSKU>MSKU-00000001</ns1:MerchantSKU>
|
27
|
+
<ns1:MerchantFulfillmentOrderItemId>TEST-00000001-1</ns1:MerchantFulfillmentOrderItemId>
|
28
|
+
<ns1:Quantity>2</ns1:Quantity>
|
29
|
+
<ns1:CancelledQuantity>0</ns1:CancelledQuantity>
|
30
|
+
<ns1:UnfulfillableQuantity>0</ns1:UnfulfillableQuantity>
|
31
|
+
</ns1:FulfillmentOrderItem>
|
32
|
+
<ns1:FulfillmentShipment>
|
33
|
+
<ns1:AmazonShipmentId>TEST00000001</ns1:AmazonShipmentId>
|
34
|
+
<ns1:FulfillmentCenterId>TST1</ns1:FulfillmentCenterId>
|
35
|
+
<ns1:FulfillmentShipmentStatus>Shipped</ns1:FulfillmentShipmentStatus>
|
36
|
+
<ns1:ShippingDateTime>2007-08-03T16:00:00Z</ns1:ShippingDateTime>
|
37
|
+
<ns1:EstimatedArrivalDateTime>2007-08-10T16:00:00Z</ns1:EstimatedArrivalDateTime>
|
38
|
+
<ns1:FulfillmentShipmentItem>
|
39
|
+
<ns1:MerchantSKU>MSKU-00000001</ns1:MerchantSKU>
|
40
|
+
<ns1:MerchantFulfillmentOrderItemId>TEST-00000001-1</ns1:MerchantFulfillmentOrderItemId>
|
41
|
+
<ns1:Quantity>2</ns1:Quantity>
|
42
|
+
<ns1:PackageNumber>1</ns1:PackageNumber>
|
43
|
+
</ns1:FulfillmentShipmentItem>
|
44
|
+
<ns1:FulfillmentShipmentPackage>
|
45
|
+
<ns1:PackageNumber>1</ns1:PackageNumber>
|
46
|
+
<ns1:CarrierCode>UPS</ns1:CarrierCode>
|
47
|
+
<ns1:TrackingNumber>UPS00000001</ns1:TrackingNumber>
|
48
|
+
</ns1:FulfillmentShipmentPackage>
|
49
|
+
</ns1:FulfillmentShipment>
|
50
|
+
</ns1:GetFulfillmentOrderResult>
|
51
|
+
<ns1:ResponseMetadata>
|
52
|
+
<ns1:RequestId>963215ec-bec6-4ae0-84e0-19f5823ee33a</ns1:RequestId>
|
53
|
+
</ns1:ResponseMetadata>
|
54
|
+
</ns1:GetFulfillmentOrderResponse>
|
55
|
+
</soapenv:Body>
|
56
|
+
</soapenv:Envelope>
|
@@ -0,0 +1,38 @@
|
|
1
|
+
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
|
2
|
+
<soapenv:Body>
|
3
|
+
<ns1:GetFulfillmentOrderResponse
|
4
|
+
xmlns:ns1="http://fba-outbound.amazonaws.com/doc/2007-08-02/">
|
5
|
+
<ns1:GetFulfillmentOrderResult>
|
6
|
+
<ns1:FulfillmentOrder>
|
7
|
+
<ns1:MerchantFulfillmentOrderId>TEST-00000002</ns1:MerchantFulfillmentOrderId>
|
8
|
+
<ns1:ReceivedDateTime>2007-08-02T08:00:00Z</ns1:ReceivedDateTime>
|
9
|
+
<ns1:ShippingSpeedCategory>Standard</ns1:ShippingSpeedCategory>
|
10
|
+
<ns1:DisplayableOrderDateTime>2007-08-02T00:00:00Z</ns1:DisplayableOrderDateTime>
|
11
|
+
<ns1:DisplayableOrderComment>Thank you for your order!</ns1:DisplayableOrderComment>
|
12
|
+
<ns1:DisplayableOrderId>TEST-00000001</ns1:DisplayableOrderId>
|
13
|
+
<ns1:DestinationAddress>
|
14
|
+
<ns1:Name>John Smith</ns1:Name>
|
15
|
+
<ns1:Line1>2412 25th Ave NW.</ns1:Line1>
|
16
|
+
<ns1:City>Seattle</ns1:City>
|
17
|
+
<ns1:StateOrProvinceCode>WA</ns1:StateOrProvinceCode>
|
18
|
+
<ns1:CountryCode>US</ns1:CountryCode>
|
19
|
+
<ns1:PostalCode>98104</ns1:PostalCode>
|
20
|
+
<ns1:PhoneNumber>206-266-1000</ns1:PhoneNumber>
|
21
|
+
</ns1:DestinationAddress>
|
22
|
+
<ns1:FulfillmentOrderStatus>Complete</ns1:FulfillmentOrderStatus>
|
23
|
+
<ns1:StatusUpdatedDateTime>2007-08-03T16:00:00Z</ns1:StatusUpdatedDateTime>
|
24
|
+
</ns1:FulfillmentOrder>
|
25
|
+
<ns1:FulfillmentOrderItem>
|
26
|
+
<ns1:MerchantSKU>MSKU-00000001</ns1:MerchantSKU>
|
27
|
+
<ns1:MerchantFulfillmentOrderItemId>TEST-00000001-1</ns1:MerchantFulfillmentOrderItemId>
|
28
|
+
<ns1:Quantity>2</ns1:Quantity>
|
29
|
+
<ns1:CancelledQuantity>0</ns1:CancelledQuantity>
|
30
|
+
<ns1:UnfulfillableQuantity>0</ns1:UnfulfillableQuantity>
|
31
|
+
</ns1:FulfillmentOrderItem>
|
32
|
+
</ns1:GetFulfillmentOrderResult>
|
33
|
+
<ns1:ResponseMetadata>
|
34
|
+
<ns1:RequestId>963215ec-bec6-4ae0-84e0-19f5823ee33a</ns1:RequestId>
|
35
|
+
</ns1:ResponseMetadata>
|
36
|
+
</ns1:GetFulfillmentOrderResponse>
|
37
|
+
</soapenv:Body>
|
38
|
+
</soapenv:Envelope>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
|
3
|
+
xmlns:aws="http://webservices.amazon.com/AWSFault/2005-15-09">
|
4
|
+
<env:Body>
|
5
|
+
<env:Fault>
|
6
|
+
<faultcode>aws:Client.UnknownError</faultcode>
|
7
|
+
<faultstring>Something bad happened!</faultstring>
|
8
|
+
<detail>
|
9
|
+
<aws:RequestId xmlns:aws="http://webservices.amazon.com/AWSFault/2005-15-09">145b969c-23ec-41e4-a552-30e57fc2684f</aws:RequestId>
|
10
|
+
</detail>
|
11
|
+
</env:Fault>
|
12
|
+
</env:Body>
|
13
|
+
</env:Envelope>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
|
3
|
+
xmlns:aws="http://webservices.amazon.com/AWSFault/2005-15-09">
|
4
|
+
<env:Body>
|
5
|
+
<env:Fault>
|
6
|
+
<faultcode>aws:Client.InvalidParameterValue</faultcode>
|
7
|
+
<faultstring>Value #1337-1 for parameter MerchantFulfillmentOrderId is invalid. Reason: requested order not found.</faultstring>
|
8
|
+
<detail>
|
9
|
+
<aws:RequestId xmlns:aws="http://webservices.amazon.com/AWSFault/2005-15-09">145b969c-23ec-41e4-a552-30e57fc2684f</aws:RequestId>
|
10
|
+
</detail>
|
11
|
+
</env:Fault>
|
12
|
+
</env:Body>
|
13
|
+
</env:Envelope>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<Orders>
|
3
|
+
<Shipment>
|
4
|
+
<InvoiceNumber>AB12345</InvoiceNumber>
|
5
|
+
<WebgistixOrderNumber>67891</WebgistixOrderNumber>
|
6
|
+
<Method>UPS Ground</Method>
|
7
|
+
<DateShipped>10/25/2009</DateShipped>
|
8
|
+
<ShipmentTrackingNumber>1Z8E5A380396682872</ShipmentTrackingNumber>
|
9
|
+
</Shipment>
|
10
|
+
<Shipment>
|
11
|
+
<InvoiceNumber>XY4567</InvoiceNumber>
|
12
|
+
<ShipmentTrackingNumber>Not Shipped</ShipmentTrackingNumber>
|
13
|
+
</Shipment>
|
14
|
+
</Orders>
|
data/test/remote/amazon_test.rb
CHANGED
@@ -76,6 +76,18 @@ class RemoteAmazonTest < Test::Unit::TestCase
|
|
76
76
|
assert_equal 0, response.stock_levels['SETTLERS']
|
77
77
|
end
|
78
78
|
|
79
|
+
def test_fetch_tracking_numbers
|
80
|
+
response = @service.fetch_tracking_numbers(['123456']) # an actual order
|
81
|
+
assert response.success?
|
82
|
+
assert_equal Hash.new, response.tracking_numbers # no tracking numbers in testing
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_fetch_tracking_numbers_ignores_not_found
|
86
|
+
response = @service.fetch_tracking_numbers(['#1337-1'])
|
87
|
+
assert response.success?
|
88
|
+
assert_equal Hash.new, response.tracking_numbers
|
89
|
+
end
|
90
|
+
|
79
91
|
def test_valid_credentials
|
80
92
|
assert @service.valid_credentials?
|
81
93
|
end
|
@@ -125,10 +125,10 @@ class RemoteShipwireTest < Test::Unit::TestCase
|
|
125
125
|
end
|
126
126
|
|
127
127
|
def test_fetch_tracking_numbers
|
128
|
-
response = @shipwire.fetch_tracking_numbers
|
128
|
+
response = @shipwire.fetch_tracking_numbers(['123456'])
|
129
129
|
assert response.success?
|
130
130
|
assert response.test?
|
131
|
-
assert_equal Hash.new, response.tracking_numbers
|
131
|
+
assert_equal Hash.new, response.tracking_numbers # no tracking numbers in testing
|
132
132
|
end
|
133
133
|
|
134
134
|
def test_valid_credentials
|
@@ -63,15 +63,25 @@ class RemoteWebgistixTest < Test::Unit::TestCase
|
|
63
63
|
response = service.fulfill('123456', @address, @line_items, @options)
|
64
64
|
assert !response.success?
|
65
65
|
assert response.test?
|
66
|
-
assert_equal "
|
66
|
+
assert_equal "Invalid Credentials", response.message
|
67
67
|
end
|
68
68
|
|
69
69
|
def test_get_inventory
|
70
70
|
response = @service.fetch_stock_levels
|
71
71
|
assert response.success?
|
72
72
|
assert response.test?
|
73
|
-
assert_equal
|
74
|
-
assert_equal
|
73
|
+
assert_equal 90, response.stock_levels['WX-01-3022']
|
74
|
+
assert_equal 140, response.stock_levels['WX-04-1080']
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_fetch_tracking_numbers
|
78
|
+
response = @service.fetch_tracking_numbers([
|
79
|
+
'1254658', 'FAItest123', 'Flat Rate Test Order 4'
|
80
|
+
])
|
81
|
+
assert response.success?
|
82
|
+
assert_equal '4209073191018052136352154', response.tracking_numbers['1254658']
|
83
|
+
assert_equal '9101805213907472080032', response.tracking_numbers['Flat Rate Test Order 4']
|
84
|
+
assert_nil response.tracking_numbers['FAItest123'] # 'Not Shipped'
|
75
85
|
end
|
76
86
|
|
77
87
|
def test_valid_credentials
|
@@ -90,6 +90,49 @@ class AmazonTest < Test::Unit::TestCase
|
|
90
90
|
assert_equal 555, response.stock_levels['GN-02-02A']
|
91
91
|
end
|
92
92
|
|
93
|
+
def test_fetch_tracking_numbers
|
94
|
+
@service.expects(:ssl_post).twice.returns(
|
95
|
+
xml_fixture('amazon/tracking_response_1'),
|
96
|
+
xml_fixture('amazon/tracking_response_2')
|
97
|
+
)
|
98
|
+
|
99
|
+
response = @service.fetch_tracking_numbers(['TEST-00000001', 'TEST-00000002'])
|
100
|
+
assert response.success?
|
101
|
+
assert_equal 'UPS00000001', response.tracking_numbers['TEST-00000001']
|
102
|
+
assert_nil response.tracking_numbers['TEST-00000002']
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_fetch_tracking_numbers_ignores_not_found
|
106
|
+
response = mock('response')
|
107
|
+
response.stubs(:code).returns(500)
|
108
|
+
response.stubs(:message).returns('Internal Server Error')
|
109
|
+
response.stubs(:body).returns(xml_fixture('amazon/tracking_response_not_found'))
|
110
|
+
|
111
|
+
@service.expects(:ssl_post).times(3).
|
112
|
+
returns(xml_fixture('amazon/tracking_response_1')).
|
113
|
+
raises(ActiveMerchant::ResponseError.new(response)).
|
114
|
+
returns(xml_fixture('amazon/tracking_response_2'))
|
115
|
+
|
116
|
+
response = @service.fetch_tracking_numbers(['TEST-00000001', '#1337-1', 'TEST-00000002'])
|
117
|
+
assert response.success?
|
118
|
+
assert_equal 'UPS00000001', response.tracking_numbers['TEST-00000001']
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_fetch_tracking_numbers_aborts_on_error
|
122
|
+
response = mock('response')
|
123
|
+
response.stubs(:code).returns(500)
|
124
|
+
response.stubs(:message).returns('Internal Server Error')
|
125
|
+
response.stubs(:body).returns(xml_fixture('amazon/tracking_response_error'))
|
126
|
+
|
127
|
+
@service.expects(:ssl_post).twice.
|
128
|
+
returns(xml_fixture('amazon/tracking_response_1')).
|
129
|
+
raises(ActiveMerchant::ResponseError.new(response))
|
130
|
+
|
131
|
+
response = @service.fetch_tracking_numbers(['TEST-00000001', 'ERROR', 'TEST-00000002'])
|
132
|
+
assert !response.success?
|
133
|
+
assert_equal 'Something bad happened!', response.faultstring
|
134
|
+
end
|
135
|
+
|
93
136
|
def test_404_error
|
94
137
|
http_response = build_mock_response(response_from_404, "Not Found", "404")
|
95
138
|
@service.expects(:ssl_post).raises(ActiveMerchant::ResponseError.new(http_response))
|
@@ -62,10 +62,9 @@ class ShipwireTest < Test::Unit::TestCase
|
|
62
62
|
|
63
63
|
def test_no_tracking_numbers_available
|
64
64
|
@shipwire.expects(:ssl_post).returns(successful_empty_tracking_response)
|
65
|
-
response = @shipwire.fetch_tracking_numbers
|
65
|
+
response = @shipwire.fetch_tracking_numbers(['1234'])
|
66
66
|
assert response.success?
|
67
67
|
assert_equal Hash.new, response.tracking_numbers
|
68
|
-
|
69
68
|
end
|
70
69
|
|
71
70
|
def test_successful_tracking
|
@@ -73,7 +72,7 @@ class ShipwireTest < Test::Unit::TestCase
|
|
73
72
|
"2987" => "1ZW682E90326795080" }
|
74
73
|
|
75
74
|
@shipwire.expects(:ssl_post).returns(successful_tracking_response)
|
76
|
-
response = @shipwire.fetch_tracking_numbers
|
75
|
+
response = @shipwire.fetch_tracking_numbers(["2986", "2987"])
|
77
76
|
assert response.success?
|
78
77
|
assert_equal "3", response.params["total_orders"]
|
79
78
|
assert_equal "Test", response.params["status"]
|
@@ -84,7 +83,11 @@ class ShipwireTest < Test::Unit::TestCase
|
|
84
83
|
|
85
84
|
def test_successful_tracking_with_live_data
|
86
85
|
@shipwire.expects(:ssl_post).returns(successful_live_tracking_response)
|
87
|
-
response = @shipwire.fetch_tracking_numbers
|
86
|
+
response = @shipwire.fetch_tracking_numbers([
|
87
|
+
'21', '22', '23', '24', '25',
|
88
|
+
'26', '2581', '2576', '2593', '2598',
|
89
|
+
'2610', '2611', '2613', '2616', '2631'
|
90
|
+
])
|
88
91
|
assert response.success?
|
89
92
|
assert_equal "15", response.params["total_orders"]
|
90
93
|
assert_equal "0", response.params["status"]
|
@@ -99,6 +99,16 @@ class WebgistixTest < Test::Unit::TestCase
|
|
99
99
|
assert_equal 202, response.stock_levels['GN-00-01A']
|
100
100
|
assert_equal 199, response.stock_levels['GN-00-02A']
|
101
101
|
end
|
102
|
+
|
103
|
+
def test_tracking_numbers
|
104
|
+
@service.expects(:ssl_post).returns(xml_fixture('webgistix/tracking_response'))
|
105
|
+
|
106
|
+
response = @service.fetch_tracking_numbers(['AB12345', 'XY4567'])
|
107
|
+
assert response.success?
|
108
|
+
assert_equal WebgistixService::SUCCESS_MESSAGE, response.message
|
109
|
+
assert_equal '1Z8E5A380396682872', response.tracking_numbers['AB12345']
|
110
|
+
assert_nil response.tracking_numbers['XY4567']
|
111
|
+
end
|
102
112
|
|
103
113
|
def test_failed_login
|
104
114
|
@service.expects(:ssl_post).returns(invalid_login_response)
|
@@ -106,10 +116,10 @@ class WebgistixTest < Test::Unit::TestCase
|
|
106
116
|
response = @service.fulfill('123456', @address, @line_items, @options)
|
107
117
|
assert !response.success?
|
108
118
|
assert response.test?
|
109
|
-
assert_equal '
|
119
|
+
assert_equal 'Invalid Credentials', response.message
|
110
120
|
assert_nil response.params['order_id']
|
111
121
|
|
112
|
-
assert_equal '
|
122
|
+
assert_equal 'Invalid Credentials', response.params['error_0']
|
113
123
|
end
|
114
124
|
|
115
125
|
def test_garbage_response
|
@@ -132,6 +142,22 @@ class WebgistixTest < Test::Unit::TestCase
|
|
132
142
|
assert !@service.valid_credentials?
|
133
143
|
end
|
134
144
|
|
145
|
+
def test_duplicate_response_is_treated_as_success
|
146
|
+
response = stub(:code => 200, :body => duplicate_response, :message => '')
|
147
|
+
Net::HTTP.any_instance.stubs(:post).raises(ActiveMerchant::ConnectionError).returns(response)
|
148
|
+
|
149
|
+
response = @service.fulfill('123456', @address, @line_items, @options)
|
150
|
+
assert response.success?
|
151
|
+
assert response.test?
|
152
|
+
assert_equal WebgistixService::DUPLICATE_MESSAGE, response.message
|
153
|
+
assert response.params['duplicate']
|
154
|
+
assert_nil response.params['order_id']
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_ensure_gateway_uses_safe_retry
|
158
|
+
assert @service.retry_safe
|
159
|
+
end
|
160
|
+
|
135
161
|
private
|
136
162
|
def minimal_successful_response
|
137
163
|
'<Completed><Success>True</Success></Completed>'
|
@@ -142,11 +168,11 @@ class WebgistixTest < Test::Unit::TestCase
|
|
142
168
|
end
|
143
169
|
|
144
170
|
def invalid_login_response
|
145
|
-
'<Error>
|
171
|
+
'<Errors><Error>Invalid Credentials</Error></Errors>'
|
146
172
|
end
|
147
173
|
|
148
174
|
def failure_response
|
149
|
-
'<Error>No Address Line 1</Error><Error>Unknown ItemID: testitem</Error><Error>Unknown ItemID: WX-01-1000</Error>'
|
175
|
+
'<Errors><Error>No Address Line 1</Error><Error>Unknown ItemID: testitem</Error><Error>Unknown ItemID: WX-01-1000</Error></Errors>'
|
150
176
|
end
|
151
177
|
|
152
178
|
def garbage_response
|
@@ -159,4 +185,8 @@ class WebgistixTest < Test::Unit::TestCase
|
|
159
185
|
'<Item><ItemID>GN-00-02A</ItemID><ItemQty>199</ItemQty></Item>' +
|
160
186
|
'</InventoryXML>'
|
161
187
|
end
|
188
|
+
|
189
|
+
def duplicate_response
|
190
|
+
'<Completed><Success>Duplicate</Success></Completed>'
|
191
|
+
end
|
162
192
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_fulfillment
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.0.
|
9
|
+
- 1
|
10
|
+
version: 1.0.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Cody Fauser
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2010-
|
19
|
+
date: 2010-12-13 00:00:00 -05:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
requirement: &id001 !ruby/object:Gem::Requirement
|
26
26
|
none: false
|
27
27
|
requirements:
|
28
|
-
- -
|
28
|
+
- - ">="
|
29
29
|
- !ruby/object:Gem::Version
|
30
30
|
hash: 7
|
31
31
|
segments:
|
@@ -88,6 +88,11 @@ files:
|
|
88
88
|
- test/fixtures/xml/amazon/inventory_list_response.xml
|
89
89
|
- test/fixtures/xml/amazon/inventory_list_response_with_next_1.xml
|
90
90
|
- test/fixtures/xml/amazon/inventory_list_response_with_next_2.xml
|
91
|
+
- test/fixtures/xml/amazon/tracking_response_1.xml
|
92
|
+
- test/fixtures/xml/amazon/tracking_response_2.xml
|
93
|
+
- test/fixtures/xml/amazon/tracking_response_error.xml
|
94
|
+
- test/fixtures/xml/amazon/tracking_response_not_found.xml
|
95
|
+
- test/fixtures/xml/webgistix/tracking_response.xml
|
91
96
|
- test/remote/amazon_test.rb
|
92
97
|
- test/remote/shipwire_test.rb
|
93
98
|
- test/remote/webgistix_test.rb
|
@@ -101,8 +106,8 @@ homepage: http://github.com/shopify/active_fulfillment
|
|
101
106
|
licenses: []
|
102
107
|
|
103
108
|
post_install_message:
|
104
|
-
rdoc_options:
|
105
|
-
|
109
|
+
rdoc_options: []
|
110
|
+
|
106
111
|
require_paths:
|
107
112
|
- lib
|
108
113
|
required_ruby_version: !ruby/object:Gem::Requirement
|