active_shipping 1.14.2 → 2.0.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.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -25
  3. data/CHANGELOG.md +5 -0
  4. data/CONTRIBUTING.md +2 -0
  5. data/README.md +2 -8
  6. data/active_shipping.gemspec +9 -3
  7. data/gemfiles/activesupport42.gemfile +0 -1
  8. data/lib/active_shipping.rb +1 -1
  9. data/lib/active_shipping/carrier.rb +2 -4
  10. data/lib/active_shipping/carriers/australia_post.rb +2 -4
  11. data/lib/active_shipping/carriers/canada_post.rb +1 -1
  12. data/lib/active_shipping/carriers/canada_post_pws.rb +33 -37
  13. data/lib/active_shipping/carriers/correios.rb +0 -2
  14. data/lib/active_shipping/carriers/new_zealand_post.rb +0 -2
  15. data/lib/active_shipping/carriers/ups.rb +0 -2
  16. data/lib/active_shipping/carriers/usps.rb +1 -3
  17. data/lib/active_shipping/external_return_label_request.rb +0 -4
  18. data/lib/active_shipping/location.rb +65 -52
  19. data/lib/active_shipping/package.rb +17 -21
  20. data/lib/active_shipping/package_item.rb +8 -20
  21. data/lib/active_shipping/rate_estimate.rb +1 -1
  22. data/lib/active_shipping/version.rb +1 -1
  23. data/test/fixtures/xml/canadapost/example_request.xml +3 -3
  24. data/test/helpers/holiday_helpers.rb +54 -0
  25. data/test/remote/australia_post_test.rb +1 -1
  26. data/test/remote/canada_post_pws_platform_test.rb +1 -3
  27. data/test/remote/canada_post_pws_test.rb +1 -1
  28. data/test/remote/canada_post_test.rb +1 -1
  29. data/test/remote/correios_test.rb +1 -2
  30. data/test/remote/fedex_test.rb +8 -8
  31. data/test/remote/kunaki_test.rb +1 -1
  32. data/test/remote/new_zealand_post_test.rb +1 -1
  33. data/test/remote/shipwire_test.rb +1 -1
  34. data/test/remote/stamps_test.rb +7 -7
  35. data/test/remote/ups_surepost_test.rb +1 -1
  36. data/test/remote/ups_test.rb +13 -11
  37. data/test/remote/usps_returns_test.rb +1 -1
  38. data/test/remote/usps_test.rb +5 -5
  39. data/test/test_helper.rb +16 -6
  40. data/test/unit/carrier_test.rb +25 -25
  41. data/test/unit/carriers/australia_post_test.rb +5 -5
  42. data/test/unit/carriers/benchmark_test.rb +1 -1
  43. data/test/unit/carriers/canada_post_pws_rating_test.rb +1 -15
  44. data/test/unit/carriers/canada_post_pws_register_test.rb +1 -15
  45. data/test/unit/carriers/canada_post_pws_shipping_test.rb +1 -13
  46. data/test/unit/carriers/canada_post_pws_test.rb +4 -4
  47. data/test/unit/carriers/canada_post_pws_tracking_test.rb +1 -1
  48. data/test/unit/carriers/canada_post_test.rb +9 -9
  49. data/test/unit/carriers/correios_test.rb +1 -2
  50. data/test/unit/carriers/fedex_test.rb +5 -5
  51. data/test/unit/carriers/kunaki_test.rb +1 -1
  52. data/test/unit/carriers/new_zealand_post_test.rb +9 -10
  53. data/test/unit/carriers/shipwire_test.rb +1 -1
  54. data/test/unit/carriers/stamps_test.rb +1 -1
  55. data/test/unit/carriers/ups_test.rb +1 -1
  56. data/test/unit/carriers/usps_returns_test.rb +1 -1
  57. data/test/unit/carriers/usps_test.rb +1 -1
  58. data/test/unit/carriers_test.rb +4 -5
  59. data/test/unit/external_return_label_request_test.rb +129 -83
  60. data/test/unit/location_test.rb +187 -91
  61. data/test/unit/package_item_test.rb +42 -47
  62. data/test/unit/package_test.rb +76 -75
  63. data/test/unit/rate_estimate_test.rb +16 -20
  64. data/test/unit/response_test.rb +28 -9
  65. data/test/unit/shipment_event_test.rb +1 -1
  66. data/test/unit/shipment_packer_test.rb +31 -31
  67. data/test/unit/tracking_response_test.rb +1 -1
  68. metadata +71 -23
  69. data/gemfiles/activesupport32.gemfile +0 -7
  70. data/gemfiles/activesupport32_nokogiri_17.gemfile +0 -7
  71. data/gemfiles/activesupport40.gemfile +0 -6
  72. data/gemfiles/activesupport40_nokogiri_17.gemfile +0 -6
  73. data/gemfiles/activesupport41.gemfile +0 -6
  74. data/gemfiles/activesupport41_nokogiri_17.gemfile +0 -6
  75. data/gemfiles/activesupport42_nokogiri_17.gemfile +0 -6
  76. data/test/fixtures/xml/canadapost_pws/merchant_details_response_no_contract_number.xml +0 -7
  77. data/test/fixtures/xml/canadapost_pws/service_options_response_priority_worldwide.xml +0 -41
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1cdf320ee4f62ffc781b724b4a1062cca673d55b
4
- data.tar.gz: 751db33e450bb92c8b9b8b38911716450e51f364
3
+ metadata.gz: 8daef7547a1eadf200bb06247f518cc9e5813a31
4
+ data.tar.gz: ea7675b5b350fdf8ea1372e87f22b3efcb99f74f
5
5
  SHA512:
