active_fulfillment 2.0.2 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +4 -0
- data/lib/active_fulfillment/fulfillment/service.rb +13 -6
- data/lib/active_fulfillment/fulfillment/services/amazon.rb +62 -51
- data/lib/active_fulfillment/fulfillment/services/amazon_mws.rb +35 -23
- data/lib/active_fulfillment/fulfillment/services/shipwire.rb +8 -6
- data/lib/active_fulfillment/fulfillment/services/webgistix.rb +76 -66
- data/lib/active_fulfillment/fulfillment/version.rb +1 -1
- data/test/remote/amazon_mws_test.rb +17 -10
- data/test/remote/amazon_test.rb +22 -15
- data/test/remote/shipwire_test.rb +36 -28
- data/test/remote/webgistix_test.rb +25 -16
- data/test/unit/services/amazon_mws_test.rb +36 -11
- data/test/unit/services/amazon_test.rb +46 -36
- data/test/unit/services/shipwire_test.rb +22 -22
- data/test/unit/services/webgistix_test.rb +45 -33
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cba1390bb08c4c010debba62180ac2f00b2c1d33
|
4
|
+
data.tar.gz: e2b321fd688279d43ddc20127de4a9640c78cc1e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2915b119a9aa6b85050b6db4942680a773a7a9b992c5850e8d79836a8abfb9dde3396d7e8c1f91ca08a62b5ab782973f09586a1c4d8b05d1a8404e03ab0b2fc9
|
7
|
+
data.tar.gz: 05b69f636a0b59eefe4ae75f677cfc7ed6f5fe9cf567bfb60ed7cd14763d0d749df31ce5b2a8bf107f6751b186334ba5b62cfe183f8660f10c2a5bf3e23c65eb
|
data/CHANGELOG
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
= ActiveFulfillment CHANGELOG
|
2
2
|
|
3
|
+
== Version 2.1.0
|
4
|
+
|
5
|
+
* Added fetch_tracking_data methods which returns tracking_companies and tracking_urls if available in addition to tracking_numbers for each service
|
6
|
+
|
3
7
|
== Version 2.0.0 (Jan 5, 2013)
|
4
8
|
|
5
9
|
* API Change on tracking numbers, returns array instead of single string [csaunders]
|
@@ -4,18 +4,18 @@ module ActiveMerchant
|
|
4
4
|
|
5
5
|
include RequiresParameters
|
6
6
|
include PostsData
|
7
|
-
|
7
|
+
|
8
8
|
def initialize(options = {})
|
9
9
|
check_test_mode(options)
|
10
|
-
|
10
|
+
|
11
11
|
@options = {}
|
12
12
|
@options.update(options)
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
def test_mode?
|
16
16
|
false
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
def test?
|
20
20
|
@options[:test] || Base.mode == :test
|
21
21
|
end
|
@@ -34,6 +34,13 @@ module ActiveMerchant
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def fetch_tracking_numbers(order_ids, options = {})
|
37
|
+
response = fetch_tracking_data(order_ids, options)
|
38
|
+
response.params.delete('tracking_companies')
|
39
|
+
response.params.delete('tracking_urls')
|
40
|
+
response
|
41
|
+
end
|
42
|
+
|
43
|
+
def fetch_tracking_data(order_ids, options = {})
|
37
44
|
raise NotImplementedError.new("Subclasses must implement")
|
38
45
|
end
|
39
46
|
|
@@ -44,7 +51,7 @@ module ActiveMerchant
|
|
44
51
|
def test_mode?
|
45
52
|
raise NotImplementedError.new("Subclasses must implement")
|
46
53
|
end
|
47
|
-
|
54
|
+
|
48
55
|
private
|
49
56
|
def check_test_mode(options)
|
50
57
|
if options[:test] and not test_mode?
|
@@ -53,4 +60,4 @@ module ActiveMerchant
|
|
53
60
|
end
|
54
61
|
end
|
55
62
|
end
|
56
|
-
end
|
63
|
+
end
|
@@ -13,16 +13,16 @@ module ActiveMerchant
|
|
13
13
|
:inventory => {
|
14
14
|
:url => 'https://fba-inventory.amazonaws.com',
|
15
15
|
:xmlns => 'http://fba-inventory.amazonaws.com/doc/2009-07-31/',
|
16
|
-
:version => '2009-07-31'
|
16
|
+
:version => '2009-07-31'
|
17
17
|
}
|
18
18
|
}
|
19
|
-
|
20
|
-
SUCCESS, FAILURE, ERROR = 'Accepted', 'Failure', 'Error'
|
19
|
+
|
20
|
+
SUCCESS, FAILURE, ERROR = 'Accepted', 'Failure', 'Error'
|
21
21
|
MESSAGES = {
|
22
22
|
:status => {
|
23
23
|
'Accepted' => 'Success',
|
24
24
|
'Failure' => 'Failed',
|
25
|
-
'Error' => 'An error occurred'
|
25
|
+
'Error' => 'An error occurred'
|
26
26
|
},
|
27
27
|
:create => {
|
28
28
|
'Accepted' => 'Successfully submitted the order',
|
@@ -33,10 +33,10 @@ module ActiveMerchant
|
|
33
33
|
'Accepted' => 'Successfully submitted request',
|
34
34
|
'Failure' => 'Failed to submit request',
|
35
35
|
'Error' => 'An error occurred while submitting request'
|
36
|
-
|
36
|
+
|
37
37
|
}
|
38
38
|
}
|
39
|
-
|
39
|
+
|
40
40
|
ENV_NAMESPACES = { 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
|
41
41
|
'xmlns:env' => 'http://schemas.xmlsoap.org/soap/envelope/',
|
42
42
|
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
|
@@ -48,8 +48,8 @@ module ActiveMerchant
|
|
48
48
|
"xmlns:aws" => "http://security.amazonaws.com/doc/2007-01-01/"
|
49
49
|
}
|
50
50
|
|
51
|
-
@@digest = OpenSSL::Digest
|
52
|
-
|
51
|
+
@@digest = OpenSSL::Digest.new("sha1")
|
52
|
+
|
53
53
|
OPERATIONS = {
|
54
54
|
:outbound => {
|
55
55
|
:status => 'GetServiceStatus',
|
@@ -63,37 +63,37 @@ module ActiveMerchant
|
|
63
63
|
:list_next => 'ListUpdatedInventorySupplyByNextToken'
|
64
64
|
}
|
65
65
|
}
|
66
|
-
|
66
|
+
|
67
67
|
# The first is the label, and the last is the code
|
68
68
|
# Standard: 3-5 business days
|
69
69
|
# Expedited: 2 business days
|
70
70
|
# Priority: 1 business day
|
71
71
|
def self.shipping_methods
|
72
|
-
[
|
72
|
+
[
|
73
73
|
[ 'Standard Shipping', 'Standard' ],
|
74
74
|
[ 'Expedited Shipping', 'Expedited' ],
|
75
75
|
[ 'Priority Shipping', 'Priority' ]
|
76
76
|
].inject(ActiveSupport::OrderedHash.new){|h, (k,v)| h[k] = v; h}
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
def self.sign(aws_secret_access_key, auth_string)
|
80
80
|
Base64.encode64(OpenSSL::HMAC.digest(@@digest, aws_secret_access_key, auth_string)).strip
|
81
81
|
end
|
82
|
-
|
82
|
+
|
83
83
|
def initialize(options = {})
|
84
84
|
requires!(options, :login, :password)
|
85
85
|
super
|
86
86
|
end
|
87
|
-
|
87
|
+
|
88
88
|
def status
|
89
89
|
commit :outbound, :status, build_status_request
|
90
90
|
end
|
91
91
|
|
92
|
-
def fulfill(order_id, shipping_address, line_items, options = {})
|
92
|
+
def fulfill(order_id, shipping_address, line_items, options = {})
|
93
93
|
requires!(options, :order_date, :comment, :shipping_method)
|
94
94
|
commit :outbound, :create, build_fulfillment_request(order_id, shipping_address, line_items, options)
|
95
95
|
end
|
96
|
-
|
96
|
+
|
97
97
|
def fetch_current_orders
|
98
98
|
commit :outbound, :list, build_get_current_fulfillment_orders_request
|
99
99
|
end
|
@@ -110,35 +110,30 @@ module ActiveMerchant
|
|
110
110
|
next_page.stock_levels.merge!(response.stock_levels)
|
111
111
|
response = next_page
|
112
112
|
end
|
113
|
-
|
113
|
+
|
114
114
|
response
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
118
|
-
def
|
118
|
+
def fetch_tracking_data(order_ids, options = {})
|
119
119
|
order_ids.inject(nil) do |previous, o_id|
|
120
120
|
response = commit :outbound, :tracking, build_tracking_request(o_id, options)
|
121
|
+
return response unless response.success?
|
121
122
|
|
122
|
-
if
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
:tracking_numbers => {}
|
127
|
-
})
|
128
|
-
else
|
129
|
-
return response
|
130
|
-
end
|
123
|
+
if previous
|
124
|
+
response.tracking_numbers.merge!(previous.tracking_numbers)
|
125
|
+
response.tracking_companies.merge!(previous.tracking_companies)
|
126
|
+
response.tracking_urls.merge!(previous.tracking_urls)
|
131
127
|
end
|
132
128
|
|
133
|
-
response.tracking_numbers.merge!(previous.tracking_numbers) if previous
|
134
129
|
response
|
135
130
|
end
|
136
131
|
end
|
137
|
-
|
132
|
+
|
138
133
|
def valid_credentials?
|
139
134
|
status.success?
|
140
135
|
end
|
141
|
-
|
136
|
+
|
142
137
|
def test_mode?
|
143
138
|
false
|
144
139
|
end
|
@@ -157,14 +152,14 @@ module ActiveMerchant
|
|
157
152
|
end
|
158
153
|
xml.target!
|
159
154
|
end
|
160
|
-
|
155
|
+
|
161
156
|
def build_status_request
|
162
157
|
request = OPERATIONS[:outbound][:status]
|
163
158
|
soap_request(request) do |xml|
|
164
159
|
xml.tag! request, { 'xmlns' => SERVICES[:outbound][:xmlns] }
|
165
160
|
end
|
166
161
|
end
|
167
|
-
|
162
|
+
|
168
163
|
def build_get_current_fulfillment_orders_request
|
169
164
|
request = OPERATIONS[:outbound][:list]
|
170
165
|
soap_request(request) do |xml|
|
@@ -184,7 +179,7 @@ module ActiveMerchant
|
|
184
179
|
xml.tag! "DisplayableOrderDateTime", options[:order_date].strftime("%Y-%m-%dT%H:%M:%SZ")
|
185
180
|
xml.tag! "DisplayableOrderComment", options[:comment]
|
186
181
|
xml.tag! "ShippingSpeedCategory", options[:shipping_method]
|
187
|
-
|
182
|
+
|
188
183
|
add_address(xml, shipping_address)
|
189
184
|
add_items(xml, line_items)
|
190
185
|
end
|
@@ -236,13 +231,13 @@ module ActiveMerchant
|
|
236
231
|
login = @options[:login]
|
237
232
|
timestamp = "#{Time.now.utc.strftime("%Y-%m-%dT%H:%M:%S")}Z"
|
238
233
|
signature = self.class.sign(@options[:password], "#{request}#{timestamp}")
|
239
|
-
|
234
|
+
|
240
235
|
xml.tag! 'aws:AWSAccessKeyId', login, AWS_SECURITY_ATTRIBUTES
|
241
236
|
xml.tag! 'aws:Signature', signature, AWS_SECURITY_ATTRIBUTES
|
242
237
|
xml.tag! 'aws:Timestamp', timestamp, AWS_SECURITY_ATTRIBUTES
|
243
238
|
end
|
244
|
-
|
245
|
-
def add_items(xml, line_items)
|
239
|
+
|
240
|
+
def add_items(xml, line_items)
|
246
241
|
Array(line_items).each_with_index do |item, index|
|
247
242
|
xml.tag! 'Item' do
|
248
243
|
xml.tag! 'MerchantSKU', item[:sku]
|
@@ -253,9 +248,9 @@ module ActiveMerchant
|
|
253
248
|
end
|
254
249
|
end
|
255
250
|
end
|
256
|
-
|
251
|
+
|
257
252
|
def add_address(xml, address)
|
258
|
-
xml.tag! 'DestinationAddress' do
|
253
|
+
xml.tag! 'DestinationAddress' do
|
259
254
|
xml.tag! 'Name', address[:name]
|
260
255
|
xml.tag! 'Line1', address[:address1]
|
261
256
|
xml.tag! 'Line2', address[:address2] unless address[:address2].blank?
|
@@ -267,26 +262,34 @@ module ActiveMerchant
|
|
267
262
|
xml.tag! 'PhoneNumber', address[:phone] unless address[:phone].blank?
|
268
263
|
end
|
269
264
|
end
|
270
|
-
|
265
|
+
|
271
266
|
def commit(service, op, body)
|
272
267
|
data = ssl_post(SERVICES[service][:url], body, 'Content-Type' => 'application/soap+xml; charset=utf-8')
|
273
|
-
response = parse_response(service, op, data)
|
268
|
+
response = parse_response(service, op, data)
|
274
269
|
Response.new(success?(response), message_from(response), response)
|
275
|
-
rescue ActiveMerchant::ResponseError => e
|
270
|
+
rescue ActiveMerchant::ResponseError => e
|
271
|
+
handle_error(e)
|
272
|
+
end
|
273
|
+
|
274
|
+
def handle_error(e)
|
276
275
|
response = parse_error(e.response)
|
277
|
-
|
276
|
+
if response.fetch(:faultstring, "") =~ /Reason: requested order not found./
|
277
|
+
Response.new(true, nil, {:status => SUCCESS, :tracking_numbers => {}, :tracking_companies => {}, :tracking_urls => {}})
|
278
|
+
else
|
279
|
+
Response.new(false, message_from(response), response)
|
280
|
+
end
|
278
281
|
end
|
279
|
-
|
282
|
+
|
280
283
|
def success?(response)
|
281
284
|
response[:response_status] == SUCCESS
|
282
285
|
end
|
283
|
-
|
286
|
+
|
284
287
|
def message_from(response)
|
285
288
|
response[:response_comment]
|
286
289
|
end
|
287
|
-
|
290
|
+
|
288
291
|
def parse_response(service, op, xml)
|
289
|
-
begin
|
292
|
+
begin
|
290
293
|
document = REXML::Document.new(xml)
|
291
294
|
rescue REXML::ParseException
|
292
295
|
return {:success => FAILURE}
|
@@ -306,12 +309,12 @@ module ActiveMerchant
|
|
306
309
|
raise ArgumentError, "Unknown service #{service}"
|
307
310
|
end
|
308
311
|
end
|
309
|
-
|
312
|
+
|
310
313
|
def parse_fulfillment_response(op, document)
|
311
314
|
response = {}
|
312
315
|
action = OPERATIONS[:outbound][op]
|
313
316
|
node = REXML::XPath.first(document, "//ns1:#{action}Response")
|
314
|
-
|
317
|
+
|
315
318
|
response[:response_status] = SUCCESS
|
316
319
|
response[:response_comment] = MESSAGES[op][SUCCESS]
|
317
320
|
response
|
@@ -334,10 +337,12 @@ module ActiveMerchant
|
|
334
337
|
response[:response_status] = SUCCESS
|
335
338
|
response
|
336
339
|
end
|
337
|
-
|
340
|
+
|
338
341
|
def parse_tracking_response(document)
|
339
342
|
response = {}
|
340
343
|
response[:tracking_numbers] = {}
|
344
|
+
response[:tracking_companies] = {}
|
345
|
+
response[:tracking_urls] = {}
|
341
346
|
|
342
347
|
track_node = REXML::XPath.first(document, '//ns1:FulfillmentShipmentPackage/ns1:TrackingNumber')
|
343
348
|
if track_node
|
@@ -345,10 +350,16 @@ module ActiveMerchant
|
|
345
350
|
response[:tracking_numbers][id_node.text] = [track_node.text]
|
346
351
|
end
|
347
352
|
|
353
|
+
company_node = REXML::XPath.first(document, '//ns1:FulfillmentShipmentPackage/ns1:CarrierCode')
|
354
|
+
if company_node
|
355
|
+
id_node = REXML::XPath.first(document, '//ns1:MerchantFulfillmentOrderId')
|
356
|
+
response[:tracking_companies][id_node.text] = [company_node.text]
|
357
|
+
end
|
358
|
+
|
348
359
|
response[:response_status] = SUCCESS
|
349
360
|
response
|
350
361
|
end
|
351
|
-
|
362
|
+
|
352
363
|
def parse_error(http_response)
|
353
364
|
response = {}
|
354
365
|
response[:http_code] = http_response.code
|
@@ -361,7 +372,7 @@ module ActiveMerchant
|
|
361
372
|
failed_node = node.find_first_recursive {|sib| sib.name == "Fault" }
|
362
373
|
faultcode_node = node.find_first_recursive {|sib| sib.name == "faultcode" }
|
363
374
|
faultstring_node = node.find_first_recursive {|sib| sib.name == "faultstring" }
|
364
|
-
|
375
|
+
|
365
376
|
response[:response_status] = FAILURE
|
366
377
|
response[:faultcode] = faultcode_node ? faultcode_node.text : ""
|
367
378
|
response[:faultstring] = faultstring_node ? faultstring_node.text : ""
|
@@ -373,6 +384,6 @@ module ActiveMerchant
|
|
373
384
|
response[:response_comment] = "#{response[:http_code]}: #{response[:http_message]}"
|
374
385
|
response
|
375
386
|
end
|
376
|
-
end
|
387
|
+
end
|
377
388
|
end
|
378
389
|
end
|
@@ -20,7 +20,7 @@ module ActiveMerchant
|
|
20
20
|
:status => {
|
21
21
|
'Accepted' => 'Success',
|
22
22
|
'Failure' => 'Failed',
|
23
|
-
'Error' => 'An error occurred'
|
23
|
+
'Error' => 'An error occurred'
|
24
24
|
},
|
25
25
|
:create => {
|
26
26
|
'Accepted' => 'Successfully submitted the order',
|
@@ -31,7 +31,7 @@ module ActiveMerchant
|
|
31
31
|
'Accepted' => 'Successfully submitted request',
|
32
32
|
'Failure' => 'Failed to submit request',
|
33
33
|
'Error' => 'An error occurred while submitting request'
|
34
|
-
|
34
|
+
|
35
35
|
}
|
36
36
|
}
|
37
37
|
|
@@ -98,7 +98,7 @@ module ActiveMerchant
|
|
98
98
|
# Expedited: 2 business days
|
99
99
|
# Priority: 1 business day
|
100
100
|
def self.shipping_methods
|
101
|
-
[
|
101
|
+
[
|
102
102
|
[ 'Standard Shipping', 'Standard' ],
|
103
103
|
[ 'Expedited Shipping', 'Expedited' ],
|
104
104
|
[ 'Priority Shipping', 'Priority' ]
|
@@ -146,23 +146,18 @@ module ActiveMerchant
|
|
146
146
|
response
|
147
147
|
end
|
148
148
|
|
149
|
-
def
|
149
|
+
def fetch_tracking_data(order_ids, options = {})
|
150
150
|
order_ids.reduce(nil) do |previous, order_id|
|
151
|
-
|
152
|
-
|
153
|
-
if !response.success?
|
154
|
-
if response.faultstring.match(/^Requested order \'.+\' not found$/)
|
155
|
-
response = Response.new(true, nil, {
|
156
|
-
:status => SUCCESS,
|
157
|
-
:tracking_numbers => {}
|
158
|
-
})
|
159
|
-
else
|
160
|
-
return response
|
161
|
-
end
|
162
|
-
end
|
151
|
+
response = commit :post, :outbound, :tracking, build_tracking_request(order_id, options)
|
152
|
+
return response if !response.success?
|
163
153
|
|
164
|
-
|
165
|
-
response
|
154
|
+
if previous
|
155
|
+
response.tracking_numbers.merge!(previous.tracking_numbers)
|
156
|
+
response.tracking_companies.merge!(previous.tracking_companies)
|
157
|
+
response.tracking_urls.merge!(previous.tracking_urls)
|
158
|
+
end
|
159
|
+
|
160
|
+
response
|
166
161
|
end
|
167
162
|
end
|
168
163
|
|
@@ -188,8 +183,16 @@ module ActiveMerchant
|
|
188
183
|
response = parse_response(service, op, data)
|
189
184
|
Response.new(success?(response), message_from(response), response)
|
190
185
|
rescue ActiveMerchant::ResponseError => e
|
186
|
+
handle_error(e)
|
187
|
+
end
|
188
|
+
|
189
|
+
def handle_error(e)
|
191
190
|
response = parse_error(e.response)
|
192
|
-
|
191
|
+
if response.fetch(:faultstring, "").match(/^Requested order \'.+\' not found$/)
|
192
|
+
Response.new(true, nil, {:status => SUCCESS, :tracking_numbers => {}, :tracking_companies => {}, :tracking_urls => {}})
|
193
|
+
else
|
194
|
+
Response.new(false, message_from(response), response)
|
195
|
+
end
|
193
196
|
end
|
194
197
|
|
195
198
|
def success?(response)
|
@@ -227,6 +230,8 @@ module ActiveMerchant
|
|
227
230
|
def parse_tracking_response(document)
|
228
231
|
response = {}
|
229
232
|
response[:tracking_numbers] = {}
|
233
|
+
response[:tracking_companies] = {}
|
234
|
+
response[:tracking_urls] = {}
|
230
235
|
|
231
236
|
tracking_numbers = REXML::XPath.match(document, "//FulfillmentShipmentPackage/member/TrackingNumber")
|
232
237
|
if tracking_numbers.present?
|
@@ -234,6 +239,12 @@ module ActiveMerchant
|
|
234
239
|
response[:tracking_numbers][order_id] = tracking_numbers.map{ |t| t.text.strip }
|
235
240
|
end
|
236
241
|
|
242
|
+
tracking_companies = REXML::XPath.match(document, "//FulfillmentShipmentPackage/member/CarrierCode")
|
243
|
+
if tracking_companies.present?
|
244
|
+
order_id = REXML::XPath.first(document, "//FulfillmentOrder/SellerFulfillmentOrderId").text.strip
|
245
|
+
response[:tracking_companies][order_id] = tracking_companies.map{ |t| t.text.strip }
|
246
|
+
end
|
247
|
+
|
237
248
|
response[:response_status] = SUCCESS
|
238
249
|
response
|
239
250
|
end
|
@@ -251,10 +262,10 @@ module ActiveMerchant
|
|
251
262
|
|
252
263
|
response[:stock_levels][params['SellerSKU']] = params['InStockSupplyQuantity'].to_i
|
253
264
|
end
|
254
|
-
|
265
|
+
|
255
266
|
next_token = REXML::XPath.first(document, '//NextToken')
|
256
267
|
response[:next_token] = next_token ? next_token.text : nil
|
257
|
-
|
268
|
+
|
258
269
|
response[:response_status] = SUCCESS
|
259
270
|
response
|
260
271
|
end
|
@@ -312,7 +323,7 @@ module ActiveMerchant
|
|
312
323
|
end
|
313
324
|
|
314
325
|
def md5_content(content)
|
315
|
-
Base64.encode64(OpenSSL::Digest
|
326
|
+
Base64.encode64(OpenSSL::Digest.new('md5', content).digest).chomp
|
316
327
|
end
|
317
328
|
|
318
329
|
def build_query(query_params)
|
@@ -347,7 +358,7 @@ module ActiveMerchant
|
|
347
358
|
:ShippingSpeedCategory => options[:shipping_method]
|
348
359
|
}
|
349
360
|
params[:DisplayableOrderComment] = options[:comment] if options[:comment]
|
350
|
-
|
361
|
+
|
351
362
|
request = build_basic_api_query(params.merge(options))
|
352
363
|
request = request.merge build_address(shipping_address)
|
353
364
|
request = request.merge build_items(line_items)
|
@@ -400,6 +411,7 @@ module ActiveMerchant
|
|
400
411
|
|
401
412
|
def build_address(address)
|
402
413
|
requires!(address, :name, :address1, :city, :state, :country, :zip)
|
414
|
+
address[:zip].upcase!
|
403
415
|
ary = address.map{ |key, value| [LOOKUPS[:destination_address][key], value] if LOOKUPS[:destination_address].include?(key) && value.present? }
|
404
416
|
Hash[ary.compact]
|
405
417
|
end
|
@@ -4,9 +4,9 @@ module ActiveMerchant
|
|
4
4
|
module Fulfillment
|
5
5
|
class ShipwireService < Service
|
6
6
|
|
7
|
-
SERVICE_URLS = { :fulfillment
|
8
|
-
:inventory
|
9
|
-
:tracking
|
7
|
+
SERVICE_URLS = { :fulfillment => 'https://api.shipwire.com/exec/FulfillmentServices.php',
|
8
|
+
:inventory => 'https://api.shipwire.com/exec/InventoryServices.php',
|
9
|
+
:tracking => 'https://api.shipwire.com/exec/TrackingServices.php'
|
10
10
|
}
|
11
11
|
|
12
12
|
SCHEMA_URLS = { :fulfillment => 'http://www.shipwire.com/exec/download/OrderList.dtd',
|
@@ -57,7 +57,7 @@ module ActiveMerchant
|
|
57
57
|
commit :inventory, build_inventory_request(options)
|
58
58
|
end
|
59
59
|
|
60
|
-
def
|
60
|
+
def fetch_tracking_data(order_ids, options = {})
|
61
61
|
commit :tracking, build_tracking_request(order_ids)
|
62
62
|
end
|
63
63
|
|
@@ -225,8 +225,10 @@ module ActiveMerchant
|
|
225
225
|
end
|
226
226
|
|
227
227
|
def parse_tracking_response(xml)
|
228
|
-
response =
|
228
|
+
response = {}
|
229
229
|
response[:tracking_numbers] = {}
|
230
|
+
response[:tracking_companies] = {}
|
231
|
+
response[:tracking_urls] = {}
|
230
232
|
|
231
233
|
document = REXML::Document.new(xml)
|
232
234
|
document.root.elements.each do |node|
|
@@ -236,7 +238,7 @@ module ActiveMerchant
|
|
236
238
|
response[:tracking_numbers][node.attributes['id']] = [tracking_number]
|
237
239
|
|
238
240
|
tracking_company = node.elements['TrackingNumber'].attributes['carrier']
|
239
|
-
response[:
|
241
|
+
response[:tracking_companies][node.attributes['id']] = tracking_company.strip if tracking_company
|
240
242
|
|
241
243
|
tracking_url = node.elements['TrackingNumber'].attributes['href']
|
242
244
|
response[:tracking_urls][node.attributes['id']] = [tracking_url.strip] if tracking_url
|