active_shipping 0.9.15 → 0.10.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.
- 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
|