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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/lib/active_shipping.rb +2 -1
  3. data/lib/active_shipping/shipping/base.rb +2 -2
  4. data/lib/active_shipping/shipping/carrier.rb +16 -13
  5. data/lib/active_shipping/shipping/carriers/benchmark_carrier.rb +3 -4
  6. data/lib/active_shipping/shipping/carriers/bogus_carrier.rb +1 -3
  7. data/lib/active_shipping/shipping/carriers/canada_post.rb +33 -44
  8. data/lib/active_shipping/shipping/carriers/canada_post_pws.rb +72 -81
  9. data/lib/active_shipping/shipping/carriers/fedex.rb +118 -109
  10. data/lib/active_shipping/shipping/carriers/kunaki.rb +33 -32
  11. data/lib/active_shipping/shipping/carriers/new_zealand_post.rb +9 -16
  12. data/lib/active_shipping/shipping/carriers/shipwire.rb +36 -35
  13. data/lib/active_shipping/shipping/carriers/stamps.rb +39 -51
  14. data/lib/active_shipping/shipping/carriers/ups.rb +280 -116
  15. data/lib/active_shipping/shipping/carriers/ups.rb.orig +456 -0
  16. data/lib/active_shipping/shipping/carriers/usps.rb +145 -100
  17. data/lib/active_shipping/shipping/carriers/usps.rb.orig +616 -0
  18. data/lib/active_shipping/shipping/errors.rb +1 -1
  19. data/lib/active_shipping/shipping/label_response.rb +25 -0
  20. data/lib/active_shipping/shipping/location.rb +18 -16
  21. data/lib/active_shipping/shipping/package.rb +51 -54
  22. data/lib/active_shipping/shipping/rate_estimate.rb +10 -12
  23. data/lib/active_shipping/shipping/rate_response.rb +3 -7
  24. data/lib/active_shipping/shipping/response.rb +6 -9
  25. data/lib/active_shipping/shipping/shipment_event.rb +2 -4
  26. data/lib/active_shipping/shipping/shipment_packer.rb +32 -17
  27. data/lib/active_shipping/shipping/shipping_response.rb +2 -4
  28. data/lib/active_shipping/shipping/tracking_response.rb +3 -5
  29. data/lib/active_shipping/version.rb +1 -1
  30. data/lib/vendor/quantified/lib/quantified/attribute.rb +79 -80
  31. data/lib/vendor/quantified/lib/quantified/length.rb +5 -5
  32. data/lib/vendor/quantified/lib/quantified/mass.rb +4 -4
  33. data/lib/vendor/quantified/test/length_test.rb +19 -15
  34. data/lib/vendor/quantified/test/mass_test.rb +14 -14
  35. data/lib/vendor/quantified/test/test_helper.rb +1 -2
  36. data/lib/vendor/test_helper.rb +0 -1
  37. data/lib/vendor/xml_node/benchmark/bench_generation.rb +2 -4
  38. data/lib/vendor/xml_node/lib/xml_node.rb +54 -55
  39. data/lib/vendor/xml_node/test/test_generating.rb +23 -28
  40. data/lib/vendor/xml_node/test/test_parsing.rb +5 -8
  41. metadata +6 -25
  42. checksums.yaml.gz.sig +0 -1
  43. data.tar.gz.sig +0 -0
  44. 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
- CarrierCodes = {
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
- ServiceTypes = {
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
- PackageTypes = {
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
- DropoffTypes = {
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
- PaymentTypes = {
75
+ PAYMENT_TYPES = {
77
76
  'sender' => 'SENDER',
78
77
  'recipient' => 'RECIPIENT',
79
78
  'third_party' => 'THIRDPARTY',
80
79
  'collect' => 'COLLECT'
81
80
  }
82
-
83
- PackageIdentifierTypes = {
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
- ServiceTypes[service_code] || "FedEx #{service_code.titleize.sub(/Fedex /, '')}"
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
- def build_rate_request(origin, destination, packages, options={})
165
- imperial = ['US','LR','MM'].include?(origin.country_code(:alpha2))
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
- if !freight
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.each do |pkg|
217
- rs << 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
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,:width,:height].each do |axis|
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', PackageIdentifierTypes[options['package_identifier_type'] || 'tracking_number'])
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
- success, message = nil
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
- self.class.service_name_for_code(service_type),
367
- :service_code => service_code,
368
- :total_price => rated_shipment.get_text('RatedShipmentDetails/ShipmentRateDetail/TotalNetCharge/Amount').to_s.to_f,
369
- :currency => currency,
370
- :packages => packages,
371
- :delivery_range => delivery_range)
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
- tracking_number, shipper_address, origin, destination, status = nil
419
- status_code, status_description, ship_time = nil
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
- :carrier => @@name,
474
- :xml => response,
475
- :request => last_request,
476
- :status => status,
477
- :status_code => status_code,
478
- :status_description => status_description,
479
- :ship_time => ship_time,
480
- :scheduled_delivery_date => scheduled_delivery_time,
481
- :actual_delivery_date => actual_delivery_time,
482
- :delivery_signature => delivery_signature,
483
- :shipment_events => shipment_events,
484
- :shipper_address => (shipper_address.nil? || shipper_address.unknown?) ? nil : shipper_address,
485
- :origin => origin,
486
- :destination => destination,
487
- :tracking_number => tracking_number
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
- %w{SUCCESS WARNING NOTE}.include? response_status_node(document).get_text('Severity').to_s
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
- "#{response_status_node(document).get_text('Severity')} - #{response_node.get_text('Code')}: #{response_node.get_text('Message')}"
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 = TransitTimes.index(day_count.to_s.chomp)
530
+ days = TRANSIT_TIMES.index(day_count.to_s.chomp)
522
531
  results << days.to_i
523
532
  end
524
533
  results