active_shipping 0.9.15 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +1 -1
- data/lib/active_shipping.rb +1 -0
- data/lib/active_shipping/shipping/carriers.rb +2 -1
- data/lib/active_shipping/shipping/carriers/canada_post.rb +5 -4
- data/lib/active_shipping/shipping/carriers/canada_post_pws.rb +837 -0
- data/lib/active_shipping/shipping/carriers/fedex.rb +33 -19
- data/lib/active_shipping/shipping/carriers/ups.rb +72 -69
- data/lib/active_shipping/shipping/carriers/ups.rb.orig +456 -0
- data/lib/active_shipping/shipping/carriers/usps.rb +185 -9
- data/lib/active_shipping/shipping/carriers/usps.rb.orig +616 -0
- data/lib/active_shipping/shipping/package.rb +109 -10
- data/lib/active_shipping/shipping/rate_estimate.rb +10 -6
- data/lib/active_shipping/shipping/shipping_response.rb +16 -0
- data/lib/active_shipping/shipping/tracking_response.rb +3 -1
- data/lib/active_shipping/version.rb +1 -1
- metadata +23 -3
@@ -337,18 +337,22 @@ module ActiveMerchant
|
|
337
337
|
message = response_message(xml)
|
338
338
|
|
339
339
|
if success
|
340
|
-
tracking_number, origin, destination, status, status_code, status_description = nil
|
340
|
+
tracking_number, origin, destination, status, status_code, status_description, delivery_signature = nil
|
341
341
|
shipment_events = []
|
342
342
|
|
343
343
|
tracking_details = root_node.elements['TrackDetails']
|
344
344
|
tracking_number = tracking_details.get_text('TrackingNumber').to_s
|
345
|
-
|
345
|
+
|
346
346
|
status_code = tracking_details.get_text('StatusCode').to_s
|
347
347
|
status_description = tracking_details.get_text('StatusDescription').to_s
|
348
348
|
status = TRACKING_STATUS_CODES[status_code]
|
349
349
|
|
350
|
+
if status_code == 'DL' && tracking_details.get_text('SignatureProofOfDeliveryAvailable').to_s == 'true'
|
351
|
+
delivery_signature = tracking_details.get_text('DeliverySignatureName').to_s
|
352
|
+
end
|
353
|
+
|
350
354
|
origin_node = tracking_details.elements['OriginLocationAddress']
|
351
|
-
|
355
|
+
|
352
356
|
if origin_node
|
353
357
|
origin = Location.new(
|
354
358
|
:country => origin_node.get_text('CountryCode').to_s,
|
@@ -357,17 +361,7 @@ module ActiveMerchant
|
|
357
361
|
)
|
358
362
|
end
|
359
363
|
|
360
|
-
|
361
|
-
|
362
|
-
if destination_node.nil?
|
363
|
-
destination_node = tracking_details.elements['ActualDeliveryAddress']
|
364
|
-
end
|
365
|
-
|
366
|
-
destination = Location.new(
|
367
|
-
:country => destination_node.get_text('CountryCode').to_s,
|
368
|
-
:province => destination_node.get_text('StateOrProvinceCode').to_s,
|
369
|
-
:city => destination_node.get_text('City').to_s
|
370
|
-
)
|
364
|
+
destination = extract_destination(tracking_details)
|
371
365
|
|
372
366
|
tracking_details.elements.each('Events') do |event|
|
373
367
|
address = event.elements['Address']
|
@@ -380,11 +374,10 @@ module ActiveMerchant
|
|
380
374
|
|
381
375
|
location = Location.new(:city => city, :state => state, :postal_code => zip_code, :country => country)
|
382
376
|
description = event.get_text('EventDescription').to_s
|
383
|
-
|
384
|
-
#
|
385
|
-
|
386
|
-
|
387
|
-
|
377
|
+
|
378
|
+
time = Time.parse("#{event.get_text('Timestamp').to_s}")
|
379
|
+
zoneless_time = time.utc
|
380
|
+
|
388
381
|
shipment_events << ShipmentEvent.new(description, zoneless_time, location)
|
389
382
|
end
|
390
383
|
shipment_events = shipment_events.sort_by(&:time)
|
@@ -398,6 +391,7 @@ module ActiveMerchant
|
|
398
391
|
:status => status,
|
399
392
|
:status_code => status_code,
|
400
393
|
:status_description => status_description,
|
394
|
+
:delivery_signature => delivery_signature,
|
401
395
|
:shipment_events => shipment_events,
|
402
396
|
:origin => origin,
|
403
397
|
:destination => destination,
|
@@ -448,6 +442,26 @@ module ActiveMerchant
|
|
448
442
|
end
|
449
443
|
results
|
450
444
|
end
|
445
|
+
|
446
|
+
def extract_destination(document)
|
447
|
+
node = document.elements['DestinationAddress'] || document.elements['ActualDeliveryAddress']
|
448
|
+
|
449
|
+
args = if node
|
450
|
+
{
|
451
|
+
:country => node.get_text('CountryCode').to_s,
|
452
|
+
:province => node.get_text('StateOrProvinceCode').to_s,
|
453
|
+
:city => node.get_text('City').to_s
|
454
|
+
}
|
455
|
+
else
|
456
|
+
{
|
457
|
+
:country => ActiveMerchant::Country.new(:alpha2 => 'ZZ', :name => 'Unknown or Invalid Territory', :alpha3 => 'ZZZ', :numeric => '999'),
|
458
|
+
:province => 'unknown',
|
459
|
+
:city => 'unknown'
|
460
|
+
}
|
461
|
+
end
|
462
|
+
|
463
|
+
Location.new(args)
|
464
|
+
end
|
451
465
|
end
|
452
466
|
end
|
453
467
|
end
|
@@ -4,22 +4,22 @@ module ActiveMerchant
|
|
4
4
|
module Shipping
|
5
5
|
class UPS < Carrier
|
6
6
|
self.retry_safe = true
|
7
|
-
|
7
|
+
|
8
8
|
cattr_accessor :default_options
|
9
9
|
cattr_reader :name
|
10
10
|
@@name = "UPS"
|
11
|
-
|
11
|
+
|
12
12
|
TEST_URL = 'https://wwwcie.ups.com'
|
13
13
|
LIVE_URL = 'https://onlinetools.ups.com'
|
14
|
-
|
14
|
+
|
15
15
|
RESOURCES = {
|
16
16
|
:rates => 'ups.app/xml/Rate',
|
17
17
|
:track => 'ups.app/xml/Track'
|
18
18
|
}
|
19
|
-
|
19
|
+
|
20
20
|
PICKUP_CODES = HashWithIndifferentAccess.new({
|
21
21
|
:daily_pickup => "01",
|
22
|
-
:customer_counter => "03",
|
22
|
+
:customer_counter => "03",
|
23
23
|
:one_time_pickup => "06",
|
24
24
|
:on_call_air => "07",
|
25
25
|
:suggested_retail_rates => "11",
|
@@ -29,7 +29,7 @@ module ActiveMerchant
|
|
29
29
|
|
30
30
|
CUSTOMER_CLASSIFICATIONS = HashWithIndifferentAccess.new({
|
31
31
|
:wholesale => "01",
|
32
|
-
:occasional => "03",
|
32
|
+
:occasional => "03",
|
33
33
|
:retail => "04"
|
34
34
|
})
|
35
35
|
|
@@ -44,7 +44,7 @@ module ActiveMerchant
|
|
44
44
|
:occasional
|
45
45
|
end
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
DEFAULT_SERVICES = {
|
49
49
|
"01" => "UPS Next Day Air",
|
50
50
|
"02" => "UPS Second Day Air",
|
@@ -64,24 +64,24 @@ module ActiveMerchant
|
|
64
64
|
"85" => "UPS Today Express",
|
65
65
|
"86" => "UPS Today Express Saver"
|
66
66
|
}
|
67
|
-
|
67
|
+
|
68
68
|
CANADA_ORIGIN_SERVICES = {
|
69
69
|
"01" => "UPS Express",
|
70
70
|
"02" => "UPS Expedited",
|
71
71
|
"14" => "UPS Express Early A.M."
|
72
72
|
}
|
73
|
-
|
73
|
+
|
74
74
|
MEXICO_ORIGIN_SERVICES = {
|
75
75
|
"07" => "UPS Express",
|
76
76
|
"08" => "UPS Expedited",
|
77
77
|
"54" => "UPS Express Plus"
|
78
78
|
}
|
79
|
-
|
79
|
+
|
80
80
|
EU_ORIGIN_SERVICES = {
|
81
81
|
"07" => "UPS Express",
|
82
82
|
"08" => "UPS Expedited"
|
83
83
|
}
|
84
|
-
|
84
|
+
|
85
85
|
OTHER_NON_US_ORIGIN_SERVICES = {
|
86
86
|
"07" => "UPS Express"
|
87
87
|
}
|
@@ -96,13 +96,13 @@ module ActiveMerchant
|
|
96
96
|
|
97
97
|
# From http://en.wikipedia.org/w/index.php?title=European_Union&oldid=174718707 (Current as of November 30, 2007)
|
98
98
|
EU_COUNTRY_CODES = ["GB", "AT", "BE", "BG", "CY", "CZ", "DK", "EE", "FI", "FR", "DE", "GR", "HU", "IE", "IT", "LV", "LT", "LU", "MT", "NL", "PL", "PT", "RO", "SK", "SI", "ES", "SE"]
|
99
|
-
|
99
|
+
|
100
100
|
US_TERRITORIES_TREATED_AS_COUNTRIES = ["AS", "FM", "GU", "MH", "MP", "PW", "PR", "VI"]
|
101
|
-
|
101
|
+
|
102
102
|
def requirements
|
103
103
|
[:key, :login, :password]
|
104
104
|
end
|
105
|
-
|
105
|
+
|
106
106
|
def find_rates(origin, destination, packages, options={})
|
107
107
|
origin, destination = upsified_location(origin), upsified_location(destination)
|
108
108
|
options = @options.merge(options)
|
@@ -112,7 +112,7 @@ module ActiveMerchant
|
|
112
112
|
response = commit(:rates, save_request(access_request + rate_request), (options[:test] || false))
|
113
113
|
parse_rate_response(origin, destination, packages, response, options)
|
114
114
|
end
|
115
|
-
|
115
|
+
|
116
116
|
def find_tracking_info(tracking_number, options={})
|
117
117
|
options = @options.update(options)
|
118
118
|
access_request = build_access_request
|
@@ -120,9 +120,9 @@ module ActiveMerchant
|
|
120
120
|
response = commit(:track, save_request(access_request + tracking_request), (options[:test] || false))
|
121
121
|
parse_tracking_response(response, options)
|
122
122
|
end
|
123
|
-
|
123
|
+
|
124
124
|
protected
|
125
|
-
|
125
|
+
|
126
126
|
def upsified_location(location)
|
127
127
|
if location.country_code == 'US' && US_TERRITORIES_TREATED_AS_COUNTRIES.include?(location.state)
|
128
128
|
atts = {:country => location.state}
|
@@ -134,7 +134,7 @@ module ActiveMerchant
|
|
134
134
|
location
|
135
135
|
end
|
136
136
|
end
|
137
|
-
|
137
|
+
|
138
138
|
def build_access_request
|
139
139
|
xml_request = XmlNode.new('AccessRequest') do |access_request|
|
140
140
|
access_request << XmlNode.new('AccessLicenseNumber', @options[:key])
|
@@ -143,7 +143,7 @@ module ActiveMerchant
|
|
143
143
|
end
|
144
144
|
xml_request.to_s
|
145
145
|
end
|
146
|
-
|
146
|
+
|
147
147
|
def build_rate_request(origin, destination, packages, options={})
|
148
148
|
packages = Array(packages)
|
149
149
|
xml_request = XmlNode.new('RatingServiceSelectionRequest') do |root_node|
|
@@ -153,9 +153,9 @@ module ActiveMerchant
|
|
153
153
|
# not implemented: 'Rate' RequestOption to specify a single service query
|
154
154
|
# request << XmlNode.new('RequestOption', ((options[:service].nil? or options[:service] == :all) ? 'Shop' : 'Rate'))
|
155
155
|
end
|
156
|
-
|
156
|
+
|
157
157
|
pickup_type = options[:pickup_type] || :daily_pickup
|
158
|
-
|
158
|
+
|
159
159
|
root_node << XmlNode.new('PickupType') do |pickup_type_node|
|
160
160
|
pickup_type_node << XmlNode.new('Code', PICKUP_CODES[pickup_type])
|
161
161
|
# not implemented: PickupType/PickupDetails element
|
@@ -164,7 +164,7 @@ module ActiveMerchant
|
|
164
164
|
root_node << XmlNode.new('CustomerClassification') do |cc_node|
|
165
165
|
cc_node << XmlNode.new('Code', CUSTOMER_CLASSIFICATIONS[cc])
|
166
166
|
end
|
167
|
-
|
167
|
+
|
168
168
|
root_node << XmlNode.new('Shipment') do |shipment|
|
169
169
|
# not implemented: Shipment/Description element
|
170
170
|
shipment << build_location_node('Shipper', (options[:shipper] || origin), options)
|
@@ -172,28 +172,28 @@ module ActiveMerchant
|
|
172
172
|
if options[:shipper] and options[:shipper] != origin
|
173
173
|
shipment << build_location_node('ShipFrom', origin, options)
|
174
174
|
end
|
175
|
-
|
175
|
+
|
176
176
|
# not implemented: * Shipment/ShipmentWeight element
|
177
|
-
# * Shipment/ReferenceNumber element
|
178
|
-
# * Shipment/Service element
|
179
|
-
# * Shipment/PickupDate element
|
180
|
-
# * Shipment/ScheduledDeliveryDate element
|
181
|
-
# * Shipment/ScheduledDeliveryTime element
|
182
|
-
# * Shipment/AlternateDeliveryTime element
|
183
|
-
# * Shipment/DocumentsOnly element
|
184
|
-
|
177
|
+
# * Shipment/ReferenceNumber element
|
178
|
+
# * Shipment/Service element
|
179
|
+
# * Shipment/PickupDate element
|
180
|
+
# * Shipment/ScheduledDeliveryDate element
|
181
|
+
# * Shipment/ScheduledDeliveryTime element
|
182
|
+
# * Shipment/AlternateDeliveryTime element
|
183
|
+
# * Shipment/DocumentsOnly element
|
184
|
+
|
185
185
|
packages.each do |package|
|
186
186
|
imperial = ['US','LR','MM'].include?(origin.country_code(:alpha2))
|
187
|
-
|
187
|
+
|
188
188
|
shipment << XmlNode.new("Package") do |package_node|
|
189
|
-
|
189
|
+
|
190
190
|
# not implemented: * Shipment/Package/PackagingType element
|
191
191
|
# * Shipment/Package/Description element
|
192
|
-
|
192
|
+
|
193
193
|
package_node << XmlNode.new("PackagingType") do |packaging_type|
|
194
194
|
packaging_type << XmlNode.new("Code", '02')
|
195
195
|
end
|
196
|
-
|
196
|
+
|
197
197
|
package_node << XmlNode.new("Dimensions") do |dimensions|
|
198
198
|
dimensions << XmlNode.new("UnitOfMeasurement") do |units|
|
199
199
|
units << XmlNode.new("Code", imperial ? 'IN' : 'CM')
|
@@ -203,33 +203,35 @@ module ActiveMerchant
|
|
203
203
|
dimensions << XmlNode.new(axis.to_s.capitalize, [value,0.1].max)
|
204
204
|
end
|
205
205
|
end
|
206
|
-
|
206
|
+
|
207
207
|
package_node << XmlNode.new("PackageWeight") do |package_weight|
|
208
208
|
package_weight << XmlNode.new("UnitOfMeasurement") do |units|
|
209
209
|
units << XmlNode.new("Code", imperial ? 'LBS' : 'KGS')
|
210
210
|
end
|
211
|
-
|
211
|
+
|
212
212
|
value = ((imperial ? package.lbs : package.kgs).to_f*1000).round/1000.0 # 3 decimals
|
213
213
|
package_weight << XmlNode.new("Weight", [value,0.1].max)
|
214
214
|
end
|
215
|
-
|
215
|
+
|
216
216
|
# not implemented: * Shipment/Package/LargePackageIndicator element
|
217
217
|
# * Shipment/Package/ReferenceNumber element
|
218
218
|
# * Shipment/Package/PackageServiceOptions element
|
219
|
-
# * Shipment/Package/AdditionalHandling element
|
219
|
+
# * Shipment/Package/AdditionalHandling element
|
220
220
|
end
|
221
|
-
|
221
|
+
|
222
222
|
end
|
223
|
-
|
223
|
+
|
224
224
|
# not implemented: * Shipment/ShipmentServiceOptions element
|
225
|
-
|
226
|
-
|
225
|
+
if options[:origin_account]
|
226
|
+
shipment << XmlNode.new("RateInformation") do |rate_info_node|
|
227
|
+
rate_info_node << XmlNode.new("NegotiatedRatesIndicator")
|
228
|
+
end
|
229
|
+
end
|
227
230
|
end
|
228
|
-
|
229
231
|
end
|
230
232
|
xml_request.to_s
|
231
233
|
end
|
232
|
-
|
234
|
+
|
233
235
|
def build_tracking_request(tracking_number, options={})
|
234
236
|
xml_request = XmlNode.new('TrackRequest') do |root_node|
|
235
237
|
root_node << XmlNode.new('Request') do |request|
|
@@ -240,7 +242,7 @@ module ActiveMerchant
|
|
240
242
|
end
|
241
243
|
xml_request.to_s
|
242
244
|
end
|
243
|
-
|
245
|
+
|
244
246
|
def build_location_node(name,location,options={})
|
245
247
|
# not implemented: * Shipment/Shipper/Name element
|
246
248
|
# * Shipment/(ShipTo|ShipFrom)/CompanyName element
|
@@ -249,13 +251,13 @@ module ActiveMerchant
|
|
249
251
|
location_node = XmlNode.new(name) do |location_node|
|
250
252
|
location_node << XmlNode.new('PhoneNumber', location.phone.gsub(/[^\d]/,'')) unless location.phone.blank?
|
251
253
|
location_node << XmlNode.new('FaxNumber', location.fax.gsub(/[^\d]/,'')) unless location.fax.blank?
|
252
|
-
|
254
|
+
|
253
255
|
if name == 'Shipper' and (origin_account = @options[:origin_account] || options[:origin_account])
|
254
256
|
location_node << XmlNode.new('ShipperNumber', origin_account)
|
255
257
|
elsif name == 'ShipTo' and (destination_account = @options[:destination_account] || options[:destination_account])
|
256
258
|
location_node << XmlNode.new('ShipperAssignedIdentificationNumber', destination_account)
|
257
259
|
end
|
258
|
-
|
260
|
+
|
259
261
|
location_node << XmlNode.new('Address') do |address|
|
260
262
|
address << XmlNode.new("AddressLine1", location.address1) unless location.address1.blank?
|
261
263
|
address << XmlNode.new("AddressLine2", location.address2) unless location.address2.blank?
|
@@ -270,17 +272,17 @@ module ActiveMerchant
|
|
270
272
|
end
|
271
273
|
end
|
272
274
|
end
|
273
|
-
|
275
|
+
|
274
276
|
def parse_rate_response(origin, destination, packages, response, options={})
|
275
277
|
rates = []
|
276
|
-
|
278
|
+
|
277
279
|
xml = REXML::Document.new(response)
|
278
280
|
success = response_success?(xml)
|
279
281
|
message = response_message(xml)
|
280
|
-
|
282
|
+
|
281
283
|
if success
|
282
284
|
rate_estimates = []
|
283
|
-
|
285
|
+
|
284
286
|
xml.elements.each('/*/RatedShipment') do |rated_shipment|
|
285
287
|
service_code = rated_shipment.get_text('Service/Code').to_s
|
286
288
|
days_to_delivery = rated_shipment.get_text('GuaranteedDaysToDelivery').to_s.to_i
|
@@ -292,17 +294,18 @@ module ActiveMerchant
|
|
292
294
|
:currency => rated_shipment.get_text('TotalCharges/CurrencyCode').to_s,
|
293
295
|
:service_code => service_code,
|
294
296
|
:packages => packages,
|
295
|
-
:delivery_range => [timestamp_from_business_day(days_to_delivery)]
|
297
|
+
:delivery_range => [timestamp_from_business_day(days_to_delivery)],
|
298
|
+
:negotiated_rate => rated_shipment.get_text('NegotiatedRates/NetSummaryCharges/GrandTotal/MonetaryValue').to_s.to_f)
|
296
299
|
end
|
297
300
|
end
|
298
301
|
RateResponse.new(success, message, Hash.from_xml(response).values.first, :rates => rate_estimates, :xml => response, :request => last_request)
|
299
302
|
end
|
300
|
-
|
303
|
+
|
301
304
|
def parse_tracking_response(response, options={})
|
302
305
|
xml = REXML::Document.new(response)
|
303
306
|
success = response_success?(xml)
|
304
307
|
message = response_message(xml)
|
305
|
-
|
308
|
+
|
306
309
|
if success
|
307
310
|
tracking_number, origin, destination, status_code, status_description = nil
|
308
311
|
delivered, exception = false
|
@@ -314,7 +317,7 @@ module ActiveMerchant
|
|
314
317
|
first_shipment = xml.elements['/*/Shipment']
|
315
318
|
first_package = first_shipment.elements['Package']
|
316
319
|
tracking_number = first_shipment.get_text('ShipmentIdentificationNumber | Package/TrackingNumber').to_s
|
317
|
-
|
320
|
+
|
318
321
|
# Build status hash
|
319
322
|
status_node = first_package.elements['Activity/Status/StatusType']
|
320
323
|
status_code = status_node.get_text('Code').to_s
|
@@ -351,10 +354,10 @@ module ActiveMerchant
|
|
351
354
|
location = location_from_address_node(activity.elements['ActivityLocation/Address'])
|
352
355
|
ShipmentEvent.new(description, zoneless_time, location)
|
353
356
|
end
|
354
|
-
|
357
|
+
|
355
358
|
shipment_events = shipment_events.sort_by(&:time)
|
356
|
-
|
357
|
-
# UPS will sometimes archive a shipment, stripping all shipment activity except for the delivery
|
359
|
+
|
360
|
+
# UPS will sometimes archive a shipment, stripping all shipment activity except for the delivery
|
358
361
|
# event (see test/fixtures/xml/delivered_shipment_without_events_tracking_response.xml for an example).
|
359
362
|
# This adds an origin event to the shipment activity in such cases.
|
360
363
|
if origin && !(shipment_events.count == 1 && status == :delivered)
|
@@ -377,7 +380,7 @@ module ActiveMerchant
|
|
377
380
|
shipment_events[-1] = ShipmentEvent.new(shipment_events.last.name, shipment_events.last.time, destination)
|
378
381
|
end
|
379
382
|
end
|
380
|
-
|
383
|
+
|
381
384
|
end
|
382
385
|
TrackingResponse.new(success, message, Hash.from_xml(response).values.first,
|
383
386
|
:carrier => @@name,
|
@@ -395,7 +398,7 @@ module ActiveMerchant
|
|
395
398
|
:destination => destination,
|
396
399
|
:tracking_number => tracking_number)
|
397
400
|
end
|
398
|
-
|
401
|
+
|
399
402
|
def location_from_address_node(address)
|
400
403
|
return nil unless address
|
401
404
|
Location.new(
|
@@ -408,7 +411,7 @@ module ActiveMerchant
|
|
408
411
|
:address3 => node_text_or_nil(address.elements['AddressLine3'])
|
409
412
|
)
|
410
413
|
end
|
411
|
-
|
414
|
+
|
412
415
|
def parse_ups_datetime(options = {})
|
413
416
|
time, date = options[:time].to_s, options[:date].to_s
|
414
417
|
if time.nil?
|
@@ -424,29 +427,29 @@ module ActiveMerchant
|
|
424
427
|
def response_success?(xml)
|
425
428
|
xml.get_text('/*/Response/ResponseStatusCode').to_s == '1'
|
426
429
|
end
|
427
|
-
|
430
|
+
|
428
431
|
def response_message(xml)
|
429
432
|
xml.get_text('/*/Response/Error/ErrorDescription | /*/Response/ResponseStatusDescription').to_s
|
430
433
|
end
|
431
|
-
|
434
|
+
|
432
435
|
def commit(action, request, test = false)
|
433
436
|
ssl_post("#{test ? TEST_URL : LIVE_URL}/#{RESOURCES[action]}", request)
|
434
437
|
end
|
435
|
-
|
436
|
-
|
438
|
+
|
439
|
+
|
437
440
|
def service_name_for(origin, code)
|
438
441
|
origin = origin.country_code(:alpha2)
|
439
|
-
|
442
|
+
|
440
443
|
name = case origin
|
441
444
|
when "CA" then CANADA_ORIGIN_SERVICES[code]
|
442
445
|
when "MX" then MEXICO_ORIGIN_SERVICES[code]
|
443
446
|
when *EU_COUNTRY_CODES then EU_ORIGIN_SERVICES[code]
|
444
447
|
end
|
445
|
-
|
448
|
+
|
446
449
|
name ||= OTHER_NON_US_ORIGIN_SERVICES[code] unless name == 'US'
|
447
450
|
name ||= DEFAULT_SERVICES[code]
|
448
451
|
end
|
449
|
-
|
452
|
+
|
450
453
|
end
|
451
454
|
end
|
452
455
|
end
|