corgibytes-tax_cloud 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +17 -0
- data/.circleci/config.yml +81 -0
- data/.circleci/setup-rubygems.sh +9 -0
- data/.gitignore +67 -0
- data/.rubocop.yml +6 -0
- data/.rubocop_todo.yml +66 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.rdoc +48 -0
- data/CONTRIBUTORS.txt +23 -0
- data/Dockerfile +9 -0
- data/Gemfile +22 -0
- data/LICENSE +23 -0
- data/README.md +190 -0
- data/Rakefile +29 -0
- data/docker-compose.yml +10 -0
- data/examples/.env.example +2 -0
- data/examples/lookup_example.rb +139 -0
- data/lib/config/locales/en.yml +34 -0
- data/lib/hash.rb +8 -0
- data/lib/savon_soap_xml.rb +32 -0
- data/lib/tasks/tax_cloud.rake +18 -0
- data/lib/tasks/tax_code_groups.rake +37 -0
- data/lib/tasks/tax_codes.rake +43 -0
- data/lib/tax_cloud.rb +70 -0
- data/lib/tax_cloud/address.rb +50 -0
- data/lib/tax_cloud/cart_item.rb +26 -0
- data/lib/tax_cloud/client.rb +60 -0
- data/lib/tax_cloud/configuration.rb +28 -0
- data/lib/tax_cloud/errors.rb +6 -0
- data/lib/tax_cloud/errors/api_error.rb +17 -0
- data/lib/tax_cloud/errors/missing_config_error.rb +13 -0
- data/lib/tax_cloud/errors/missing_config_option_error.rb +19 -0
- data/lib/tax_cloud/errors/soap_error.rb +30 -0
- data/lib/tax_cloud/errors/tax_cloud_error.rb +83 -0
- data/lib/tax_cloud/errors/unexpected_soap_response_error.rb +19 -0
- data/lib/tax_cloud/record.rb +14 -0
- data/lib/tax_cloud/responses.rb +13 -0
- data/lib/tax_cloud/responses/authorized.rb +10 -0
- data/lib/tax_cloud/responses/authorized_with_capture.rb +10 -0
- data/lib/tax_cloud/responses/base.rb +82 -0
- data/lib/tax_cloud/responses/captured.rb +10 -0
- data/lib/tax_cloud/responses/cart_item.rb +23 -0
- data/lib/tax_cloud/responses/generic.rb +31 -0
- data/lib/tax_cloud/responses/lookup.rb +38 -0
- data/lib/tax_cloud/responses/ping.rb +10 -0
- data/lib/tax_cloud/responses/returned.rb +10 -0
- data/lib/tax_cloud/responses/tax_code_groups.rb +30 -0
- data/lib/tax_cloud/responses/tax_codes.rb +30 -0
- data/lib/tax_cloud/responses/tax_codes_by_group.rb +30 -0
- data/lib/tax_cloud/responses/verify_address.rb +26 -0
- data/lib/tax_cloud/tax_code.rb +11 -0
- data/lib/tax_cloud/tax_code_constants.rb +560 -0
- data/lib/tax_cloud/tax_code_group.rb +28 -0
- data/lib/tax_cloud/tax_code_group_constants.rb +31 -0
- data/lib/tax_cloud/tax_code_groups.rb +25 -0
- data/lib/tax_cloud/tax_codes.rb +25 -0
- data/lib/tax_cloud/transaction.rb +118 -0
- data/lib/tax_cloud/version.rb +4 -0
- data/tax_cloud.gemspec +23 -0
- data/test/cassettes/authorized.yml +826 -0
- data/test/cassettes/authorized_with_capture.yml +826 -0
- data/test/cassettes/authorized_with_localized_time.yml +826 -0
- data/test/cassettes/captured.yml +872 -0
- data/test/cassettes/get_tic_groups.yml +783 -0
- data/test/cassettes/get_tics.yml +1079 -0
- data/test/cassettes/get_tics_by_group.yml +776 -0
- data/test/cassettes/invalid_soap_call.yml +778 -0
- data/test/cassettes/lookup.yml +780 -0
- data/test/cassettes/lookup_ny.yml +780 -0
- data/test/cassettes/ping.yml +776 -0
- data/test/cassettes/ping_with_invalid_credentials.yml +774 -0
- data/test/cassettes/ping_with_invalid_response.yml +774 -0
- data/test/cassettes/returned.yml +872 -0
- data/test/cassettes/verify_bad_address.yml +772 -0
- data/test/cassettes/verify_good_address.yml +772 -0
- data/test/helper.rb +17 -0
- data/test/test_address.rb +54 -0
- data/test/test_cart_item.rb +15 -0
- data/test/test_client.rb +27 -0
- data/test/test_configuration_optional_keys.rb +42 -0
- data/test/test_configuration_required_keys.rb +31 -0
- data/test/test_lookup_response.rb +20 -0
- data/test/test_setup.rb +17 -0
- data/test/test_soap.rb +11 -0
- data/test/test_tax_code_groups.rb +29 -0
- data/test/test_tax_codes.rb +17 -0
- data/test/test_transaction.rb +78 -0
- data/test/test_transaction_ny.rb +25 -0
- data/test/vcr_setup.rb +9 -0
- metadata +174 -0
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rdoc/task'
|
4
|
+
require 'vcr'
|
5
|
+
|
6
|
+
Rake::TestTask.new(:test) do |test|
|
7
|
+
test.libs << 'lib' << 'test'
|
8
|
+
test.pattern = 'test/test_*.rb'
|
9
|
+
# REM
|
10
|
+
#test.verbose = false
|
11
|
+
end
|
12
|
+
|
13
|
+
RDoc::Task.new do |rd|
|
14
|
+
README = 'README.rdoc'.freeze
|
15
|
+
rd.main = README
|
16
|
+
rd.rdoc_files.include(README, 'CHANGELOG.rdoc', 'LICENSE.rdoc', 'lib/**/*.rb')
|
17
|
+
rd.rdoc_dir = 'doc'
|
18
|
+
rd.title = 'tax_cloud'
|
19
|
+
end
|
20
|
+
|
21
|
+
load 'lib/tasks/tax_cloud.rake'
|
22
|
+
load 'lib/tasks/tax_codes.rake'
|
23
|
+
load 'lib/tasks/tax_code_groups.rake'
|
24
|
+
load 'vcr/tasks/vcr.rake'
|
25
|
+
|
26
|
+
require 'rubocop/rake_task'
|
27
|
+
RuboCop::RakeTask.new(:rubocop)
|
28
|
+
|
29
|
+
task default: [:rubocop, :test]
|
data/docker-compose.yml
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
##
|
2
|
+
# An example of doing a tax lookup that hits TaxCloud. To run:
|
3
|
+
#
|
4
|
+
# bundle exec ruby lookup_example.rb
|
5
|
+
#
|
6
|
+
# Make sure you copy the .env.example to .env an update the
|
7
|
+
# values in it before running. I also recommend no running
|
8
|
+
# this script against a live TaxCloud site. Run it only against
|
9
|
+
# test sites.
|
10
|
+
##
|
11
|
+
|
12
|
+
require 'dotenv/load'
|
13
|
+
require 'securerandom'
|
14
|
+
|
15
|
+
require_relative '../lib/tax_cloud'
|
16
|
+
|
17
|
+
##
|
18
|
+
# Load the TaxCloud settings from the environment file.\
|
19
|
+
#
|
20
|
+
def load_config
|
21
|
+
TaxCloud.configure do |config|
|
22
|
+
config.api_login_id = ENV['TAX_CLOUD_LOGIN_ID']
|
23
|
+
config.api_key = ENV['TAX_CLOUD_API_KEY']
|
24
|
+
config.open_timeout = 10
|
25
|
+
config.read_timeout = 10
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Display the current TaxCloud settings.
|
31
|
+
#
|
32
|
+
def display_config
|
33
|
+
TaxCloud.configure do |config|
|
34
|
+
puts "API Login ID: #{config.api_login_id}"
|
35
|
+
puts "API Key: #{config.api_key}"
|
36
|
+
puts "Open timeout: #{config.open_timeout}"
|
37
|
+
puts "Read timeout: #{config.read_timeout}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# Create a test transaction with one cart item.
|
43
|
+
#
|
44
|
+
# Will create a new customer and cart each time using GUIDs for
|
45
|
+
# the customer and cart IDs. This prevents collisions with
|
46
|
+
# existing customer/carts when running the script multiple times.
|
47
|
+
#
|
48
|
+
def create_test_transaction
|
49
|
+
origin = TaxCloud::Address.new(
|
50
|
+
:address1 => '162 East Avenue',
|
51
|
+
:address2 => 'Third Floor',
|
52
|
+
:city => 'Norwalk',
|
53
|
+
:state => 'CT',
|
54
|
+
:zip5 => '06851')
|
55
|
+
|
56
|
+
destination = TaxCloud::Address.new(
|
57
|
+
:address1 => '3121 West Government Way',
|
58
|
+
:address2 => 'Suite 2B',
|
59
|
+
:city => 'Seattle',
|
60
|
+
:state => 'WA',
|
61
|
+
:zip5 => '98199')
|
62
|
+
|
63
|
+
transaction = TaxCloud::Transaction.new(
|
64
|
+
:customer_id => SecureRandom.uuid,
|
65
|
+
:cart_id => SecureRandom.uuid,
|
66
|
+
:origin => origin,
|
67
|
+
:destination => destination)
|
68
|
+
|
69
|
+
transaction.cart_items << TaxCloud::CartItem.new(
|
70
|
+
:index => 0,
|
71
|
+
:item_id => 'SKU-100',
|
72
|
+
:tic => TaxCloud::TaxCodes::GENERAL,
|
73
|
+
:price => 10.00,
|
74
|
+
:quantity => 1)
|
75
|
+
|
76
|
+
transaction
|
77
|
+
end
|
78
|
+
|
79
|
+
##
|
80
|
+
# Displays information about the transaction:
|
81
|
+
#
|
82
|
+
# - Customer ID
|
83
|
+
# - Cart ID
|
84
|
+
# - Origin Address
|
85
|
+
# - Destination Address
|
86
|
+
# - Cart Items
|
87
|
+
#
|
88
|
+
# @param [TaxCloud::Transaction] transaction
|
89
|
+
#
|
90
|
+
def display_transaction(transaction)
|
91
|
+
puts "Customer ID: #{transaction.customer_id}"
|
92
|
+
puts "Cart ID: #{transaction.cart_id}"
|
93
|
+
puts "Origin: #{transaction.origin.to_hash}"
|
94
|
+
puts "Destination: #{transaction.destination.to_hash}"
|
95
|
+
puts "Cart Items: #{transaction.cart_items.map(&:to_hash)}"
|
96
|
+
end
|
97
|
+
|
98
|
+
##
|
99
|
+
# Display the total tax and tax for each cart item.
|
100
|
+
#
|
101
|
+
# @param [TaxCloud::Responses::Lookup] lookup
|
102
|
+
def display_tax(lookup)
|
103
|
+
puts "Total tax amount: #{lookup.tax_amount}"
|
104
|
+
|
105
|
+
lookup.cart_items.each do |cart_item|
|
106
|
+
puts "Tax cart index #{cart_item.cart_item_index}: #{cart_item.tax_amount}"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
##
|
112
|
+
# Run an example lookup
|
113
|
+
##
|
114
|
+
puts 'Loading config information from .env file...'
|
115
|
+
load_config
|
116
|
+
puts 'Config loaded'
|
117
|
+
puts
|
118
|
+
|
119
|
+
puts 'The TaxCloud config is:'
|
120
|
+
display_config
|
121
|
+
puts
|
122
|
+
|
123
|
+
puts 'Checking config...'
|
124
|
+
TaxCloud.configuration.check!
|
125
|
+
puts 'Check passed.'
|
126
|
+
puts
|
127
|
+
|
128
|
+
puts 'Pinging TaxCloud server...'
|
129
|
+
puts TaxCloud.client.ping
|
130
|
+
|
131
|
+
puts 'Cart values:'
|
132
|
+
transaction = create_test_transaction
|
133
|
+
display_transaction(transaction)
|
134
|
+
puts
|
135
|
+
|
136
|
+
puts 'Tax lookup:'
|
137
|
+
lookup = transaction.lookup
|
138
|
+
display_tax(lookup)
|
139
|
+
puts
|
@@ -0,0 +1,34 @@
|
|
1
|
+
en:
|
2
|
+
taxcloud:
|
3
|
+
errors:
|
4
|
+
messages:
|
5
|
+
missing_config:
|
6
|
+
message: "Missing configuration."
|
7
|
+
summary: "TaxCloud requires an API login ID and key."
|
8
|
+
resolution: "Create a TaxCloud merchant account at http://www.taxcloud.net.
|
9
|
+
Add a website to your TaxCloud account. This will generate an API ID and
|
10
|
+
API Key that you will need to use the service. Configure the TaxCloud
|
11
|
+
gem. For example, add the following to `config/initializers/tax_cloud.rb`.\n
|
12
|
+
\_\_TaxCloud.configure do |config|\n
|
13
|
+
\_\_\_config.api_login_id = 'your_tax_cloud_api_login_id'\n
|
14
|
+
\_\_\_config.api_key = 'your_tax_cloud_api_key'\n
|
15
|
+
\_\_\_config.usps_username = 'your_usps_username' # optional\n
|
16
|
+
\_\_end\n"
|
17
|
+
missing_config_option:
|
18
|
+
message: "Missing configuration option: %{name}."
|
19
|
+
summary: "A configuration option was not provided when configuring TaxCloud."
|
20
|
+
resolution: "Review your `TaxCloud.configure` code. Are you using an environment
|
21
|
+
variable that has not been set?"
|
22
|
+
soap_error:
|
23
|
+
message: "%{message}"
|
24
|
+
summary: "The server returned a %{code} error."
|
25
|
+
resolution: "Review the parameters passed to the request."
|
26
|
+
unexpected_soap_response:
|
27
|
+
message: "Expected a value for `%{key}` in `%{chain}` in the TaxCloud response."
|
28
|
+
summary: "TaxCloud returned an unexpected response: `%{raw}`."
|
29
|
+
resolution: "This is possibly a bug in the tax_cloud gem.\n
|
30
|
+
Please report it in https://github.com/drewtempelmeyer/tax_cloud/issues."
|
31
|
+
api_error:
|
32
|
+
message: "%{message}"
|
33
|
+
summary: "The TaxCloud server returned an error in the response: `%{raw}`"
|
34
|
+
resolution: "Check the request parameters."
|
data/lib/hash.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# Hack Savon to work properly with arrays
|
2
|
+
module Savon #:nodoc:
|
3
|
+
module SOAP #:nodoc:
|
4
|
+
class XML #:nodoc:
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
old_add_namespaces_to_body = self.instance_method(:add_namespaces_to_body)
|
9
|
+
|
10
|
+
def add_namespaces_to_body(hash, path = [input[1].to_s])
|
11
|
+
return unless hash
|
12
|
+
return hash if hash.kind_of? Array
|
13
|
+
return hash.to_s unless hash.kind_of? Hash
|
14
|
+
|
15
|
+
hash.inject({}) do |newhash, (key, value)|
|
16
|
+
camelcased_key = Gyoku::XMLKey.create(key)
|
17
|
+
newpath = path + [camelcased_key]
|
18
|
+
|
19
|
+
if used_namespaces[newpath]
|
20
|
+
newhash.merge(
|
21
|
+
"#{used_namespaces[newpath]}:#{camelcased_key}" =>
|
22
|
+
add_namespaces_to_body(value, types[newpath] ? [types[newpath]] : newpath)
|
23
|
+
)
|
24
|
+
else
|
25
|
+
newhash.merge(key => value)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'tax_cloud'
|
2
|
+
|
3
|
+
namespace :tax_cloud do
|
4
|
+
desc 'Configure TaxCloud.'
|
5
|
+
task :configure do
|
6
|
+
unless TaxCloud.configured?
|
7
|
+
TaxCloud.configure do |config|
|
8
|
+
config.api_login_id = ENV['TAXCLOUD_API_LOGIN_ID']
|
9
|
+
config.api_key = ENV['TAXCLOUD_API_KEY']
|
10
|
+
config.usps_username = ENV['TAXCLOUD_USPS_USERNAME']
|
11
|
+
end
|
12
|
+
Savon.configure do |config|
|
13
|
+
config.log = false
|
14
|
+
end
|
15
|
+
HTTPI.log = false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
namespace :tax_cloud do
|
2
|
+
desc 'Generate tax code groups.'
|
3
|
+
task tax_code_groups: :configure do
|
4
|
+
filename = 'lib/tax_cloud/tax_code_group_constants.rb'
|
5
|
+
|
6
|
+
begin
|
7
|
+
groups = TaxCloud::TaxCode::Groups.all.values
|
8
|
+
|
9
|
+
File.open filename, 'wt' do |f|
|
10
|
+
f.write "module TaxCloud\n"
|
11
|
+
f.write " class TaxCode\n"
|
12
|
+
f.write " # Tax Code Groups.\n"
|
13
|
+
f.write " class Groups\n"
|
14
|
+
|
15
|
+
groups.each do |group|
|
16
|
+
puts " #{group.description}"
|
17
|
+
code = group.description.upcase
|
18
|
+
code.gsub! /[^A-Z0-9]/, '_'
|
19
|
+
code.gsub! /_$/, ''
|
20
|
+
code.gsub! /\_+/, '_'
|
21
|
+
f.write " \# #{group.description}\n"
|
22
|
+
f.write " #{code} = #{group.group_id}\n"
|
23
|
+
end
|
24
|
+
|
25
|
+
f.write " end\n"
|
26
|
+
f.write " end\n"
|
27
|
+
f.write "end\n"
|
28
|
+
end
|
29
|
+
|
30
|
+
puts "Done, #{filename}."
|
31
|
+
rescue => e
|
32
|
+
puts 'ERROR: Unable to generate a new list of tax codes.'
|
33
|
+
puts e.message
|
34
|
+
raise e
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
namespace :tax_cloud do
|
2
|
+
desc 'Generate tax codes.'
|
3
|
+
task tax_codes: :configure do
|
4
|
+
filename = 'lib/tax_cloud/tax_code_constants.rb'
|
5
|
+
|
6
|
+
begin
|
7
|
+
groups = TaxCloud::TaxCode::Groups.all.values
|
8
|
+
groups_and_tax_codes = Hash[groups.map do |group|
|
9
|
+
[group, group.tax_codes.values]
|
10
|
+
end]
|
11
|
+
File.open filename, 'wt' do |f|
|
12
|
+
f.write "module TaxCloud\n"
|
13
|
+
f.write " # Tax Codes.\n"
|
14
|
+
f.write " class TaxCodes\n"
|
15
|
+
f.write "\n"
|
16
|
+
codes = {}
|
17
|
+
groups_and_tax_codes.each_pair do |group, tax_codes|
|
18
|
+
puts " #{group.description}"
|
19
|
+
f.write " \# #{group.description}\n\n"
|
20
|
+
tax_codes.each do |tax_code|
|
21
|
+
code = tax_code.description.upcase
|
22
|
+
code.gsub! /[^A-Z0-9]/, '_'
|
23
|
+
code.gsub! /\_+$/, ''
|
24
|
+
code.gsub! /\_+/, '_'
|
25
|
+
# avoid duplicates
|
26
|
+
code_id = codes[code] ? "#{code}_#{codes[code]}" : code
|
27
|
+
codes[code] = (codes[code] || 0) + 1
|
28
|
+
f.write " \# #{group.description}: #{tax_code.description}\n"
|
29
|
+
f.write " #{code_id} = #{tax_code.ticid}\n"
|
30
|
+
end
|
31
|
+
f.write "\n"
|
32
|
+
end
|
33
|
+
f.write " end\n"
|
34
|
+
f.write "end\n"
|
35
|
+
end
|
36
|
+
puts "Done, #{filename}."
|
37
|
+
rescue => e
|
38
|
+
puts 'ERROR: Unable to generate a new list of tax codes.'
|
39
|
+
puts e.message
|
40
|
+
raise e
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/tax_cloud.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'savon'
|
2
|
+
require 'i18n'
|
3
|
+
require 'hash'
|
4
|
+
require 'savon_soap_xml'
|
5
|
+
|
6
|
+
require 'active_support'
|
7
|
+
require 'active_support/core_ext'
|
8
|
+
|
9
|
+
require 'tax_cloud/version'
|
10
|
+
require 'tax_cloud/errors'
|
11
|
+
require 'tax_cloud/responses'
|
12
|
+
require 'tax_cloud/record'
|
13
|
+
require 'tax_cloud/transaction'
|
14
|
+
require 'tax_cloud/address'
|
15
|
+
require 'tax_cloud/cart_item'
|
16
|
+
require 'tax_cloud/tax_code'
|
17
|
+
require 'tax_cloud/tax_code_group'
|
18
|
+
require 'tax_cloud/tax_codes'
|
19
|
+
require 'tax_cloud/tax_code_constants'
|
20
|
+
require 'tax_cloud/tax_code_groups'
|
21
|
+
require 'tax_cloud/tax_code_group_constants'
|
22
|
+
require 'tax_cloud/configuration'
|
23
|
+
require 'tax_cloud/client'
|
24
|
+
|
25
|
+
I18n.load_path << File.join(File.dirname(__FILE__), 'config', 'locales', 'en.yml')
|
26
|
+
|
27
|
+
# TaxCloud is a web service to calculate and track sales tax for your ecommerce platform. Integration is easy to use.
|
28
|
+
# For information on configuring and using the TaxCloud API, look at the <tt>README</tt> file.
|
29
|
+
module TaxCloud
|
30
|
+
# WSDL location for TaxCloud API.
|
31
|
+
WSDL_URL = 'https://api.taxcloud.net/1.0/?wsdl'.freeze
|
32
|
+
|
33
|
+
# TaxCloud API version.
|
34
|
+
API_VERSION = '1.0'.freeze
|
35
|
+
|
36
|
+
class << self
|
37
|
+
# TaxCloud gem configuration.
|
38
|
+
attr_accessor :configuration
|
39
|
+
|
40
|
+
# Returns true if the gem has been configured.
|
41
|
+
def configured?
|
42
|
+
configuration.present?
|
43
|
+
end
|
44
|
+
|
45
|
+
# Configure the gem.
|
46
|
+
def configure
|
47
|
+
self.configuration ||= Configuration.new
|
48
|
+
yield configuration
|
49
|
+
end
|
50
|
+
|
51
|
+
# Reset the current configuration.
|
52
|
+
def reset!
|
53
|
+
self.configuration = nil
|
54
|
+
@client = nil
|
55
|
+
end
|
56
|
+
|
57
|
+
# The configured SOAP client to the TaxCloud service.
|
58
|
+
def client
|
59
|
+
check_configuration!
|
60
|
+
@client ||= TaxCloud::Client.new
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def check_configuration!
|
66
|
+
raise TaxCloud::Errors::MissingConfig.new unless self.configuration
|
67
|
+
self.configuration.check!
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module TaxCloud #:nodoc:
|
2
|
+
# An <tt>Address</tt> defines an address in the United States.
|
3
|
+
class Address < Record
|
4
|
+
# First line of address.
|
5
|
+
attr_accessor :address1
|
6
|
+
# Second line of adress.
|
7
|
+
attr_accessor :address2
|
8
|
+
# City.
|
9
|
+
attr_accessor :city
|
10
|
+
# State.
|
11
|
+
attr_accessor :state
|
12
|
+
# 5-digit Zip Code.
|
13
|
+
attr_accessor :zip5
|
14
|
+
# 4-digit Zip Code.
|
15
|
+
attr_accessor :zip4
|
16
|
+
|
17
|
+
# Verify this address.
|
18
|
+
#
|
19
|
+
# Returns a verified TaxCloud::Address.
|
20
|
+
def verify
|
21
|
+
params = to_hash.downcase_keys
|
22
|
+
if TaxCloud.configuration.usps_username
|
23
|
+
params = params.merge(
|
24
|
+
'uspsUserID' => TaxCloud.configuration.usps_username
|
25
|
+
)
|
26
|
+
end
|
27
|
+
response = TaxCloud.client.request(:verify_address, params)
|
28
|
+
TaxCloud::Responses::VerifyAddress.parse(response)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Complete zip code.
|
32
|
+
# Returns a 9-digit Zip Code, when available.
|
33
|
+
def zip
|
34
|
+
return nil unless zip5 && !zip5.empty?
|
35
|
+
[zip5, zip4].select { |z| z && !z.empty? }.join('-')
|
36
|
+
end
|
37
|
+
|
38
|
+
# Convert the object to a usable hash for SOAP requests
|
39
|
+
def to_hash
|
40
|
+
{
|
41
|
+
'Address1' => address1,
|
42
|
+
'Address2' => address2,
|
43
|
+
'City' => city,
|
44
|
+
'State' => state,
|
45
|
+
'Zip5' => zip5,
|
46
|
+
'Zip4' => zip4
|
47
|
+
}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|