6
- metadata.gz: 2cb07bbdefd76c3ae7a05f523d42d4f79de0daecfa2688ee708c79dc369e81fb475f153c777e29cd896018bf686afa6f9cc93a9f153c1d2903695e79053e4d2f
7
- data.tar.gz: 04e6be9e02c295e14b725dfbe0c193d400445e2b487ba7193899053e2c81c8d9dfbf544cd699afaac03ca0d4bb221b65b2f023edfdd507ed988ff06ef5766105
6
+ metadata.gz: a2b9295a91d1a7af45debd3c659588b9e3f86fb212d266c58d4274a60db07f760ff0833dd01795ad69449bceafb3de154dcef1999c80c8bd26df753292f45c45
7
+ data.tar.gz: c1390c553d52b92720f7219ce72ee8f68589361b342346a8b88b2b616c1b668931472c17d816aeb4c74c91e35394e5c355b2428679d492d32d2969da1e08db5d
@@ -3,41 +3,19 @@ script: bundle exec rake test
3
3
  sudo: false
4
4
 
5
5
  rvm:
6
- - "2.0"
7
- - "2.1"
8
6
  - "2.2.2"
9
7
  - "2.3.1"
8
+ - "2.4.0"
10
9
 
11
10
  gemfile:
12
- - gemfiles/activesupport32.gemfile
13
- - gemfiles/activesupport32_nokogiri_17.gemfile
14
- - gemfiles/activesupport40.gemfile
15
- - gemfiles/activesupport40_nokogiri_17.gemfile
16
- - gemfiles/activesupport41.gemfile
17
- - gemfiles/activesupport41_nokogiri_17.gemfile
18
11
  - gemfiles/activesupport42.gemfile
19
- - gemfiles/activesupport42_nokogiri_17.gemfile
20
12
  - gemfiles/activesupport50.gemfile
21
13
  - gemfiles/activesupport_master.gemfile
22
14
 
23
15
  matrix:
24
16
  exclude:
25
- - rvm: "2.0"
26
- gemfile: gemfiles/activesupport32_nokogiri_17.gemfile
27
- - rvm: "2.0"
28
- gemfile: gemfiles/activesupport40_nokogiri_17.gemfile
29
- - rvm: "2.0"
30
- gemfile: gemfiles/activesupport41_nokogiri_17.gemfile
31
- - rvm: "2.0"
32
- gemfile: gemfiles/activesupport42_nokogiri_17.gemfile
33
- - rvm: "2.0"
34
- gemfile: gemfiles/activesupport50.gemfile
35
- - rvm: "2.0"
36
- gemfile: gemfiles/activesupport_master.gemfile
37
- - rvm: "2.1"
38
- gemfile: gemfiles/activesupport50.gemfile
39
- - rvm: "2.1"
40
- gemfile: gemfiles/activesupport_master.gemfile
17
+ - rvm: "2.4.0"
18
+ gemfile: gemfiles/activesupport42.gemfile
41
19
 
