tax_cloud 0.3.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/test.yml +30 -0
- data/.rubocop.yml +9 -25
- data/.rubocop_todo.yml +47 -0
- data/CHANGELOG.md +85 -0
- data/CONTRIBUTORS.txt +3 -0
- data/Gemfile +15 -5
- data/LICENSE.md +21 -0
- data/README.md +200 -0
- data/Rakefile +5 -19
- data/lib/config/locales/en.yml +2 -2
- data/lib/hash.rb +3 -4
- data/lib/tasks/tax_cloud.rake +4 -4
- data/lib/tasks/tax_code_groups.rake +11 -11
- data/lib/tasks/tax_codes.rake +12 -12
- data/lib/tax_cloud/address.rb +10 -5
- data/lib/tax_cloud/cart_item.rb +2 -0
- data/lib/tax_cloud/client.rb +13 -3
- data/lib/tax_cloud/configuration.rb +13 -2
- data/lib/tax_cloud/errors/api_error.rb +3 -3
- data/lib/tax_cloud/errors/missing_config_error.rb +2 -1
- data/lib/tax_cloud/errors/missing_config_option_error.rb +2 -1
- data/lib/tax_cloud/errors/soap_error.rb +6 -6
- data/lib/tax_cloud/errors/tax_cloud_error.rb +5 -4
- data/lib/tax_cloud/errors/unexpected_soap_response_error.rb +3 -3
- data/lib/tax_cloud/errors.rb +2 -0
- data/lib/tax_cloud/record.rb +2 -0
- data/lib/tax_cloud/responses/authorized.rb +3 -1
- data/lib/tax_cloud/responses/authorized_with_capture.rb +3 -1
- data/lib/tax_cloud/responses/base.rb +5 -4
- data/lib/tax_cloud/responses/captured.rb +3 -1
- data/lib/tax_cloud/responses/cart_item.rb +6 -2
- data/lib/tax_cloud/responses/generic.rb +2 -0
- data/lib/tax_cloud/responses/lookup.rb +10 -8
- data/lib/tax_cloud/responses/ping.rb +3 -1
- data/lib/tax_cloud/responses/returned.rb +3 -1
- data/lib/tax_cloud/responses/tax_code_groups.rb +3 -1
- data/lib/tax_cloud/responses/tax_codes.rb +3 -1
- data/lib/tax_cloud/responses/tax_codes_by_group.rb +3 -1
- data/lib/tax_cloud/responses/verify_address.rb +3 -1
- data/lib/tax_cloud/responses.rb +2 -0
- data/lib/tax_cloud/tax_code.rb +2 -0
- data/lib/tax_cloud/tax_code_constants.rb +262 -260
- data/lib/tax_cloud/tax_code_group.rb +3 -1
- data/lib/tax_cloud/tax_code_group_constants.rb +2 -0
- data/lib/tax_cloud/tax_code_groups.rb +3 -1
- data/lib/tax_cloud/tax_codes.rb +3 -1
- data/lib/tax_cloud/transaction.rb +2 -0
- data/lib/tax_cloud/version.rb +3 -1
- data/lib/tax_cloud.rb +8 -3
- data/tax_cloud.gemspec +17 -18
- data/test/cassettes/authorized.yml +6 -6
- data/test/cassettes/authorized_with_capture.yml +6 -6
- data/test/cassettes/authorized_with_localized_time.yml +6 -6
- data/test/cassettes/captured.yml +7 -7
- data/test/cassettes/get_tic_groups.yml +5 -5
- data/test/cassettes/get_tics.yml +5 -5
- data/test/cassettes/get_tics_by_group.yml +5 -5
- data/test/cassettes/invalid_soap_call.yml +5 -5
- data/test/cassettes/lookup.yml +5 -5
- data/test/cassettes/lookup_ny.yml +5 -5
- data/test/cassettes/ping.yml +5 -5
- data/test/cassettes/ping_with_invalid_credentials.yml +5 -5
- data/test/cassettes/ping_with_invalid_response.yml +5 -5
- data/test/cassettes/returned.yml +7 -7
- data/test/cassettes/verify_bad_address.yml +5 -5
- data/test/cassettes/verify_good_address.yml +5 -5
- data/test/helper.rb +3 -1
- data/test/test_address.rb +7 -5
- data/test/test_cart_item.rb +3 -1
- data/test/test_client.rb +4 -2
- data/test/test_configuration_optional_keys.rb +44 -0
- data/test/{test_configuration.rb → test_configuration_required_keys.rb} +6 -4
- data/test/test_lookup_response.rb +22 -0
- data/test/test_setup.rb +3 -1
- data/test/test_soap.rb +3 -1
- data/test/test_tax_code_groups.rb +4 -2
- data/test/test_tax_codes.rb +3 -1
- data/test/test_transaction.rb +3 -1
- data/test/test_transaction_ny.rb +3 -1
- data/test/vcr_setup.rb +2 -0
- metadata +37 -91
- data/.travis.yml +0 -6
- data/CHANGELOG.rdoc +0 -42
- data/LICENSE.rdoc +0 -22
- data/README.rdoc +0 -140
data/lib/tax_cloud/address.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TaxCloud #:nodoc:
|
2
4
|
# An <tt>Address</tt> defines an address in the United States.
|
3
5
|
class Address < Record
|
@@ -19,9 +21,11 @@ module TaxCloud #:nodoc:
|
|
19
21
|
# Returns a verified TaxCloud::Address.
|
20
22
|
def verify
|
21
23
|
params = to_hash.downcase_keys
|
22
|
-
|
23
|
-
|
24
|
-
|
24
|
+
if TaxCloud.configuration.usps_username
|
25
|
+
params = params.merge(
|
26
|
+
'uspsUserID' => TaxCloud.configuration.usps_username
|
27
|
+
)
|
28
|
+
end
|
25
29
|
response = TaxCloud.client.request(:verify_address, params)
|
26
30
|
TaxCloud::Responses::VerifyAddress.parse(response)
|
27
31
|
end
|
@@ -29,8 +33,9 @@ module TaxCloud #:nodoc:
|
|
29
33
|
# Complete zip code.
|
30
34
|
# Returns a 9-digit Zip Code, when available.
|
31
35
|
def zip
|
32
|
-
return nil unless zip5 && zip5.
|
33
|
-
|
36
|
+
return nil unless zip5 && !zip5.empty?
|
37
|
+
|
38
|
+
[zip5, zip4].select { |z| z && !z.empty? }.join('-')
|
34
39
|
end
|
35
40
|
|
36
41
|
# Convert the object to a usable hash for SOAP requests
|
data/lib/tax_cloud/cart_item.rb
CHANGED
data/lib/tax_cloud/client.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TaxCloud #:nodoc:
|
2
4
|
# A <tt>Client</tt> communicates with the TaxCloud service.
|
3
5
|
class Client < Savon::Client
|
4
6
|
# Create a new client.
|
5
7
|
def initialize
|
6
|
-
super
|
8
|
+
super client_params
|
7
9
|
end
|
8
10
|
|
9
11
|
# Make a safe SOAP call.
|
@@ -34,16 +36,24 @@ module TaxCloud #:nodoc:
|
|
34
36
|
# Authorization hash to use with all SOAP requests
|
35
37
|
def auth_params
|
36
38
|
return {} unless TaxCloud.configuration
|
39
|
+
|
37
40
|
{
|
38
41
|
'apiLoginID' => TaxCloud.configuration.api_login_id,
|
39
42
|
'apiKey' => TaxCloud.configuration.api_key
|
40
43
|
}
|
41
44
|
end
|
42
45
|
|
43
|
-
def
|
46
|
+
def client_params
|
47
|
+
{ wsdl: TaxCloud::WSDL_URL }.tap do |params|
|
48
|
+
params[:open_timeout] = TaxCloud.configuration.open_timeout if TaxCloud.configuration.open_timeout
|
49
|
+
params[:read_timeout] = TaxCloud.configuration.read_timeout if TaxCloud.configuration.read_timeout
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def safe
|
44
54
|
yield
|
45
55
|
rescue Savon::SOAPFault => e
|
46
|
-
raise TaxCloud::Errors::SoapError
|
56
|
+
raise TaxCloud::Errors::SoapError, e
|
47
57
|
end
|
48
58
|
end
|
49
59
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TaxCloud #:nodoc:
|
2
4
|
# TaxCloud gem configuration.
|
3
5
|
class Configuration
|
@@ -7,13 +9,22 @@ module TaxCloud #:nodoc:
|
|
7
9
|
attr_accessor :api_key
|
8
10
|
# Optional USPS username.
|
9
11
|
attr_accessor :usps_username
|
12
|
+
# Savon client option open_timeout.
|
13
|
+
attr_accessor :open_timeout
|
14
|
+
# Savon client option read_timeout.
|
15
|
+
attr_accessor :read_timeout
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@open_timeout = 2
|
19
|
+
@read_timeout = 2
|
20
|
+
end
|
10
21
|
|
11
22
|
# Check the configuration.
|
12
23
|
#
|
13
24
|
# Will raise a TaxCloud::Errors::MissingConfigOption if any of the API login ID or the API key are missing.
|
14
25
|
def check!
|
15
|
-
|
16
|
-
|
26
|
+
raise TaxCloud::Errors::MissingConfigOption, 'api_login_id' unless api_login_id && !api_login_id.strip.empty?
|
27
|
+
raise TaxCloud::Errors::MissingConfigOption, 'api_key' unless api_key && !api_key.strip.empty?
|
17
28
|
end
|
18
29
|
end
|
19
30
|
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module TaxCloud #:nodoc:
|
3
4
|
module Errors #:nodoc:
|
4
5
|
# This error is raised when the TaxCloud service
|
@@ -10,8 +11,7 @@ module TaxCloud #:nodoc:
|
|
10
11
|
def initialize(message, raw)
|
11
12
|
super(compose_message('api_error',
|
12
13
|
message: message,
|
13
|
-
raw: raw
|
14
|
-
))
|
14
|
+
raw: raw))
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module TaxCloud #:nodoc:
|
3
4
|
module Errors #:nodoc:
|
4
5
|
# This error is raised when a SOAP call fails.
|
@@ -9,15 +10,14 @@ module TaxCloud #:nodoc:
|
|
9
10
|
# Create the new error.
|
10
11
|
# === Parameters
|
11
12
|
# [e] SOAP response.
|
12
|
-
def initialize(
|
13
|
-
@fault =
|
14
|
-
|
13
|
+
def initialize(exception)
|
14
|
+
@fault = exception
|
15
|
+
exception.to_hash.tap do |fault|
|
15
16
|
fault_code = fault[:fault][:faultcode]
|
16
17
|
fault_string = parse_fault(fault[:fault][:faultstring])
|
17
18
|
super(compose_message('soap_error',
|
18
19
|
message: fault_string,
|
19
|
-
code: fault_code
|
20
|
-
))
|
20
|
+
code: fault_code))
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -1,4 +1,5 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module TaxCloud #:nodoc:
|
3
4
|
module Errors #:nodoc:
|
4
5
|
# Default parent TaxCloud error for all custom errors. This handles the base
|
@@ -25,8 +26,8 @@ module TaxCloud #:nodoc:
|
|
25
26
|
@summary = create_summary(key, attributes)
|
26
27
|
@resolution = create_resolution(key, attributes)
|
27
28
|
|
28
|
-
"\nProblem:\n #{@problem}"
|
29
|
-
"\nSummary:\n #{@summary}"
|
29
|
+
"\nProblem:\n #{@problem}" \
|
30
|
+
"\nSummary:\n #{@summary}" \
|
30
31
|
"\nResolution:\n #{@resolution}"
|
31
32
|
end
|
32
33
|
|
@@ -43,7 +44,7 @@ module TaxCloud #:nodoc:
|
|
43
44
|
#
|
44
45
|
# Returns a localized error message string.
|
45
46
|
def translate(key, options)
|
46
|
-
::I18n.translate("#{BASE_KEY}.#{key}", { locale: :en }.merge(options)).strip
|
47
|
+
::I18n.translate("#{BASE_KEY}.#{key}", **{ locale: :en }.merge(options)).strip
|
47
48
|
end
|
48
49
|
|
49
50
|
# Create the problem.
|
@@ -1,4 +1,5 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module TaxCloud #:nodoc:
|
3
4
|
module Errors #:nodoc:
|
4
5
|
# This error is raised when TaxCloud returns an
|
@@ -12,8 +13,7 @@ module TaxCloud #:nodoc:
|
|
12
13
|
super(compose_message('unexpected_soap_response',
|
13
14
|
key: key,
|
14
15
|
raw: raw,
|
15
|
-
chain: chain
|
16
|
-
))
|
16
|
+
chain: chain))
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
data/lib/tax_cloud/errors.rb
CHANGED
data/lib/tax_cloud/record.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TaxCloud #:nodoc:
|
2
4
|
module Responses #:nodoc:
|
3
5
|
# Response to a TaxCloud Authorized API call.
|
4
6
|
#
|
5
|
-
# See https://api.taxcloud.
|
7
|
+
# See https://api.taxcloud.com/1.0/TaxCloud.asmx?op=Authorized.
|
6
8
|
class Authorized < Generic
|
7
9
|
response_key :authorized
|
8
10
|
end
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TaxCloud #:nodoc:
|
2
4
|
module Responses #:nodoc:
|
3
5
|
# Response to a TaxCloud AuthorizedWithCapture API call.
|
4
6
|
#
|
5
|
-
# See https://api.taxcloud.
|
7
|
+
# See https://api.taxcloud.com/1.0/TaxCloud.asmx?op=AuthorizedWithCapture.
|
6
8
|
class AuthorizedWithCapture < Generic
|
7
9
|
response_key :authorized_with_capture
|
8
10
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TaxCloud #:nodoc:
|
2
4
|
module Responses #:nodoc:
|
3
5
|
# A base TaxCloud SOAP response.
|
@@ -49,7 +51,8 @@ module TaxCloud #:nodoc:
|
|
49
51
|
chain.split('/').each do |key|
|
50
52
|
current_value = current_value[key.to_sym]
|
51
53
|
next if current_value
|
52
|
-
|
54
|
+
|
55
|
+
raise TaxCloud::Errors::UnexpectedSoapResponse.new(raw, key, chain)
|
53
56
|
end
|
54
57
|
current_value
|
55
58
|
end
|
@@ -75,9 +78,7 @@ module TaxCloud #:nodoc:
|
|
75
78
|
elsif self.dsl[:error_number]
|
76
79
|
return true if match(self.dsl[:error_number]) == '0'
|
77
80
|
end
|
78
|
-
if self.dsl[:error_message]
|
79
|
-
fail TaxCloud::Errors::ApiError.new(match(self.dsl[:error_message]), raw)
|
80
|
-
end
|
81
|
+
raise TaxCloud::Errors::ApiError.new(match(self.dsl[:error_message]), raw) if self.dsl[:error_message]
|
81
82
|
end
|
82
83
|
end
|
83
84
|
end
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TaxCloud #:nodoc:
|
2
4
|
module Responses #:nodoc:
|
3
5
|
# Response to a TaxCloud Captured API call.
|
4
6
|
#
|
5
|
-
# See https://api.taxcloud.
|
7
|
+
# See https://api.taxcloud.com/1.0/TaxCloud.asmx?op=Captured.
|
6
8
|
class Captured < Generic
|
7
9
|
response_key :captured
|
8
10
|
end
|
@@ -1,8 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bigdecimal'
|
4
|
+
|
1
5
|
module TaxCloud #:nodoc:
|
2
6
|
module Responses #:nodoc:
|
3
7
|
# A single item in the response to a TaxCloud Lookup API call.
|
4
8
|
#
|
5
|
-
# See https://api.taxcloud.
|
9
|
+
# See https://api.taxcloud.com/1.0/TaxCloud.asmx?op=Lookup.
|
6
10
|
class CartItem
|
7
11
|
# The index of the cart item.
|
8
12
|
attr_accessor :cart_item_index
|
@@ -14,7 +18,7 @@ module TaxCloud #:nodoc:
|
|
14
18
|
# [savon_response] SOAP response.
|
15
19
|
def initialize(savon_response)
|
16
20
|
self.cart_item_index = savon_response[:cart_item_index].to_i
|
17
|
-
self.tax_amount = savon_response[:tax_amount]
|
21
|
+
self.tax_amount = BigDecimal(savon_response[:tax_amount])
|
18
22
|
end
|
19
23
|
end
|
20
24
|
end
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TaxCloud #:nodoc:
|
2
4
|
module Responses #:nodoc:
|
3
5
|
# Response to a TaxCloud Lookup API call.
|
4
6
|
#
|
5
|
-
# See https://api.taxcloud.
|
7
|
+
# See https://api.taxcloud.com/1.0/TaxCloud.asmx?op=Lookup.
|
6
8
|
class Lookup < Base
|
7
9
|
# Cart ID.
|
8
10
|
attr_accessor :cart_id
|
@@ -20,13 +22,13 @@ module TaxCloud #:nodoc:
|
|
20
22
|
self.cart_id = match('lookup_response/lookup_result/cart_id')
|
21
23
|
# there can be on response or an array of responses
|
22
24
|
cart_item_responses = match('lookup_response/lookup_result/cart_items_response/cart_item_response')
|
23
|
-
if cart_item_responses.is_a?(Array)
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
self.cart_items = if cart_item_responses.is_a?(Array)
|
26
|
+
cart_item_responses.map do |cart_item_response|
|
27
|
+
TaxCloud::Responses::CartItem.new(cart_item_response)
|
28
|
+
end
|
29
|
+
else
|
30
|
+
[TaxCloud::Responses::CartItem.new(cart_item_responses)]
|
31
|
+
end
|
30
32
|
end
|
31
33
|
|
32
34
|
# Total tax amount in this cart.
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TaxCloud #:nodoc:
|
2
4
|
module Responses #:nodoc:
|
3
5
|
# Response to a TaxCloud Ping API call.
|
4
6
|
#
|
5
|
-
# See https://api.taxcloud.
|
7
|
+
# See https://api.taxcloud.com/1.0/TaxCloud.asmx?op=Ping.
|
6
8
|
class Ping < Generic
|
7
9
|
response_key :ping
|
8
10
|
end
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TaxCloud #:nodoc:
|
2
4
|
module Responses #:nodoc:
|
3
5
|
# Response to a TaxCloud Returned API call.
|
4
6
|
#
|
5
|
-
# See https://api.taxcloud.
|
7
|
+
# See https://api.taxcloud.com/1.0/TaxCloud.asmx?op=Returned.
|
6
8
|
class Returned < Generic
|
7
9
|
response_key :returned
|
8
10
|
end
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TaxCloud #:nodoc:
|
2
4
|
module Responses #:nodoc:
|
3
5
|
# Response to a TaxCloud getTICGroups API call.
|
4
6
|
#
|
5
|
-
# https://api.taxcloud.
|
7
|
+
# https://api.taxcloud.com/1.0/TaxCloud.asmx?op=GetTICGroups
|
6
8
|
class TaxCodeGroups < Base
|
7
9
|
response_type 'get_tic_groups_response/get_tic_groups_result/response_type'
|
8
10
|
error_message 'get_tic_groups_response/get_tic_groups_result/messages/response_message/message'
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TaxCloud #:nodoc:
|
2
4
|
module Responses #:nodoc:
|
3
5
|
# Response to a TaxCloud getTICs API call.
|
4
6
|
#
|
5
|
-
# See https://api.taxcloud.
|
7
|
+
# See https://api.taxcloud.com/1.0/TaxCloud.asmx?op=GetTICs.
|
6
8
|
class TaxCodes < Base
|
7
9
|
response_type 'get_ti_cs_response/get_ti_cs_result/response_type'
|
8
10
|
error_message 'get_ti_cs_response/get_ti_cs_result/messages/response_message/message'
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TaxCloud #:nodoc:
|
2
4
|
module Responses #:nodoc:
|
3
5
|
# Response to a TaxCloud getTICsByGroup API call.
|
4
6
|
#
|
5
|
-
# See https://api.taxcloud.
|
7
|
+
# See https://api.taxcloud.com/1.0/TaxCloud.asmx?op=GetTICsByGroup.
|
6
8
|
class TaxCodesByGroup < Base
|
7
9
|
response_type 'get_ti_cs_by_group_response/get_ti_cs_by_group_result/response_type'
|
8
10
|
error_message 'get_ti_cs_by_group_response/get_ti_cs_by_group_result/messages/response_message/message'
|
@@ -1,8 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module TaxCloud #:nodoc:
|
2
4
|
module Responses #:nodoc:
|
3
5
|
# Response to a TaxCloud VerifyAddress API call.
|
4
6
|
#
|
5
|
-
# See https://api.taxcloud.
|
7
|
+
# See https://api.taxcloud.com/1.0/TaxCloud.asmx?op=VerifyAddress.
|
6
8
|
class VerifyAddress < Base
|
7
9
|
error_number 'verify_address_response/verify_address_result/err_number'
|
8
10
|
error_message 'verify_address_response/verify_address_result/err_description'
|
data/lib/tax_cloud/responses.rb
CHANGED