From 7411f9a463c6181846c00c59651d305718a26eee Mon Sep 17 00:00:00 2001 From: pborel Date: Wed, 9 Nov 2016 17:12:34 -0500 Subject: [PATCH 01/11] WIP adds ability to use USPS address standardization --- lib/active_shipping/carriers/usps.rb | 77 +++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/lib/active_shipping/carriers/usps.rb b/lib/active_shipping/carriers/usps.rb index 6afd4e2f8..36d39e325 100644 --- a/lib/active_shipping/carriers/usps.rb +++ b/lib/active_shipping/carriers/usps.rb @@ -229,6 +229,18 @@ def find_rates(origin, destination, packages, options = {}) end end + def standardize_address(addresses, options = {}) + options = @options.merge(options) + + locations = [] + addresses.each { |address| locations << Location.from(address) } + build_address_standardization_request(locations) + + request = build_address_standardization_request(origin, packages, destination, options) + + parse_address_standardize_response(commit(:world_rates, request, false), addresses, options) + end + def valid_credentials? # Cannot test with find_rates because USPS doesn't allow that in test mode test_mode? ? canned_address_verification_works? : super @@ -515,6 +527,70 @@ def rates_from_response_node(response_node, packages, options = {}) rate_hash end + def build_address_standardization_request(addresses, options) + xml_builder = Nokogiri::XML::Builder.new do |xml| + xml.AddressValidateRequest('USERID' => @options[:login]) do + xml.IncludeOptionalElements = true + xml.ReturnCarrierRoute = true + Array(addresses).each_with_index do |package, id| + xml.Address('ID' => id) do + xml.FirmName = addresses[:FirmName] + xml.Address1 = addresses[:Address1] + xml.Address2 = addresses[:Address2] + xml.City = addresses[:City] + xml.State = addresses[:State] + xml.Zip5 = addresses[:Zip5] + xml.Zip4 = addresses[:Zip4] + end + end + end + end + save_request(xml_builder.to_xml) + end + + def parse_address_standardize_response(response, addresses, options = {}) + success = true + message = '' + address_hash = {} + + xml = Nokogiri.XML(response) + + if error = xml.at_xpath('/Error | //ServiceErrors/ServiceError') + success = false + message = error.at('Description').text + else + xml.root.xpath('Address').each do |address| + if address.at('Error') + success = false + message = package.at('Error/Description').text + break + end + end + + if success + address_hash = addresses_from_response_node(xml, addresses, options) + unless address_hash + success = false + message = "Unknown root node in XML response: '#{xml.root.name}'" + end + end + + end + + if success + addresses = address_hash.keys.map do |address| + Location.new(:address1 => address_hash[address][:address1], + :address2 => address_hash[address][:address2], + :postal_code => address_hash[address][:zip5], + :city => address_hash[address][:city], + :state => address_hash[address][:state]) + end + addresses.reject! { |e| e.package_count != packages.length } + end + + AddressStandarizationResponse.new(success, message, Hash.from_xml(response), :xml => response, :request => last_request) + end + def package_valid_for_service(package, service_node) return true if service_node.at('MaxWeight').nil? max_weight = service_node.at('MaxWeight').text.to_f @@ -607,7 +683,6 @@ def parse_tracking_response(response, options = {}) end end - def parse_tracking_info(response, node) success = !has_error?(node) message = response_message(node) From 67f439a9055608811dcdb46bbaed71543861e7af Mon Sep 17 00:00:00 2001 From: pborel Date: Wed, 9 Nov 2016 17:46:21 -0500 Subject: [PATCH 02/11] adds AddressStandardizationResponse --- .../address_standardization_response.rb | 26 +++++++++++++++++++ lib/active_shipping/carriers/usps.rb | 20 +++++++------- 2 files changed, 36 insertions(+), 10 deletions(-) create mode 100644 lib/active_shipping/address_standardization_response.rb diff --git a/lib/active_shipping/address_standardization_response.rb b/lib/active_shipping/address_standardization_response.rb new file mode 100644 index 000000000..0d05fc01d --- /dev/null +++ b/lib/active_shipping/address_standardization_response.rb @@ -0,0 +1,26 @@ +module ActiveShipping + + # The `AddressStandarizationResponse` object is returned by the {ActiveShipping::Carrier#????} + # call. The most important method is {#standardize_addresses}, which will return a list of + # standardized, correctly-spelled, validated, full addresses. + # + # @note This only works for USPS and in the US + # + # @!attribute addresses + # The correct addresses returned from USPS + class AddressStandarizationResponse < Response + + attr_reader :addresses + + # Initializes a new AddressStandarizationResponse instance. + # + # @param success (see ActiveShipping::Response#initialize) + # @param message (see ActiveShipping::Response#initialize) + # @param params (see ActiveShipping::Response#initialize) + # @option options (see ActiveShipping::Response#initialize) + def initialize(success, message, params = {}, options = {}) + @addresses = Array(options[:addresses]) + super + end + end +end \ No newline at end of file diff --git a/lib/active_shipping/carriers/usps.rb b/lib/active_shipping/carriers/usps.rb index 36d39e325..6c59dfc7a 100644 --- a/lib/active_shipping/carriers/usps.rb +++ b/lib/active_shipping/carriers/usps.rb @@ -229,16 +229,16 @@ def find_rates(origin, destination, packages, options = {}) end end - def standardize_address(addresses, options = {}) - options = @options.merge(options) + def standardize_addresses(addresses, options = {}) + options = @options.merge(options) - locations = [] - addresses.each { |address| locations << Location.from(address) } - build_address_standardization_request(locations) + locations = [] + addresses.each { |address| locations << Location.from(address) } + build_address_standardization_request(locations) - request = build_address_standardization_request(origin, packages, destination, options) + request = build_address_standardization_request(origin, packages, destination, options) - parse_address_standardize_response(commit(:world_rates, request, false), addresses, options) + parse_address_standardize_response(commit(:world_rates, request, false), addresses, options) end def valid_credentials? @@ -530,7 +530,7 @@ def rates_from_response_node(response_node, packages, options = {}) def build_address_standardization_request(addresses, options) xml_builder = Nokogiri::XML::Builder.new do |xml| xml.AddressValidateRequest('USERID' => @options[:login]) do - xml.IncludeOptionalElements = true + xml.IncludeOptionalElements = true xml.ReturnCarrierRoute = true Array(addresses).each_with_index do |package, id| xml.Address('ID' => id) do @@ -578,7 +578,7 @@ def parse_address_standardize_response(response, addresses, options = {}) end if success - addresses = address_hash.keys.map do |address| + addresses = address_hash.keys.map do |address| Location.new(:address1 => address_hash[address][:address1], :address2 => address_hash[address][:address2], :postal_code => address_hash[address][:zip5], @@ -588,7 +588,7 @@ def parse_address_standardize_response(response, addresses, options = {}) addresses.reject! { |e| e.package_count != packages.length } end - AddressStandarizationResponse.new(success, message, Hash.from_xml(response), :xml => response, :request => last_request) + AddressStandarizationResponse.new(success, message, Hash.from_xml(response), :addresses => addresses, :xml => response, :request => last_request) end def package_valid_for_service(package, service_node) From 301462940914d2f4302bd739518d6bf36e890bf3 Mon Sep 17 00:00:00 2001 From: pborel Date: Wed, 9 Nov 2016 18:27:40 -0500 Subject: [PATCH 03/11] remove options b/c not used --- lib/active_shipping/carriers/usps.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/active_shipping/carriers/usps.rb b/lib/active_shipping/carriers/usps.rb index 6c59dfc7a..9bdbc9dc5 100644 --- a/lib/active_shipping/carriers/usps.rb +++ b/lib/active_shipping/carriers/usps.rb @@ -229,8 +229,8 @@ def find_rates(origin, destination, packages, options = {}) end end - def standardize_addresses(addresses, options = {}) - options = @options.merge(options) + def standardize_addresses(addresses) + # options = @options.merge(options) locations = [] addresses.each { |address| locations << Location.from(address) } From 05ab9ffe40fe9c06de92e5701d40db8cbfc09581 Mon Sep 17 00:00:00 2001 From: pborel Date: Wed, 9 Nov 2016 18:27:51 -0500 Subject: [PATCH 04/11] remove options b/c not used --- lib/active_shipping/carriers/usps.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/active_shipping/carriers/usps.rb b/lib/active_shipping/carriers/usps.rb index 9bdbc9dc5..43649fcbc 100644 --- a/lib/active_shipping/carriers/usps.rb +++ b/lib/active_shipping/carriers/usps.rb @@ -230,8 +230,6 @@ def find_rates(origin, destination, packages, options = {}) end def standardize_addresses(addresses) - # options = @options.merge(options) - locations = [] addresses.each { |address| locations << Location.from(address) } build_address_standardization_request(locations) From f0a6e68909cdbe82f6dc495b9510f0b362d1fcbb Mon Sep 17 00:00:00 2001 From: pborel Date: Wed, 9 Nov 2016 18:35:31 -0500 Subject: [PATCH 05/11] fix typo in naming of AddressStandardizationResponse class --- lib/active_shipping/address_standardization_response.rb | 2 +- lib/active_shipping/carriers/usps.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/active_shipping/address_standardization_response.rb b/lib/active_shipping/address_standardization_response.rb index 0d05fc01d..f8e453b99 100644 --- a/lib/active_shipping/address_standardization_response.rb +++ b/lib/active_shipping/address_standardization_response.rb @@ -8,7 +8,7 @@ module ActiveShipping # # @!attribute addresses # The correct addresses returned from USPS - class AddressStandarizationResponse < Response + class AddressStandardizationResponse < Response attr_reader :addresses diff --git a/lib/active_shipping/carriers/usps.rb b/lib/active_shipping/carriers/usps.rb index 43649fcbc..5bdf65788 100644 --- a/lib/active_shipping/carriers/usps.rb +++ b/lib/active_shipping/carriers/usps.rb @@ -586,7 +586,7 @@ def parse_address_standardize_response(response, addresses, options = {}) addresses.reject! { |e| e.package_count != packages.length } end - AddressStandarizationResponse.new(success, message, Hash.from_xml(response), :addresses => addresses, :xml => response, :request => last_request) + AddressStandardizationResponse.new(success, message, Hash.from_xml(response), :addresses => addresses, :xml => response, :request => last_request) end def package_valid_for_service(package, service_node) From e6c2b114a9c02a47f659636d1b18c75ff928f4d1 Mon Sep 17 00:00:00 2001 From: pborel Date: Wed, 9 Nov 2016 18:42:29 -0500 Subject: [PATCH 06/11] add options back to fix USPS api integration bug --- lib/active_shipping/carriers/usps.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/active_shipping/carriers/usps.rb b/lib/active_shipping/carriers/usps.rb index 5bdf65788..f65a1158a 100644 --- a/lib/active_shipping/carriers/usps.rb +++ b/lib/active_shipping/carriers/usps.rb @@ -229,10 +229,12 @@ def find_rates(origin, destination, packages, options = {}) end end - def standardize_addresses(addresses) + def standardize_addresses(addresses, options = {}) + options = @options.merge(options) + locations = [] addresses.each { |address| locations << Location.from(address) } - build_address_standardization_request(locations) + build_address_standardization_request(locations, options) request = build_address_standardization_request(origin, packages, destination, options) From 61d832a92a786a2e0b72d7e619c14b1696c0ad2a Mon Sep 17 00:00:00 2001 From: pborel Date: Wed, 9 Nov 2016 18:46:32 -0500 Subject: [PATCH 07/11] remove wrong method for setting result in standarize_addresses method --- lib/active_shipping/carriers/usps.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/active_shipping/carriers/usps.rb b/lib/active_shipping/carriers/usps.rb index f65a1158a..edd69d38d 100644 --- a/lib/active_shipping/carriers/usps.rb +++ b/lib/active_shipping/carriers/usps.rb @@ -234,9 +234,7 @@ def standardize_addresses(addresses, options = {}) locations = [] addresses.each { |address| locations << Location.from(address) } - build_address_standardization_request(locations, options) - - request = build_address_standardization_request(origin, packages, destination, options) + request = build_address_standardization_request(locations, options) parse_address_standardize_response(commit(:world_rates, request, false), addresses, options) end From 7ec09e02c676e57719f95181c6fb1b9d3b232732 Mon Sep 17 00:00:00 2001 From: pborel Date: Thu, 10 Nov 2016 12:12:53 -0500 Subject: [PATCH 08/11] remove unneeded param from standardize_addresses --- lib/active_shipping/carriers/usps.rb | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/active_shipping/carriers/usps.rb b/lib/active_shipping/carriers/usps.rb index edd69d38d..7183cd41b 100644 --- a/lib/active_shipping/carriers/usps.rb +++ b/lib/active_shipping/carriers/usps.rb @@ -229,12 +229,10 @@ def find_rates(origin, destination, packages, options = {}) end end - def standardize_addresses(addresses, options = {}) - options = @options.merge(options) - + def standardize_addresses(addresses) locations = [] addresses.each { |address| locations << Location.from(address) } - request = build_address_standardization_request(locations, options) + request = build_address_standardization_request(locations) parse_address_standardize_response(commit(:world_rates, request, false), addresses, options) end @@ -525,7 +523,7 @@ def rates_from_response_node(response_node, packages, options = {}) rate_hash end - def build_address_standardization_request(addresses, options) + def build_address_standardization_request(addresses) xml_builder = Nokogiri::XML::Builder.new do |xml| xml.AddressValidateRequest('USERID' => @options[:login]) do xml.IncludeOptionalElements = true From 63b38ec642fbaaba4db07046e58218e92da7f5da Mon Sep 17 00:00:00 2001 From: pborel Date: Thu, 10 Nov 2016 13:15:55 -0500 Subject: [PATCH 09/11] fixes object reference error --- lib/active_shipping/carriers/usps.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/active_shipping/carriers/usps.rb b/lib/active_shipping/carriers/usps.rb index 7183cd41b..486e7feda 100644 --- a/lib/active_shipping/carriers/usps.rb +++ b/lib/active_shipping/carriers/usps.rb @@ -581,7 +581,6 @@ def parse_address_standardize_response(response, addresses, options = {}) :city => address_hash[address][:city], :state => address_hash[address][:state]) end - addresses.reject! { |e| e.package_count != packages.length } end AddressStandardizationResponse.new(success, message, Hash.from_xml(response), :addresses => addresses, :xml => response, :request => last_request) From 5421ee6757f172858272e1445b3947ae8b0c739c Mon Sep 17 00:00:00 2001 From: pborel Date: Thu, 10 Nov 2016 13:33:45 -0500 Subject: [PATCH 10/11] adds xml to hash method for address --- lib/active_shipping/carriers/usps.rb | 143 +++++++++++++++------------ 1 file changed, 79 insertions(+), 64 deletions(-) diff --git a/lib/active_shipping/carriers/usps.rb b/lib/active_shipping/carriers/usps.rb index 486e7feda..21038eead 100644 --- a/lib/active_shipping/carriers/usps.rb +++ b/lib/active_shipping/carriers/usps.rb @@ -229,7 +229,7 @@ def find_rates(origin, destination, packages, options = {}) end end - def standardize_addresses(addresses) + def standardize_addresses(addresses, options = {}) locations = [] addresses.each { |address| locations << Location.from(address) } request = build_address_standardization_request(locations) @@ -523,69 +523,6 @@ def rates_from_response_node(response_node, packages, options = {}) rate_hash end - def build_address_standardization_request(addresses) - xml_builder = Nokogiri::XML::Builder.new do |xml| - xml.AddressValidateRequest('USERID' => @options[:login]) do - xml.IncludeOptionalElements = true - xml.ReturnCarrierRoute = true - Array(addresses).each_with_index do |package, id| - xml.Address('ID' => id) do - xml.FirmName = addresses[:FirmName] - xml.Address1 = addresses[:Address1] - xml.Address2 = addresses[:Address2] - xml.City = addresses[:City] - xml.State = addresses[:State] - xml.Zip5 = addresses[:Zip5] - xml.Zip4 = addresses[:Zip4] - end - end - end - end - save_request(xml_builder.to_xml) - end - - def parse_address_standardize_response(response, addresses, options = {}) - success = true - message = '' - address_hash = {} - - xml = Nokogiri.XML(response) - - if error = xml.at_xpath('/Error | //ServiceErrors/ServiceError') - success = false - message = error.at('Description').text - else - xml.root.xpath('Address').each do |address| - if address.at('Error') - success = false - message = package.at('Error/Description').text - break - end - end - - if success - address_hash = addresses_from_response_node(xml, addresses, options) - unless address_hash - success = false - message = "Unknown root node in XML response: '#{xml.root.name}'" - end - end - - end - - if success - addresses = address_hash.keys.map do |address| - Location.new(:address1 => address_hash[address][:address1], - :address2 => address_hash[address][:address2], - :postal_code => address_hash[address][:zip5], - :city => address_hash[address][:city], - :state => address_hash[address][:state]) - end - end - - AddressStandardizationResponse.new(success, message, Hash.from_xml(response), :addresses => addresses, :xml => response, :request => last_request) - end - def package_valid_for_service(package, service_node) return true if service_node.at('MaxWeight').nil? max_weight = service_node.at('MaxWeight').text.to_f @@ -724,6 +661,84 @@ def parse_tracking_info(response, node) ) end + def build_address_standardization_request(addresses) + xml_builder = Nokogiri::XML::Builder.new do |xml| + xml.AddressValidateRequest('USERID' => @options[:login]) do + xml.IncludeOptionalElements = true + xml.ReturnCarrierRoute = true + Array(addresses).each_with_index do |package, id| + xml.Address('ID' => id) do + xml.FirmName = addresses[:FirmName] + xml.Address1 = addresses[:Address1] + xml.Address2 = addresses[:Address2] + xml.City = addresses[:City] + xml.State = addresses[:State] + xml.Zip5 = addresses[:Zip5] + xml.Zip4 = addresses[:Zip4] + end + end + end + end + save_request(xml_builder.to_xml) + end + + def parse_address_standardize_response(response, addresses, options = {}) + success = true + message = '' + address_hash = {} + + xml = Nokogiri.XML(response) + + if error = xml.at_xpath('/Error | //ServiceErrors/ServiceError') + success = false + message = error.at('Description').text + else + xml.root.xpath('Address').each do |address| + if address.at('Error') + success = false + message = package.at('Error/Description').text + break + end + end + + if success + address_hash = addresses_from_response_node(xml, addresses, options) + unless address_hash + success = false + message = "Unknown root node in XML response: '#{xml.root.name}'" + end + end + end + + if success + addresses = address_hash.keys.map do |address| + Location.new(:address1 => address_hash[address][:address1], + :address2 => address_hash[address][:address2], + :postal_code => address_hash[address][:zip5], + :city => address_hash[address][:city], + :state => address_hash[address][:state]) + end + end + + AddressStandardizationResponse.new(success, message, Hash.from_xml(response), :addresses => addresses, :xml => response, :request => last_request) + end + + def addresses_from_response_node(xml, addresses, options) + address_hash = {} + return false unless (root_node = response_node.at_xpath('/AddressValidateResponse')) + + root_node.xpath('Address').each do |address_node| + this_address = addresses[address_node['ID'].to_i] + + address_hash.merge!( { :address1 => this_address.xpath('Address1'), + :address2 => this_address.xpath('Address2'), + :zip5 => this_address.xpath('zip5'), + :city => this_address.xpath('city'), + :state => this_address.xpath('state') } ) + end + address_hash + end + def error_description_node(node) node.xpath('Error/Description') end From 095af097a9250086cff8ee5891936d907483b5bf Mon Sep 17 00:00:00 2001 From: pborel Date: Thu, 10 Nov 2016 17:22:23 -0500 Subject: [PATCH 11/11] fixes a lot of bugs with formatting the req/res for addresses --- lib/active_shipping.rb | 1 + .../address_standardization_response.rb | 4 +- lib/active_shipping/carriers/usps.rb | 80 ++++++++----------- 3 files changed, 36 insertions(+), 49 deletions(-) diff --git a/lib/active_shipping.rb b/lib/active_shipping.rb index 31c8aa4a3..656d1f797 100644 --- a/lib/active_shipping.rb +++ b/lib/active_shipping.rb @@ -45,3 +45,4 @@ require 'active_shipping/errors' require 'active_shipping/external_return_label_request' require 'active_shipping/external_return_label_response' +require 'active_shipping/address_standardization_response' diff --git a/lib/active_shipping/address_standardization_response.rb b/lib/active_shipping/address_standardization_response.rb index f8e453b99..78fb8deea 100644 --- a/lib/active_shipping/address_standardization_response.rb +++ b/lib/active_shipping/address_standardization_response.rb @@ -10,7 +10,7 @@ module ActiveShipping # The correct addresses returned from USPS class AddressStandardizationResponse < Response - attr_reader :addresses + attr_reader :locations # Initializes a new AddressStandarizationResponse instance. # @@ -19,7 +19,7 @@ class AddressStandardizationResponse < Response # @param params (see ActiveShipping::Response#initialize) # @option options (see ActiveShipping::Response#initialize) def initialize(success, message, params = {}, options = {}) - @addresses = Array(options[:addresses]) + @locations = options[:locations] super end end diff --git a/lib/active_shipping/carriers/usps.rb b/lib/active_shipping/carriers/usps.rb index 21038eead..f861c4277 100644 --- a/lib/active_shipping/carriers/usps.rb +++ b/lib/active_shipping/carriers/usps.rb @@ -29,7 +29,8 @@ class USPS < Carrier :us_rates => 'RateV4', :world_rates => 'IntlRateV2', :test => 'CarrierPickupAvailability', - :track => 'TrackV2' + :track => 'TrackV2', + :address_standarization => 'Verify' } USE_SSL = { :us_rates => false, @@ -230,11 +231,9 @@ def find_rates(origin, destination, packages, options = {}) end def standardize_addresses(addresses, options = {}) - locations = [] - addresses.each { |address| locations << Location.from(address) } - request = build_address_standardization_request(locations) + request = build_address_standardization_request(addresses) - parse_address_standardize_response(commit(:world_rates, request, false), addresses, options) + parse_address_standardize_response(commit(:address_standarization, request, false), addresses, options) end def valid_credentials? @@ -664,17 +663,18 @@ def parse_tracking_info(response, node) def build_address_standardization_request(addresses) xml_builder = Nokogiri::XML::Builder.new do |xml| xml.AddressValidateRequest('USERID' => @options[:login]) do - xml.IncludeOptionalElements = true - xml.ReturnCarrierRoute = true - Array(addresses).each_with_index do |package, id| + xml.IncludeOptionalElements(true) + xml.ReturnCarrierRoute(true) + Array(addresses).each_with_index do |address, id| xml.Address('ID' => id) do - xml.FirmName = addresses[:FirmName] - xml.Address1 = addresses[:Address1] - xml.Address2 = addresses[:Address2] - xml.City = addresses[:City] - xml.State = addresses[:State] - xml.Zip5 = addresses[:Zip5] - xml.Zip4 = addresses[:Zip4] + xml.FirmName(address[:firm_name]) + xml.Address1(address[:address1]) + xml.Address2(address[:address2]) + xml.City(address[:city]) + xml.State(address[:state]) + xml.Urbanization(address[:urbanization]) + xml.Zip5(address[:postal_code]) + xml.Zip4(address[:zip4]) end end end @@ -686,6 +686,7 @@ def parse_address_standardize_response(response, addresses, options = {}) success = true message = '' address_hash = {} + locations = [] xml = Nokogiri.XML(response) @@ -696,47 +697,32 @@ def parse_address_standardize_response(response, addresses, options = {}) xml.root.xpath('Address').each do |address| if address.at('Error') success = false - message = package.at('Error/Description').text + message = address.at('Error/Description').text break end end - - if success - address_hash = addresses_from_response_node(xml, addresses, options) - unless address_hash - success = false - message = "Unknown root node in XML response: '#{xml.root.name}'" - end - end end if success - addresses = address_hash.keys.map do |address| - Location.new(:address1 => address_hash[address][:address1], - :address2 => address_hash[address][:address2], - :postal_code => address_hash[address][:zip5], - :city => address_hash[address][:city], - :state => address_hash[address][:state]) + addresses = Hash.from_xml(response)["AddressValidateResponse"]["Address"] + if addresses.is_a?(Array) + addresses.each do |address| + locations << Location.new(:address1 => address["Address1"], + :address2 => address["Address2"], + :postal_code => address["Zip5"], + :city => address["City"], + :state => address["State"]) + end + else + locations << Location.new(:address1 => addresses["Address1"], + :address2 => addresses["Address2"], + :postal_code => addresses["Zip5"], + :city => addresses["City"], + :state => addresses["State"]) end end - AddressStandardizationResponse.new(success, message, Hash.from_xml(response), :addresses => addresses, :xml => response, :request => last_request) - end - - def addresses_from_response_node(xml, addresses, options) - address_hash = {} - return false unless (root_node = response_node.at_xpath('/AddressValidateResponse')) - - root_node.xpath('Address').each do |address_node| - this_address = addresses[address_node['ID'].to_i] - - address_hash.merge!( { :address1 => this_address.xpath('Address1'), - :address2 => this_address.xpath('Address2'), - :zip5 => this_address.xpath('zip5'), - :city => this_address.xpath('city'), - :state => this_address.xpath('state') } ) - end - address_hash + AddressStandardizationResponse.new(success, message, Hash.from_xml(response), :locations => locations, :addresses => addresses, :xml => response, :request => last_request) end def error_description_node(node)