active_shipping 0.12.4 → 0.12.5
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/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
|