42
20
  env:
43
21
  global:
@@ -1,5 +1,10 @@
1
1
  # ActiveShipping CHANGELOG
2
2
 
3
+ ### v2.0.0
4
+ - Drop support for < ruby 2.2, support ruby 2.4
5
+ - Drop support for < Rails 4.2.
6
+ - BREAKING CHANGE: Use shopify/measured instead of shopify/quantified for dimensions and units.
7
+
3
8
  ### v1.14.2
4
9
  - Make saturday delivery an option for fedex
5
10
 
@@ -2,6 +2,8 @@
2
2
 
3
3
  We love receiving pull requests! Anything from new carriers to documentation fixes.
4
4
 
5
+ Also, we are looking for maintainers for the current version of ActiveShipping 2.0.
6
+
5
7
  ## Standards
6
8
 
7
9
  * PR should explain what the feature does, and why the change exists.
data/README.md CHANGED
@@ -7,9 +7,6 @@ This library interfaces with the web services of various shipping carriers. The
7
7
  - Tracking shipments
8
8
  - Purchasing shipping labels
9
9
 
10
- Active Shipping is currently being used and improved in a production environment for [Shopify](http://shopify.com).
11
-
12
-
13
10
  ## Supported Shipping Carriers
14
11
 
15
12
  * [UPS](http://www.ups.com)
@@ -25,11 +22,8 @@ Active Shipping is currently being used and improved in a production environment
25
22
 
26
23
 
27
24
  ## Versions
28
-
29
- Development on `master` is for a pre-release of the `2.x` version of this gem. It includes a number of backwards incompatible changes and improvements. Progress can be tracked in [the milestone](https://github.com/Shopify/active_shipping/milestone/1).
30
-
31
- We are no longer actively developing version `1.x`. We have released `1.9` and will only backport small fixes to this version, on branch `1-9-stable`, and they should be on `master` first.
32
-
25
+ Note: `2.x` contains breaking changes, please see the [changelog](https://github.com/Shopify/active_shipping/blob/master/CHANGELOG.md). Shopify will not be actively contibuting to the 2.0 version of this gem and is looking for maintainers.
26
+ We have released `1.9` and will only backport small fixes to this version, on branch `1-9-stable`, and they should be on `master` first.
33
27
 
34
28
  ## Installation
35
29
 
@@ -17,16 +17,22 @@ Gem::Specification.new do |s|
17
17
  s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
18
  s.test_files = s.files.grep(%r{^(test|spec|features)/})
19
19
  s.require_path = "lib"
20
+ s.post_install_message = "Thanks for installing ActiveShipping! If upgrading to v2.0, please see the changelog for breaking changes: https://github.com/Shopify/active_shipping/blob/master/CHANGELOG.md."
20
21
 
21
- s.add_dependency("quantified", "~> 1.0.1")
22
- s.add_dependency("activesupport", ">= 3.2", "< 5.2.0")
22
+
23
+ s.add_dependency("measured", ">= 2.0")
24
+ s.add_dependency("activesupport", ">= 4.2", "< 5.2.0")
23
25
  s.add_dependency("active_utils", "~> 3.3.1")
24
- s.add_dependency("nokogiri", ">= 1.6.8")
26
+ s.add_dependency("nokogiri", ">= 1.6")
25
27
 
26
28
  s.add_development_dependency("minitest")
29
+ s.add_development_dependency("minitest-reporters")
27
30
  s.add_development_dependency("rake")
28
31
  s.add_development_dependency("mocha", "~> 1")
29
32
  s.add_development_dependency("timecop")
30
33
  s.add_development_dependency("business_time")
31
34
  s.add_development_dependency("pry")
35
+ s.add_development_dependency("pry-byebug")
36
+ s.add_development_dependency("vcr")
37
+ s.add_development_dependency("webmock")
32
38
  end
@@ -2,5 +2,4 @@ source "https://rubygems.org"
2
2
 
3
3
  gemspec path: '..'
4
4
 
5
- gem 'nokogiri', '= 1.6.8'
6
5
  gem 'activesupport', '~> 4.2.0'
@@ -2,7 +2,7 @@ require 'active_support/all'
2
2
  require 'active_utils'
3
3
 
4
4
  require 'nokogiri'
5
- require 'quantified'
5
+ require 'measured'
6
6
 
7
7
  require 'active_shipping/response'
8
8
  require 'active_shipping/rate_response'
@@ -18,8 +18,6 @@ module ActiveShipping
18
18
  # The last request performed against the carrier's API.
19
19
  # @see #save_request
20
20
  class Carrier
21
- include Quantified
22
-
23
21
  attr_reader :last_request
24
22
  attr_accessor :test_mode
25
23
  alias_method :test_mode?, :test_mode
@@ -122,9 +120,9 @@ module ActiveShipping
122
120
  end
123
121
 
124
122
  # The maximum weight the carrier will accept.
125
- # @return [Quantified::Mass]
123
+ # @return [Measured::Weight]
126
124
  def maximum_weight
127
- Mass.new(150, :pounds)
125
+ Measured::Weight.new(150, :pounds)
128
126
  end
129
127
 
130
128
  # The address field maximum length accepted by the carrier
@@ -1,5 +1,3 @@
1
- require 'active_support/core_ext/object/to_query'
2
-
3
1
  module ActiveShipping
4
2
  class AustraliaPost < Carrier
5
3
  cattr_reader :name
@@ -154,7 +152,7 @@ module ActiveShipping
154
152
  length: @package.cm(:length),
155
153
  width: @package.cm(:width),
156
154
  height: @package.cm(:height),
157
- weight: @package.weight.in_kg.to_f.round(2),
155
+ weight: @package.kilograms.to_f.round(2),
158
156
  from_postcode: @origin.postal_code,
159
157
  to_postcode: @destination.postal_code
160
158
  }
@@ -162,7 +160,7 @@ module ActiveShipping
162
160
 
163
161
  def international_params
164
162
  {
165
- weight: @package.weight.in_kg.to_f.round(2),
163
+ weight: @package.kilograms.to_f.round(2),
166
164
  country_code: @destination.country_code
167
165
  }
168
166
  end
@@ -86,7 +86,7 @@ module ActiveShipping
86
86
  end
87
87
 
88
88
  def maximum_weight
89
- Mass.new(30, :kilograms)
89
+ Measured::Weight.new(30, :kg)
90
90
  end
91
91
 
92
92
  def maximum_address_field_length
@@ -164,7 +164,7 @@ module ActiveShipping
164
164
  end
165
165
 
166
166
  def maximum_weight
167
- Mass.new(MAX_WEIGHT, :kilograms)
167
+ Measured::Weight.new(MAX_WEIGHT, :kg)
168
168
  end
169
169
 
170
170
  def maximum_address_field_length
@@ -214,14 +214,14 @@ module ActiveShipping
214
214
  restrictions_node = doc.root.at('restrictions')
215
215
  dimensions_node = restrictions_node.at('dimensional-restrictions')
216
216
  restrictions = {
217
- :min_weight => restrictions_node.at("weight-restriction").attributes['min'].try(:value).to_i,
218
- :max_weight => restrictions_node.at("weight-restriction").attributes['max'].try(:value).to_i,
219
- :min_length => dimensions_node.at("length").attributes['min'].try(:value).to_f,
220
- :max_length => dimensions_node.at("length").attributes['max'].try(:value).to_f,
221
- :min_height => dimensions_node.at("height").attributes['min'].try(:value).to_f,
222
- :max_height => dimensions_node.at("height").attributes['max'].try(:value).to_f,
223
- :min_width => dimensions_node.at("width").attributes['min'].try(:value).to_f,
224
- :max_width => dimensions_node.at("width").attributes['max'].try(:value).to_f
217
+ :min_weight => restrictions_node.at("weight-restriction").attributes['min'].value.to_i,
218
+ :max_weight => restrictions_node.at("weight-restriction").attributes['max'].value.to_i,
219
+ :min_length => dimensions_node.at("length").attributes['min'].value.to_f,
220
+ :max_length => dimensions_node.at("length").attributes['max'].value.to_f,
221
+ :min_height => dimensions_node.at("height").attributes['min'].value.to_f,
222
+ :max_height => dimensions_node.at("height").attributes['max'].value.to_f,
223
+ :min_width => dimensions_node.at("width").attributes['min'].value.to_f,
224
+ :max_width => dimensions_node.at("width").attributes['max'].value.to_f
225
225
  }
226
226
 
227
227
  {
@@ -526,7 +526,7 @@ module ActiveShipping
526
526
  raise "No Merchant Info" if doc.root.at('customer-number').blank?
527
527
  options = {
528
528
  :customer_number => doc.root.at('customer-number').text,
529
- :contract_number => doc.root.at('contract-number').try(:text),
529
+ :contract_number => doc.root.at('contract-number').text,
530
530
  :username => doc.root.at('merchant-username').text,
531
531
  :password => doc.root.at('merchant-password').text,
532
532
  :has_default_credit_card => doc.root.at('has-default-credit-card').text == 'true'
@@ -728,43 +728,39 @@ module ActiveShipping
728
728
 
729
729
  def shipping_options_node(xml, available_options, options = {})
730
730
  return if (options.symbolize_keys.keys & available_options).empty?
731
-
732
- options_doc = Nokogiri::XML::Builder.new do |options_xml|
733
- options_xml.public_send('options') do
734
- if options[:cod] && options[:cod_amount]
735
- options_xml.public_send('option') do
736
- options_xml.public_send('option-code', 'COD')
737
- options_xml.public_send('option-amount', options[:cod_amount])
738
- options_xml.public_send('option-qualifier-1', options[:cod_includes_shipping]) unless options[:cod_includes_shipping].blank?
739
- options_xml.public_send('option-qualifier-2', options[:cod_method_of_payment]) unless options[:cod_method_of_payment].blank?
740
- end
731
+ xml.public_send('options') do
732
+
733
+ if options[:cod] && options[:cod_amount]
734
+ xml.public_send('option') do
735
+ xml.public_send('option-code', 'COD')
736
+ xml.public_send('option-amount', options[:cod_amount])
737
+ xml.public_send('option-qualifier-1', options[:cod_includes_shipping]) unless options[:cod_includes_shipping].blank?
738
+ xml.public_send('option-qualifier-2', options[:cod_method_of_payment]) unless options[:cod_method_of_payment].blank?
741
739
  end
740
+ end
742
741
 
743
- if options[:cov]
744
- options_xml.public_send('option') do
745
- options_xml.public_send('option-code', 'COV')
746
- options_xml.public_send('option-amount', options[:cov_amount]) unless options[:cov_amount].blank?
747
- end
742
+ if options[:cov]
743
+ xml.public_send('option') do
744
+ xml.public_send('option-code', 'COV')
745
+ xml.public_send('option-amount', options[:cov_amount]) unless options[:cov_amount].blank?
748
746
  end
747
+ end
749
748
 
750
- if options[:d2po]
751
- options_xml.public_send('option') do
752
- options_xml.public_send('option-code', 'D2PO')
753
- options_xml.public_send('option-qualifier-2'. options[:d2po_office_id]) unless options[:d2po_office_id].blank?
754
- end
749
+ if options[:d2po]
750
+ xml.public_send('option') do
751
+ xml.public_send('option-code', 'D2PO')
752
+ xml.public_send('option-qualifier-2'. options[:d2po_office_id]) unless options[:d2po_office_id].blank?
755
753
  end
754
+ end
756
755
 
757
- [:so, :dc, :pa18, :pa19, :hfp, :dns, :lad, :rase, :rts, :aban].each do |code|
758
- if options[code]
759
- options_xml.public_send('option') do
760
- options_xml.public_send('option-code', code.to_s.upcase)
761
- end
756
+ [:so, :dc, :pa18, :pa19, :hfp, :dns, :lad, :rase, :rts, :aban].each do |code|
757
+ if options[code]
758
+ xml.public_send('option') do
759
+ xml.public_send('option-code', code.to_s.upcase)
762
760
  end
763
761
  end
764
762
  end
765
763
  end
766
-
767
- xml.parent << options_doc.doc.at("options") if options_doc.doc.at("options").children.any?
768
764
  end
769
765
 
770
766
  def expected_date_from_node(node)
@@ -1,5 +1,3 @@
1
- # -*- encoding utf-8 -*-
2
-
3
1
  module ActiveShipping
4
2
  class Correios < Carrier
5
3
 
@@ -1,5 +1,3 @@
1
- require 'active_support/core_ext/object/to_query'
2
-
3
1
  module ActiveShipping
4
2
  class NewZealandPost < Carrier
5
3
  cattr_reader :name
@@ -1,5 +1,3 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
1
  module ActiveShipping
4
2
  class UPS < Carrier
5
3
  self.retry_safe = true
@@ -1,5 +1,3 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
1
  module ActiveShipping
4
2
  # After getting an API login from USPS (looks like '123YOURNAME456'),
5
3
  # run the following test:
@@ -234,7 +232,7 @@ module ActiveShipping
234
232
  end
235
233
 
236
234
  def maximum_weight
237
- Mass.new(70, :pounds)
235
+ Measured::Weight.new(70, :pounds)
238
236
  end
239
237
 
240
238
  def extract_event_details(node)
@@ -1,8 +1,5 @@
1
- # -*- coding: utf-8 -*-
2
1
  module ActiveShipping
3
-
4
2
  class ExternalReturnLabelRequest
5
-
6
3
  CAP_STRING_LEN = 100
7
4
 
8
5
  USPS_EMAIL_REGEX = /^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/
@@ -416,6 +413,5 @@ module ActiveShipping
416
413
  raise USPSValidationError, "'#{v}' is not a valid e-mail in #{meth}"
417
414
  end
418
415
  end
419
-
420
416
  end
421
417
  end
@@ -2,6 +2,21 @@ module ActiveShipping #:nodoc:
2
2
  class Location
3
3
  ADDRESS_TYPES = %w(residential commercial po_box)
4
4
 
5
+ ATTRIBUTE_ALIASES = {
6
+ name: [:name],
7
+ country: [:country_code, :country],
8
+ postal_code: [:postal_code, :zip, :postal],
9
+ province: [:province_code, :state_code, :territory_code, :region_code, :province, :state, :territory, :region],
10
+ city: [:city, :town],
11
+ address1: [:address1, :address, :street],
12
+ address2: [:address2],
13
+ address3: [:address3],
14
+ phone: [:phone, :phone_number],
15
+ fax: [:fax, :fax_number],
16
+ address_type: [:address_type],
17
+ company_name: [:company, :company_name],
18
+ }.freeze
19
+
5
20
  attr_reader :options,
6
21
  :country,
7
22
  :postal_code,
@@ -24,9 +39,12 @@ module ActiveShipping #:nodoc:
24
39
  alias_method :company, :company_name
25
40
 
26
41
  def initialize(options = {})
27
- @country = (options[:country].nil? or options[:country].is_a?(ActiveUtils::Country)) ?
28
- options[:country] :
29
- ActiveUtils::Country.find(options[:country])
42
+ @country = if options[:country].nil? || options[:country].is_a?(ActiveUtils::Country)
43
+ options[:country]
44
+ else
45
+ ActiveUtils::Country.find(options[:country])
46
+ end
47
+
30
48
  @postal_code = options[:postal_code] || options[:postal] || options[:zip]
31
49
  @province = options[:province] || options[:state] || options[:territory] || options[:region]
32
50
  @city = options[:city]
@@ -42,37 +60,27 @@ module ActiveShipping #:nodoc:
42
60
  end
43
61
 
44
62
  def self.from(object, options = {})
45
- return object if object.is_a? ActiveShipping::Location
46
- attr_mappings = {
47
- :name => [:name],
48
- :country => [:country_code, :country],
49
- :postal_code => [:postal_code, :zip, :postal],
50
- :province => [:province_code, :state_code, :territory_code, :region_code, :province, :state, :territory, :region],
51
- :city => [:city, :town],
52
- :address1 => [:address1, :address, :street],
53
- :address2 => [:address2],
54
- :address3 => [:address3],
55
- :phone => [:phone, :phone_number],
56
- :fax => [:fax, :fax_number],
57
- :address_type => [:address_type],
58
- :company_name => [:company, :company_name]
59
- }
63
+ return object if object.is_a?(ActiveShipping::Location)
64
+
60
65
  attributes = {}
61
- hash_access = begin
62
- object[:some_symbol]
63
- true
64
- rescue
65
- false
66
- end
67
- attr_mappings.each do |pair|
68
- pair[1].each do |sym|
69
- if value = (object[sym] if hash_access) || (object.send(sym) if object.respond_to?(sym) && (!hash_access || !Hash.public_instance_methods.include?(sym.to_s)))
70
- attributes[pair[0]] = value
71
- break
66
+
67
+ hash_access = object.respond_to?(:[])
68
+
69
+ ATTRIBUTE_ALIASES.each do |attribute, aliases|
70
+ aliases.detect do |sym|
71
+ value = object[sym] if hash_access
72
+ if !value &&
73
+ object.respond_to?(sym) &&
74
+ (!hash_access || !Hash.public_instance_methods.include?(sym))
75
+ value = object.send(sym)
72
76
  end
77
+
78
+ attributes[attribute] = value if value
73
79
  end
74
80
  end
81
+
75
82
  attributes.delete(:address_type) unless ADDRESS_TYPES.include?(attributes[:address_type].to_s)
83
+
76
84
  new(attributes.update(options))
77
85
  end
78
86
 
@@ -80,10 +88,21 @@ module ActiveShipping #:nodoc:
80
88
  @country.nil? ? nil : @country.code(format).value
81
89
  end
82
90
 
83
- def residential?; @address_type == 'residential' end
84
- def commercial?; @address_type == 'commercial' end
85
- def po_box?; @address_type == 'po_box' end
86
- def unknown?; country_code == 'ZZ' end
91
+ def residential?
92
+ @address_type == 'residential'
93
+ end
94
+
95
+ def commercial?
96
+ @address_type == 'commercial'
97
+ end
98
+
99
+ def po_box?
100
+ @address_type == 'po_box'
101
+ end
102
+
103
+ def unknown?
104
+ country_code == 'ZZ'
105
+ end
87
106
 
88
107
  def address_type=(value)
89
108
  return unless value.present?
@@ -93,18 +112,18 @@ module ActiveShipping #:nodoc:
93
112
 
94
113
  def to_hash
95
114
  {
96
- :country => country_code,
97
- :postal_code => postal_code,
98
- :province => province,
99
- :city => city,
100
- :name => name,
101
- :address1 => address1,
102
- :address2 => address2,
103
- :address3 => address3,
104
- :phone => phone,
105
- :fax => fax,
106
- :address_type => address_type,
107
- :company_name => company_name
115
+ country: country_code,
116
+ postal_code: postal_code,
117
+ province: province,
118
+ city: city,
119
+ name: name,
120
+ address1: address1,
121
+ address2: address2,
122
+ address3: address3,
123
+ phone: phone,
124
+ fax: fax,
125
+ address_type: address_type,
126
+ company_name: company_name
108
127
  }
109
128
  end
110
129
 
@@ -128,13 +147,7 @@ module ActiveShipping #:nodoc:
128
147
 
129
148
  # Returns the postal code as a properly formatted Zip+4 code, e.g. "77095-2233"
130
149
  def zip_plus_4
131
- if /(\d{5})(\d{4})/ =~ @postal_code
132
- return "#{$1}-#{$2}"
133
- elsif /\d{5}-\d{4}/ =~ @postal_code
134
- return @postal_code
135
- else
136
- nil
137
- end
150
+ "#{$1}-#{$2}" if /(\d{5})-?(\d{4})/ =~ @postal_code
138
151
  end
139
152
 
140
153
  def address2_and_3