active_shipping 0.12.4 → 0.12.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/active_shipping.rb +2 -1
- data/lib/active_shipping/shipping/base.rb +2 -2
- data/lib/active_shipping/shipping/carrier.rb +16 -13
- data/lib/active_shipping/shipping/carriers/benchmark_carrier.rb +3 -4
- data/lib/active_shipping/shipping/carriers/bogus_carrier.rb +1 -3
- data/lib/active_shipping/shipping/carriers/canada_post.rb +33 -44
- data/lib/active_shipping/shipping/carriers/canada_post_pws.rb +72 -81
- data/lib/active_shipping/shipping/carriers/fedex.rb +118 -109
- data/lib/active_shipping/shipping/carriers/kunaki.rb +33 -32
- data/lib/active_shipping/shipping/carriers/new_zealand_post.rb +9 -16
- data/lib/active_shipping/shipping/carriers/shipwire.rb +36 -35
- data/lib/active_shipping/shipping/carriers/stamps.rb +39 -51
- data/lib/active_shipping/shipping/carriers/ups.rb +280 -116
- data/lib/active_shipping/shipping/carriers/ups.rb.orig +456 -0
- data/lib/active_shipping/shipping/carriers/usps.rb +145 -100
- data/lib/active_shipping/shipping/carriers/usps.rb.orig +616 -0
- data/lib/active_shipping/shipping/errors.rb +1 -1
- data/lib/active_shipping/shipping/label_response.rb +25 -0
- data/lib/active_shipping/shipping/location.rb +18 -16
- data/lib/active_shipping/shipping/package.rb +51 -54
- data/lib/active_shipping/shipping/rate_estimate.rb +10 -12
- data/lib/active_shipping/shipping/rate_response.rb +3 -7
- data/lib/active_shipping/shipping/response.rb +6 -9
- data/lib/active_shipping/shipping/shipment_event.rb +2 -4
- data/lib/active_shipping/shipping/shipment_packer.rb +32 -17
- data/lib/active_shipping/shipping/shipping_response.rb +2 -4
- data/lib/active_shipping/shipping/tracking_response.rb +3 -5
- data/lib/active_shipping/version.rb +1 -1
- data/lib/vendor/quantified/lib/quantified/attribute.rb +79 -80
- data/lib/vendor/quantified/lib/quantified/length.rb +5 -5
- data/lib/vendor/quantified/lib/quantified/mass.rb +4 -4
- data/lib/vendor/quantified/test/length_test.rb +19 -15
- data/lib/vendor/quantified/test/mass_test.rb +14 -14
- data/lib/vendor/quantified/test/test_helper.rb +1 -2
- data/lib/vendor/test_helper.rb +0 -1
- data/lib/vendor/xml_node/benchmark/bench_generation.rb +2 -4
- data/lib/vendor/xml_node/lib/xml_node.rb +54 -55
- data/lib/vendor/xml_node/test/test_generating.rb +23 -28
- data/lib/vendor/xml_node/test/test_parsing.rb +5 -8
- metadata +6 -25
- checksums.yaml.gz.sig +0 -1
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -0
@@ -4,29 +4,28 @@
|
|
4
4
|
require 'date'
|
5
5
|
module ActiveMerchant
|
6
6
|
module Shipping
|
7
|
-
|
8
7
|
# :key is your developer API key
|
9
8
|
# :password is your API password
|
10
9
|
# :account is your FedEx account number
|
11
10
|
# :login is your meter number
|
12
11
|
class FedEx < Carrier
|
13
12
|
self.retry_safe = true
|
14
|
-
|
13
|
+
|
15
14
|
cattr_reader :name
|
16
15
|
@@name = "FedEx"
|
17
|
-
|
16
|
+
|
18
17
|
TEST_URL = 'https://gatewaybeta.fedex.com:443/xml'
|
19
18
|
LIVE_URL = 'https://gateway.fedex.com:443/xml'
|
20
|
-
|
21
|
-
|
19
|
+
|
20
|
+
CARRIER_CODES = {
|
22
21
|
"fedex_ground" => "FDXG",
|
23
22
|
"fedex_express" => "FDXE"
|
24
23
|
}
|
25
24
|
|
26
25
|
DELIVERY_ADDRESS_NODE_NAMES = %w(DestinationAddress ActualDeliveryAddress)
|
27
26
|
SHIPPER_ADDRESS_NODE_NAMES = %w(ShipperAddress)
|
28
|
-
|
29
|
-
|
27
|
+
|
28
|
+
SERVICE_TYPES = {
|
30
29
|
"PRIORITY_OVERNIGHT" => "FedEx Priority Overnight",
|
31
30
|
"PRIORITY_OVERNIGHT_SATURDAY_DELIVERY" => "FedEx Priority Overnight Saturday Delivery",
|
32
31
|
"FEDEX_2_DAY" => "FedEx 2 Day",
|
@@ -55,7 +54,7 @@ module ActiveMerchant
|
|
55
54
|
"FEDEX_FREIGHT_ECONOMY" => "FedEx Freight Economy"
|
56
55
|
}
|
57
56
|
|
58
|
-
|
57
|
+
PACKAGE_TYPES = {
|
59
58
|
"fedex_envelope" => "FEDEX_ENVELOPE",
|
60
59
|
"fedex_pak" => "FEDEX_PAK",
|
61
60
|
"fedex_box" => "FEDEX_BOX",
|
@@ -65,7 +64,7 @@ module ActiveMerchant
|
|
65
64
|
"your_packaging" => "YOUR_PACKAGING"
|
66
65
|
}
|
67
66
|
|
68
|
-
|
67
|
+
DROPOFF_TYPES = {
|
69
68
|
'regular_pickup' => 'REGULAR_PICKUP',
|
70
69
|
'request_courier' => 'REQUEST_COURIER',
|
71
70
|
'dropbox' => 'DROP_BOX',
|
@@ -73,14 +72,14 @@ module ActiveMerchant
|
|
73
72
|
'station' => 'STATION'
|
74
73
|
}
|
75
74
|
|
76
|
-
|
75
|
+
PAYMENT_TYPES = {
|
77
76
|
'sender' => 'SENDER',
|
78
77
|
'recipient' => 'RECIPIENT',
|
79
78
|
'third_party' => 'THIRDPARTY',
|
80
79
|
'collect' => 'COLLECT'
|
81
80
|
}
|
82
|
-
|
83
|
-
|
81
|
+
|
82
|
+
PACKAGE_IDENTIFIER_TYPES = {
|
84
83
|
'tracking_number' => 'TRACKING_NUMBER_OR_DOORTAG',
|
85
84
|
'door_tag' => 'TRACKING_NUMBER_OR_DOORTAG',
|
86
85
|
'rma' => 'RMA',
|
@@ -92,12 +91,11 @@ module ActiveMerchant
|
|
92
91
|
'express_mps_master' => 'EXPRESS_MPS_MASTER'
|
93
92
|
}
|
94
93
|
|
95
|
-
|
96
|
-
TransitTimes = ["UNKNOWN","ONE_DAY","TWO_DAYS","THREE_DAYS","FOUR_DAYS","FIVE_DAYS","SIX_DAYS","SEVEN_DAYS","EIGHT_DAYS","NINE_DAYS","TEN_DAYS","ELEVEN_DAYS","TWELVE_DAYS","THIRTEEN_DAYS","FOURTEEN_DAYS","FIFTEEN_DAYS","SIXTEEN_DAYS","SEVENTEEN_DAYS","EIGHTEEN_DAYS"]
|
94
|
+
TRANSIT_TIMES = %w(UNKNOWN ONE_DAY TWO_DAYS THREE_DAYS FOUR_DAYS FIVE_DAYS SIX_DAYS SEVEN_DAYS EIGHT_DAYS NINE_DAYS TEN_DAYS ELEVEN_DAYS TWELVE_DAYS THIRTEEN_DAYS FOURTEEN_DAYS FIFTEEN_DAYS SIXTEEN_DAYS SEVENTEEN_DAYS EIGHTEEN_DAYS)
|
97
95
|
|
98
96
|
# FedEx tracking codes as described in the FedEx Tracking Service WSDL Guide
|
99
97
|
# All delays also have been marked as exceptions
|
100
|
-
TRACKING_STATUS_CODES = HashWithIndifferentAccess.new(
|
98
|
+
TRACKING_STATUS_CODES = HashWithIndifferentAccess.new(
|
101
99
|
'AA' => :at_airport,
|
102
100
|
'AD' => :at_delivery,
|
103
101
|
'AF' => :at_fedex_facility,
|
@@ -129,31 +127,31 @@ module ActiveMerchant
|
|
129
127
|
'SF' => :at_sort_facility,
|
130
128
|
'SP' => :split_status,
|
131
129
|
'TR' => :transfer
|
132
|
-
|
130
|
+
)
|
133
131
|
|
134
132
|
def self.service_name_for_code(service_code)
|
135
|
-
|
133
|
+
SERVICE_TYPES[service_code] || "FedEx #{service_code.titleize.sub(/Fedex /, '')}"
|
136
134
|
end
|
137
|
-
|
135
|
+
|
138
136
|
def requirements
|
139
137
|
[:key, :password, :account, :login]
|
140
138
|
end
|
141
|
-
|
139
|
+
|
142
140
|
def find_rates(origin, destination, packages, options = {})
|
143
141
|
options = @options.update(options)
|
144
142
|
packages = Array(packages)
|
145
|
-
|
143
|
+
|
146
144
|
rate_request = build_rate_request(origin, destination, packages, options)
|
147
|
-
|
145
|
+
|
148
146
|
xml = commit(save_request(rate_request), (options[:test] || false))
|
149
147
|
response = remove_version_prefix(xml)
|
150
148
|
|
151
149
|
parse_rate_response(origin, destination, packages, response, options)
|
152
150
|
end
|
153
|
-
|
154
|
-
def find_tracking_info(tracking_number, options={})
|
151
|
+
|
152
|
+
def find_tracking_info(tracking_number, options = {})
|
155
153
|
options = @options.update(options)
|
156
|
-
|
154
|
+
|
157
155
|
tracking_request = build_tracking_request(tracking_number, options)
|
158
156
|
xml = commit(save_request(tracking_request), (options[:test] || false))
|
159
157
|
response = remove_version_prefix(xml)
|
@@ -161,36 +159,30 @@ module ActiveMerchant
|
|
161
159
|
end
|
162
160
|
|
163
161
|
protected
|
164
|
-
|
165
|
-
|
162
|
+
|
163
|
+
def build_rate_request(origin, destination, packages, options = {})
|
164
|
+
imperial = %w(US LR MM).include?(origin.country_code(:alpha2))
|
166
165
|
|
167
166
|
xml_request = XmlNode.new('RateRequest', 'xmlns' => 'http://fedex.com/ws/rate/v13') do |root_node|
|
168
167
|
root_node << build_request_header
|
168
|
+
root_node << build_version_node
|
169
169
|
|
170
|
-
# Version
|
171
|
-
root_node << XmlNode.new('Version') do |version_node|
|
172
|
-
version_node << XmlNode.new('ServiceId', 'crs')
|
173
|
-
version_node << XmlNode.new('Major', '13')
|
174
|
-
version_node << XmlNode.new('Intermediate', '0')
|
175
|
-
version_node << XmlNode.new('Minor', '0')
|
176
|
-
end
|
177
|
-
|
178
170
|
# Returns delivery dates
|
179
171
|
root_node << XmlNode.new('ReturnTransitAndCommit', true)
|
180
172
|
# Returns saturday delivery shipping options when available
|
181
173
|
root_node << XmlNode.new('VariableOptions', 'SATURDAY_DELIVERY')
|
182
|
-
|
174
|
+
|
183
175
|
root_node << XmlNode.new('RequestedShipment') do |rs|
|
184
176
|
rs << XmlNode.new('ShipTimestamp', ship_timestamp(options[:turn_around_time]))
|
185
177
|
|
186
178
|
freight = has_freight?(options)
|
187
179
|
|
188
|
-
|
180
|
+
unless freight
|
189
181
|
# fedex api wants this up here otherwise request returns an error
|
190
182
|
rs << XmlNode.new('DropoffType', options[:dropoff_type] || 'REGULAR_PICKUP')
|
191
183
|
rs << XmlNode.new('PackagingType', options[:packaging_type] || 'YOUR_PACKAGING')
|
192
184
|
end
|
193
|
-
|
185
|
+
|
194
186
|
rs << build_location_node('Shipper', (options[:shipper] || origin))
|
195
187
|
rs << build_location_node('Recipient', destination)
|
196
188
|
if options[:shipper] and options[:shipper] != origin
|
@@ -211,21 +203,25 @@ module ActiveMerchant
|
|
211
203
|
end
|
212
204
|
|
213
205
|
rs << build_rate_request_types_node
|
214
|
-
|
215
206
|
rs << XmlNode.new('PackageCount', packages.size)
|
216
|
-
packages
|
217
|
-
|
218
|
-
rps << XmlNode.new('GroupPackageCount', 1)
|
219
|
-
rps << build_package_weight_node(pkg, imperial)
|
220
|
-
rps << build_package_dimensions_node(pkg, imperial)
|
221
|
-
end
|
222
|
-
end
|
207
|
+
rs << build_packages_nodes(packages, imperial)
|
208
|
+
|
223
209
|
end
|
224
210
|
end
|
225
211
|
end
|
226
212
|
xml_request.to_s
|
227
213
|
end
|
228
214
|
|
215
|
+
def build_packages_nodes(packages, imperial)
|
216
|
+
packages.map do |pkg|
|
217
|
+
XmlNode.new('RequestedPackageLineItems') do |rps|
|
218
|
+
rps << XmlNode.new('GroupPackageCount', 1)
|
219
|
+
rps << build_package_weight_node(pkg, imperial)
|
220
|
+
rps << build_package_dimensions_node(pkg, imperial)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
229
225
|
def build_shipping_charges_payment_node(freight_options)
|
230
226
|
XmlNode.new('ShippingChargesPayment') do |shipping_charges_payment|
|
231
227
|
shipping_charges_payment << XmlNode.new('PaymentType', freight_options[:payment_type])
|
@@ -263,14 +259,23 @@ module ActiveMerchant
|
|
263
259
|
def build_package_weight_node(pkg, imperial)
|
264
260
|
XmlNode.new('Weight') do |tw|
|
265
261
|
tw << XmlNode.new('Units', imperial ? 'LB' : 'KG')
|
266
|
-
tw << XmlNode.new('Value', [((imperial ? pkg.lbs : pkg.kgs).to_f*1000).round/1000.0, 0.1].max)
|
262
|
+
tw << XmlNode.new('Value', [((imperial ? pkg.lbs : pkg.kgs).to_f * 1000).round / 1000.0, 0.1].max)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
def build_version_node
|
267
|
+
XmlNode.new('Version') do |version_node|
|
268
|
+
version_node << XmlNode.new('ServiceId', 'crs')
|
269
|
+
version_node << XmlNode.new('Major', '13')
|
270
|
+
version_node << XmlNode.new('Intermediate', '0')
|
271
|
+
version_node << XmlNode.new('Minor', '0')
|
267
272
|
end
|
268
273
|
end
|
269
274
|
|
270
275
|
def build_package_dimensions_node(pkg, imperial)
|
271
276
|
XmlNode.new('Dimensions') do |dimensions|
|
272
|
-
[:length
|
273
|
-
value = ((imperial ? pkg.inches(axis) : pkg.cm(axis)).to_f*1000).round/1000.0 # 3 decimals
|
277
|
+
[:length, :width, :height].each do |axis|
|
278
|
+
value = ((imperial ? pkg.inches(axis) : pkg.cm(axis)).to_f * 1000).round / 1000.0 # 3 decimals
|
274
279
|
dimensions << XmlNode.new(axis.to_s.capitalize, value.ceil)
|
275
280
|
end
|
276
281
|
dimensions << XmlNode.new('Units', imperial ? 'IN' : 'CM')
|
@@ -280,11 +285,11 @@ module ActiveMerchant
|
|
280
285
|
def build_rate_request_types_node(type = 'ACCOUNT')
|
281
286
|
XmlNode.new('RateRequestTypes', type)
|
282
287
|
end
|
283
|
-
|
284
|
-
def build_tracking_request(tracking_number, options={})
|
288
|
+
|
289
|
+
def build_tracking_request(tracking_number, options = {})
|
285
290
|
xml_request = XmlNode.new('TrackRequest', 'xmlns' => 'http://fedex.com/ws/track/v3') do |root_node|
|
286
291
|
root_node << build_request_header
|
287
|
-
|
292
|
+
|
288
293
|
# Version
|
289
294
|
root_node << XmlNode.new('Version') do |version_node|
|
290
295
|
version_node << XmlNode.new('ServiceId', 'trck')
|
@@ -292,19 +297,19 @@ module ActiveMerchant
|
|
292
297
|
version_node << XmlNode.new('Intermediate', '0')
|
293
298
|
version_node << XmlNode.new('Minor', '0')
|
294
299
|
end
|
295
|
-
|
300
|
+
|
296
301
|
root_node << XmlNode.new('PackageIdentifier') do |package_node|
|
297
302
|
package_node << XmlNode.new('Value', tracking_number)
|
298
|
-
package_node << XmlNode.new('Type',
|
303
|
+
package_node << XmlNode.new('Type', PACKAGE_IDENTIFIER_TYPES[options['package_identifier_type'] || 'tracking_number'])
|
299
304
|
end
|
300
|
-
|
305
|
+
|
301
306
|
root_node << XmlNode.new('ShipDateRangeBegin', options['ship_date_range_begin']) if options['ship_date_range_begin']
|
302
307
|
root_node << XmlNode.new('ShipDateRangeEnd', options['ship_date_range_end']) if options['ship_date_range_end']
|
303
308
|
root_node << XmlNode.new('IncludeDetailedScans', 1)
|
304
309
|
end
|
305
310
|
xml_request.to_s
|
306
311
|
end
|
307
|
-
|
312
|
+
|
308
313
|
def build_request_header
|
309
314
|
web_authentication_detail = XmlNode.new('WebAuthenticationDetail') do |wad|
|
310
315
|
wad << XmlNode.new('UserCredential') do |uc|
|
@@ -312,19 +317,19 @@ module ActiveMerchant
|
|
312
317
|
uc << XmlNode.new('Password', @options[:password])
|
313
318
|
end
|
314
319
|
end
|
315
|
-
|
320
|
+
|
316
321
|
client_detail = XmlNode.new('ClientDetail') do |cd|
|
317
322
|
cd << XmlNode.new('AccountNumber', @options[:account])
|
318
323
|
cd << XmlNode.new('MeterNumber', @options[:login])
|
319
324
|
end
|
320
|
-
|
325
|
+
|
321
326
|
trasaction_detail = XmlNode.new('TransactionDetail') do |td|
|
322
|
-
td << XmlNode.new('CustomerTransactionId', 'ActiveShipping') # TODO: Need to do something better with this..
|
327
|
+
td << XmlNode.new('CustomerTransactionId', @options[:transaction_id] || 'ActiveShipping') # TODO: Need to do something better with this..
|
323
328
|
end
|
324
|
-
|
329
|
+
|
325
330
|
[web_authentication_detail, client_detail, trasaction_detail]
|
326
331
|
end
|
327
|
-
|
332
|
+
|
328
333
|
def build_location_node(name, location)
|
329
334
|
XmlNode.new(name) do |xml_node|
|
330
335
|
xml_node << XmlNode.new('Address') do |address_node|
|
@@ -338,22 +343,23 @@ module ActiveMerchant
|
|
338
343
|
end
|
339
344
|
end
|
340
345
|
end
|
341
|
-
|
346
|
+
|
342
347
|
def parse_rate_response(origin, destination, packages, response, options)
|
343
348
|
rate_estimates = []
|
344
|
-
|
345
|
-
|
349
|
+
|
346
350
|
xml = build_document(response)
|
347
351
|
root_node = xml.elements['RateReply']
|
348
|
-
|
352
|
+
|
349
353
|
success = response_success?(xml)
|
350
354
|
message = response_message(xml)
|
351
|
-
|
355
|
+
|
356
|
+
raise ActiveMerchant::Shipping::ResponseContentError.new(StandardError.new('Invalid document'), xml) unless root_node
|
357
|
+
|
352
358
|
root_node.elements.each('RateReplyDetails') do |rated_shipment|
|
353
359
|
service_code = rated_shipment.get_text('ServiceType').to_s
|
354
360
|
is_saturday_delivery = rated_shipment.get_text('AppliedOptions').to_s == 'SATURDAY_DELIVERY'
|
355
361
|
service_type = is_saturday_delivery ? "#{service_code}_SATURDAY_DELIVERY" : service_code
|
356
|
-
|
362
|
+
|
357
363
|
transit_time = rated_shipment.get_text('TransitTime').to_s if service_code == "FEDEX_GROUND"
|
358
364
|
max_transit_time = rated_shipment.get_text('MaximumTransitTime').to_s if service_code == "FEDEX_GROUND"
|
359
365
|
|
@@ -363,14 +369,14 @@ module ActiveMerchant
|
|
363
369
|
|
364
370
|
currency = rated_shipment.get_text('RatedShipmentDetails/ShipmentRateDetail/TotalNetCharge/Currency').to_s
|
365
371
|
rate_estimates << RateEstimate.new(origin, destination, @@name,
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
+
self.class.service_name_for_code(service_type),
|
373
|
+
:service_code => service_code,
|
374
|
+
:total_price => rated_shipment.get_text('RatedShipmentDetails/ShipmentRateDetail/TotalNetCharge/Amount').to_s.to_f,
|
375
|
+
:currency => currency,
|
376
|
+
:packages => packages,
|
377
|
+
:delivery_range => delivery_range)
|
372
378
|
end
|
373
|
-
|
379
|
+
|
374
380
|
if rate_estimates.empty?
|
375
381
|
success = false
|
376
382
|
message = "No shipping rates could be found for the destination address" if message.blank?
|
@@ -381,11 +387,11 @@ module ActiveMerchant
|
|
381
387
|
|
382
388
|
def delivery_range_from(transit_time, max_transit_time, delivery_timestamp, options)
|
383
389
|
delivery_range = [delivery_timestamp, delivery_timestamp]
|
384
|
-
|
385
|
-
#if there's no delivery timestamp but we do have a transit time, use it
|
390
|
+
|
391
|
+
# if there's no delivery timestamp but we do have a transit time, use it
|
386
392
|
if delivery_timestamp.blank? && transit_time.present?
|
387
|
-
transit_range = parse_transit_times([transit_time,max_transit_time.presence || transit_time])
|
388
|
-
delivery_range = transit_range.map{|days| business_days_from(ship_date(options[:turn_around_time]), days)}
|
393
|
+
transit_range = parse_transit_times([transit_time, max_transit_time.presence || transit_time])
|
394
|
+
delivery_range = transit_range.map { |days| business_days_from(ship_date(options[:turn_around_time]), days) }
|
389
395
|
end
|
390
396
|
|
391
397
|
delivery_range
|
@@ -410,19 +416,17 @@ module ActiveMerchant
|
|
410
416
|
def parse_tracking_response(response, options)
|
411
417
|
xml = build_document(response)
|
412
418
|
root_node = xml.elements['TrackReply']
|
413
|
-
|
419
|
+
|
414
420
|
success = response_success?(xml)
|
415
421
|
message = response_message(xml)
|
416
|
-
|
422
|
+
|
417
423
|
if success
|
418
|
-
|
419
|
-
|
420
|
-
scheduled_delivery_time, actual_delivery_time, delivery_signature = nil
|
424
|
+
origin = nil
|
425
|
+
delivery_signature = nil
|
421
426
|
shipment_events = []
|
422
427
|
|
423
428
|
tracking_details = root_node.elements['TrackDetails']
|
424
429
|
tracking_number = tracking_details.get_text('TrackingNumber').to_s
|
425
|
-
|
426
430
|
status_code = tracking_details.get_text('StatusCode').to_s
|
427
431
|
status_description = tracking_details.get_text('StatusDescription').to_s
|
428
432
|
status = TRACKING_STATUS_CODES[status_code]
|
@@ -447,7 +451,7 @@ module ActiveMerchant
|
|
447
451
|
ship_time = extract_timestamp(tracking_details, 'ShipTimestamp')
|
448
452
|
actual_delivery_time = extract_timestamp(tracking_details, 'ActualDeliveryTimestamp')
|
449
453
|
scheduled_delivery_time = extract_timestamp(tracking_details, 'EstimatedDeliveryTimestamp')
|
450
|
-
|
454
|
+
|
451
455
|
tracking_details.elements.each('Events') do |event|
|
452
456
|
address = event.elements['Address']
|
453
457
|
|
@@ -456,7 +460,7 @@ module ActiveMerchant
|
|
456
460
|
zip_code = address.get_text('PostalCode').to_s
|
457
461
|
country = address.get_text('CountryCode').to_s
|
458
462
|
next if country.blank?
|
459
|
-
|
463
|
+
|
460
464
|
location = Location.new(:city => city, :state => state, :postal_code => zip_code, :country => country)
|
461
465
|
description = event.get_text('EventDescription').to_s
|
462
466
|
|
@@ -468,23 +472,23 @@ module ActiveMerchant
|
|
468
472
|
shipment_events = shipment_events.sort_by(&:time)
|
469
473
|
|
470
474
|
end
|
471
|
-
|
475
|
+
|
472
476
|
TrackingResponse.new(success, message, Hash.from_xml(response),
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
477
|
+
:carrier => @@name,
|
478
|
+
:xml => response,
|
479
|
+
:request => last_request,
|
480
|
+
:status => status,
|
481
|
+
:status_code => status_code,
|
482
|
+
:status_description => status_description,
|
483
|
+
:ship_time => ship_time,
|
484
|
+
:scheduled_delivery_date => scheduled_delivery_time,
|
485
|
+
:actual_delivery_date => actual_delivery_time,
|
486
|
+
:delivery_signature => delivery_signature,
|
487
|
+
:shipment_events => shipment_events,
|
488
|
+
:shipper_address => (shipper_address.nil? || shipper_address.unknown?) ? nil : shipper_address,
|
489
|
+
:origin => origin,
|
490
|
+
:destination => destination,
|
491
|
+
:tracking_number => tracking_number
|
488
492
|
)
|
489
493
|
end
|
490
494
|
|
@@ -501,24 +505,29 @@ module ActiveMerchant
|
|
501
505
|
def response_status_node(document)
|
502
506
|
document.elements['/*/Notifications/']
|
503
507
|
end
|
504
|
-
|
508
|
+
|
505
509
|
def response_success?(document)
|
506
|
-
|
510
|
+
response_node = response_status_node(document)
|
511
|
+
return false if response_node.nil?
|
512
|
+
|
513
|
+
%w(SUCCESS WARNING NOTE).include? response_node.get_text('Severity').to_s
|
507
514
|
end
|
508
|
-
|
515
|
+
|
509
516
|
def response_message(document)
|
510
517
|
response_node = response_status_node(document)
|
511
|
-
"
|
518
|
+
return "" if response_node.nil?
|
519
|
+
|
520
|
+
"#{response_node.get_text('Severity')} - #{response_node.get_text('Code')}: #{response_node.get_text('Message')}"
|
512
521
|
end
|
513
|
-
|
522
|
+
|
514
523
|
def commit(request, test = false)
|
515
|
-
ssl_post(test ? TEST_URL : LIVE_URL, request.gsub("\n",''))
|
524
|
+
ssl_post(test ? TEST_URL : LIVE_URL, request.gsub("\n", ''))
|
516
525
|
end
|
517
|
-
|
526
|
+
|
518
527
|
def parse_transit_times(times)
|
519
528
|
results = []
|
520
529
|
times.each do |day_count|
|
521
|
-
days =
|
530
|
+
days = TRANSIT_TIMES.index(day_count.to_s.chomp)
|
522
531
|
results << days.to_i
|
523
532
|
end
|
524
533
|
results
|