active_shipping 0.9.11 → 0.9.12
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/CHANGELOG
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
2011/04/21:
|
2
|
+
* USPS updated to use new APIs [james]
|
3
|
+
* new :gift boolean option for Package [james]
|
4
|
+
* Location's :address_type can be "po_box" [james]
|
5
|
+
|
6
|
+
Earlier:
|
1
7
|
* New Zealand Post [AbleTech]
|
2
8
|
* Include address name for rate requests to Shipwire if provided [dennis]
|
3
9
|
* Add support for address name to Location [dennis]
|
@@ -29,8 +29,8 @@ module ActiveMerchant
|
|
29
29
|
TEST_RESOURCE = 'ShippingAPITest.dll'
|
30
30
|
|
31
31
|
API_CODES = {
|
32
|
-
:us_rates => '
|
33
|
-
:world_rates => '
|
32
|
+
:us_rates => 'RateV4',
|
33
|
+
:world_rates => 'IntlRateV2',
|
34
34
|
:test => 'CarrierPickupAvailability'
|
35
35
|
}
|
36
36
|
USE_SSL = {
|
@@ -180,7 +180,7 @@ module ActiveMerchant
|
|
180
180
|
end
|
181
181
|
|
182
182
|
def world_rates(origin, destination, packages, options={})
|
183
|
-
request = build_world_rate_request(packages, destination
|
183
|
+
request = build_world_rate_request(packages, destination)
|
184
184
|
# never use test mode; rate requests just won't work on test servers
|
185
185
|
parse_rate_response origin, destination, packages, commit(:world_rates,request,false), options
|
186
186
|
end
|
@@ -204,7 +204,7 @@ module ActiveMerchant
|
|
204
204
|
# "machinability" entirely.
|
205
205
|
def build_us_rate_request(packages, origin_zip, destination_zip, options={})
|
206
206
|
packages = Array(packages)
|
207
|
-
request = XmlNode.new('
|
207
|
+
request = XmlNode.new('RateV4Request', :USERID => @options[:login]) do |rate_request|
|
208
208
|
packages.each_with_index do |p,id|
|
209
209
|
rate_request << XmlNode.new('Package', :ID => id.to_s) do |package|
|
210
210
|
package << XmlNode.new('Service', US_SERVICES[options[:service] || :all])
|
@@ -212,9 +212,7 @@ module ActiveMerchant
|
|
212
212
|
package << XmlNode.new('ZipDestination', strip_zip(destination_zip))
|
213
213
|
package << XmlNode.new('Pounds', 0)
|
214
214
|
package << XmlNode.new('Ounces', "%0.1f" % [p.ounces,1].max)
|
215
|
-
|
216
|
-
package << XmlNode.new('Container', CONTAINERS[p.options[:container]])
|
217
|
-
end
|
215
|
+
package << XmlNode.new('Container', CONTAINERS[p.options[:container]])
|
218
216
|
package << XmlNode.new('Size', USPS.size_code_for(p))
|
219
217
|
package << XmlNode.new('Width', p.inches(:width))
|
220
218
|
package << XmlNode.new('Length', p.inches(:length))
|
@@ -241,21 +239,34 @@ module ActiveMerchant
|
|
241
239
|
#
|
242
240
|
# package.options[:mail_type] -- one of [:package, :postcard, :matter_for_the_blind, :envelope].
|
243
241
|
# Defaults to :package.
|
244
|
-
def build_world_rate_request(packages,
|
245
|
-
country = COUNTRY_NAME_CONVERSIONS[
|
246
|
-
request = XmlNode.new('
|
242
|
+
def build_world_rate_request(packages, destination)
|
243
|
+
country = COUNTRY_NAME_CONVERSIONS[destination.country.code(:alpha2).value] || destination.country.name
|
244
|
+
request = XmlNode.new('IntlRateV2Request', :USERID => @options[:login]) do |rate_request|
|
247
245
|
packages.each_index do |id|
|
248
246
|
p = packages[id]
|
249
247
|
rate_request << XmlNode.new('Package', :ID => id.to_s) do |package|
|
250
248
|
package << XmlNode.new('Pounds', 0)
|
251
249
|
package << XmlNode.new('Ounces', [p.ounces,1].max.ceil) #takes an integer for some reason, must be rounded UP
|
252
250
|
package << XmlNode.new('MailType', MAIL_TYPES[p.options[:mail_type]] || 'Package')
|
253
|
-
|
254
|
-
|
251
|
+
package << XmlNode.new('GXG') do |gxg|
|
252
|
+
gxg << XmlNode.new('POBoxFlag', destination.po_box? ? 'Y' : 'N')
|
253
|
+
gxg << XmlNode.new('GiftFlag', p.gift? ? 'Y' : 'N')
|
254
|
+
end
|
255
|
+
value = if p.value && p.value > 0 && p.currency && p.currency != 'USD'
|
256
|
+
0.0
|
257
|
+
else
|
258
|
+
(p.value || 0) / 100.0
|
255
259
|
end
|
260
|
+
package << XmlNode.new('ValueOfContents', value)
|
256
261
|
package << XmlNode.new('Country') do |node|
|
257
262
|
node.cdata = country
|
258
263
|
end
|
264
|
+
package << XmlNode.new('Container', p.cylinder? ? 'NONRECTANGULAR' : 'RECTANGULAR')
|
265
|
+
package << XmlNode.new('Size', USPS.size_code_for(p))
|
266
|
+
package << XmlNode.new('Width', [p.inches(:width), 0.01].max)
|
267
|
+
package << XmlNode.new('Length', [p.inches(:length), 0.01].max)
|
268
|
+
package << XmlNode.new('Height', [p.inches(:height), 0.01].max)
|
269
|
+
package << XmlNode.new('Girth', [p.inches(:girth), 0.01].max)
|
259
270
|
end
|
260
271
|
end
|
261
272
|
end
|
@@ -285,41 +296,49 @@ module ActiveMerchant
|
|
285
296
|
rate_hash = rates_from_response_node(xml, packages)
|
286
297
|
unless rate_hash
|
287
298
|
success = false
|
288
|
-
message = "Unknown root node in XML response: '#{
|
299
|
+
message = "Unknown root node in XML response: '#{xml.root.name}'"
|
289
300
|
end
|
290
301
|
end
|
291
302
|
|
292
303
|
end
|
293
304
|
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
305
|
+
if success
|
306
|
+
rate_estimates = rate_hash.keys.map do |service_name|
|
307
|
+
RateEstimate.new(origin,destination,@@name,"USPS #{service_name}",
|
308
|
+
:package_rates => rate_hash[service_name][:package_rates],
|
309
|
+
:service_code => rate_hash[service_name][:service_code],
|
310
|
+
:currency => 'USD')
|
311
|
+
end
|
312
|
+
rate_estimates.reject! {|e| e.package_count != packages.length}
|
313
|
+
rate_estimates = rate_estimates.sort_by(&:total_price)
|
299
314
|
end
|
300
|
-
rate_estimates.reject! {|e| e.package_count != packages.length}
|
301
|
-
rate_estimates = rate_estimates.sort_by(&:total_price)
|
302
315
|
|
303
316
|
RateResponse.new(success, message, Hash.from_xml(response), :rates => rate_estimates, :xml => response, :request => last_request)
|
304
317
|
end
|
305
318
|
|
306
319
|
def rates_from_response_node(response_node, packages)
|
307
320
|
rate_hash = {}
|
308
|
-
return false unless (root_node = response_node.elements['/
|
309
|
-
domestic = (root_node.name == '
|
321
|
+
return false unless (root_node = response_node.elements['/IntlRateV2Response | /RateV4Response'])
|
322
|
+
domestic = (root_node.name == 'RateV4Response')
|
310
323
|
|
311
324
|
domestic_elements = ['Postage', 'CLASSID', 'MailService', 'Rate']
|
312
325
|
international_elements = ['Service', 'ID', 'SvcDescription', 'Postage']
|
313
326
|
service_node, service_code_node, service_name_node, rate_node = domestic ? domestic_elements : international_elements
|
314
327
|
|
315
328
|
root_node.each_element('Package') do |package_node|
|
316
|
-
|
329
|
+
this_package = packages[package_node.attributes['ID'].to_i]
|
317
330
|
|
318
331
|
package_node.each_element(service_node) do |service_response_node|
|
319
332
|
service_name = service_response_node.get_text(service_name_node).to_s
|
320
333
|
|
321
|
-
#
|
322
|
-
service_name.gsub!(/&lt
|
334
|
+
# strips the double-escaped HTML for trademark symbols from service names
|
335
|
+
service_name.gsub!(/&lt;\S*&gt;/,'')
|
336
|
+
# ...leading "USPS"
|
337
|
+
service_name.gsub!(/^USPS/,'')
|
338
|
+
# ...trailing asterisks
|
339
|
+
service_name.gsub!(/\*+$/,'')
|
340
|
+
# ...surrounding spaces
|
341
|
+
service_name.strip!
|
323
342
|
|
324
343
|
# aggregate specific package rates into a service-centric RateEstimate
|
325
344
|
# first package with a given service name will initialize these;
|
@@ -327,7 +346,7 @@ module ActiveMerchant
|
|
327
346
|
this_service = rate_hash[service_name] ||= {}
|
328
347
|
this_service[:service_code] ||= service_response_node.attributes[service_code_node]
|
329
348
|
package_rates = this_service[:package_rates] ||= []
|
330
|
-
this_package_rate = {:package =>
|
349
|
+
this_package_rate = {:package => this_package,
|
331
350
|
:rate => Package.cents_from(service_response_node.get_text(rate_node).to_s.to_f)}
|
332
351
|
|
333
352
|
package_rates << this_package_rate if package_valid_for_service(this_package,service_response_node)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module ActiveMerchant #:nodoc:
|
2
2
|
module Shipping #:nodoc:
|
3
3
|
class Location
|
4
|
+
ADDRESS_TYPES = %w{residential commercial po_box}
|
4
5
|
|
5
6
|
attr_reader :options,
|
6
7
|
:country,
|
@@ -34,8 +35,12 @@ module ActiveMerchant #:nodoc:
|
|
34
35
|
@address3 = options[:address3]
|
35
36
|
@phone = options[:phone]
|
36
37
|
@fax = options[:fax]
|
37
|
-
|
38
|
-
|
38
|
+
if options[:address_type].present?
|
39
|
+
@address_type = options[:address_type].to_s
|
40
|
+
unless ADDRESS_TYPES.include?(@address_type)
|
41
|
+
raise ArgumentError.new("address_type must be one of #{ADDRESS_TYPES.map(&:inspect).join(', ')}")
|
42
|
+
end
|
43
|
+
end
|
39
44
|
end
|
40
45
|
|
41
46
|
def self.from(object, options={})
|
@@ -68,7 +73,7 @@ module ActiveMerchant #:nodoc:
|
|
68
73
|
end
|
69
74
|
end
|
70
75
|
end
|
71
|
-
attributes.delete(:address_type) unless
|
76
|
+
attributes.delete(:address_type) unless ADDRESS_TYPES.include?(attributes[:address_type].to_s)
|
72
77
|
self.new(attributes.update(options))
|
73
78
|
end
|
74
79
|
|
@@ -76,8 +81,9 @@ module ActiveMerchant #:nodoc:
|
|
76
81
|
@country.nil? ? nil : @country.code(format).value
|
77
82
|
end
|
78
83
|
|
79
|
-
def residential?;
|
80
|
-
def commercial?;
|
84
|
+
def residential?; @address_type == 'residential' end
|
85
|
+
def commercial?; @address_type == 'commercial' end
|
86
|
+
def po_box?; @address_type == 'po_box' end
|
81
87
|
|
82
88
|
def to_s
|
83
89
|
prettyprint.gsub(/\n/, ' ')
|
@@ -32,6 +32,7 @@ module ActiveMerchant #:nodoc:
|
|
32
32
|
@value = Package.cents_from(options[:value])
|
33
33
|
@currency = options[:currency] || (options[:value].currency if options[:value].respond_to?(:currency))
|
34
34
|
@cylinder = (options[:cylinder] || options[:tube]) ? true : false
|
35
|
+
@gift = options[:gift] ? true : false
|
35
36
|
end
|
36
37
|
|
37
38
|
def cylinder?
|
@@ -39,6 +40,8 @@ module ActiveMerchant #:nodoc:
|
|
39
40
|
end
|
40
41
|
alias_method :tube?, :cylinder?
|
41
42
|
|
43
|
+
def gift?; @gift end
|
44
|
+
|
42
45
|
def ounces(options={})
|
43
46
|
weight(options).in_ounces.amount
|
44
47
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_shipping
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 35
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 9
|
9
|
-
-
|
10
|
-
version: 0.9.
|
9
|
+
- 12
|
10
|
+
version: 0.9.12
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- James MacAulay
|
@@ -18,7 +18,7 @@ autorequire:
|
|
18
18
|
bindir: bin
|
19
19
|
cert_chain: []
|
20
20
|
|
21
|
-
date: 2011-
|
21
|
+
date: 2011-04-21 00:00:00 -04:00
|
22
22
|
default_executable:
|
23
23
|
dependencies:
|
24
24
|
- !ruby/object:Gem::Dependency
|
@@ -146,7 +146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
146
146
|
requirements: []
|
147
147
|
|
148
148
|
rubyforge_project: active_shipping
|
149
|
-
rubygems_version: 1.
|
149
|
+
rubygems_version: 1.6.2
|
150
150
|
signing_key:
|
151
151
|
specification_version: 3
|
152
152
|
summary: Shipping API extension for Active Merchant
|