tax_cloud 0.3.0 → 0.5.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 (86) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/test.yml +30 -0
  3. data/.rubocop.yml +9 -25
  4. data/.rubocop_todo.yml +47 -0
  5. data/CHANGELOG.md +85 -0
  6. data/CONTRIBUTORS.txt +3 -0
  7. data/Gemfile +15 -5
  8. data/LICENSE.md +21 -0
  9. data/README.md +200 -0
  10. data/Rakefile +5 -19
  11. data/lib/config/locales/en.yml +2 -2
  12. data/lib/hash.rb +3 -4
  13. data/lib/tasks/tax_cloud.rake +4 -4
  14. data/lib/tasks/tax_code_groups.rake +11 -11
  15. data/lib/tasks/tax_codes.rake +12 -12
  16. data/lib/tax_cloud/address.rb +10 -5
  17. data/lib/tax_cloud/cart_item.rb +2 -0
  18. data/lib/tax_cloud/client.rb +13 -3
  19. data/lib/tax_cloud/configuration.rb +13 -2
  20. data/lib/tax_cloud/errors/api_error.rb +3 -3
  21. data/lib/tax_cloud/errors/missing_config_error.rb +2 -1
  22. data/lib/tax_cloud/errors/missing_config_option_error.rb +2 -1
  23. data/lib/tax_cloud/errors/soap_error.rb +6 -6
  24. data/lib/tax_cloud/errors/tax_cloud_error.rb +5 -4
  25. data/lib/tax_cloud/errors/unexpected_soap_response_error.rb +3 -3
  26. data/lib/tax_cloud/errors.rb +2 -0
  27. data/lib/tax_cloud/record.rb +2 -0
  28. data/lib/tax_cloud/responses/authorized.rb +3 -1
  29. data/lib/tax_cloud/responses/authorized_with_capture.rb +3 -1
  30. data/lib/tax_cloud/responses/base.rb +5 -4
  31. data/lib/tax_cloud/responses/captured.rb +3 -1
  32. data/lib/tax_cloud/responses/cart_item.rb +6 -2
  33. data/lib/tax_cloud/responses/generic.rb +2 -0
  34. data/lib/tax_cloud/responses/lookup.rb +10 -8
  35. data/lib/tax_cloud/responses/ping.rb +3 -1
  36. data/lib/tax_cloud/responses/returned.rb +3 -1
  37. data/lib/tax_cloud/responses/tax_code_groups.rb +3 -1
  38. data/lib/tax_cloud/responses/tax_codes.rb +3 -1
  39. data/lib/tax_cloud/responses/tax_codes_by_group.rb +3 -1
  40. data/lib/tax_cloud/responses/verify_address.rb +3 -1
  41. data/lib/tax_cloud/responses.rb +2 -0
  42. data/lib/tax_cloud/tax_code.rb +2 -0
  43. data/lib/tax_cloud/tax_code_constants.rb +262 -260
  44. data/lib/tax_cloud/tax_code_group.rb +3 -1
  45. data/lib/tax_cloud/tax_code_group_constants.rb +2 -0
  46. data/lib/tax_cloud/tax_code_groups.rb +3 -1
  47. data/lib/tax_cloud/tax_codes.rb +3 -1
  48. data/lib/tax_cloud/transaction.rb +2 -0
  49. data/lib/tax_cloud/version.rb +3 -1
  50. data/lib/tax_cloud.rb +8 -3
  51. data/tax_cloud.gemspec +17 -18
  52. data/test/cassettes/authorized.yml +6 -6
  53. data/test/cassettes/authorized_with_capture.yml +6 -6
  54. data/test/cassettes/authorized_with_localized_time.yml +6 -6
  55. data/test/cassettes/captured.yml +7 -7
  56. data/test/cassettes/get_tic_groups.yml +5 -5
  57. data/test/cassettes/get_tics.yml +5 -5
  58. data/test/cassettes/get_tics_by_group.yml +5 -5
  59. data/test/cassettes/invalid_soap_call.yml +5 -5
  60. data/test/cassettes/lookup.yml +5 -5
  61. data/test/cassettes/lookup_ny.yml +5 -5
  62. data/test/cassettes/ping.yml +5 -5
  63. data/test/cassettes/ping_with_invalid_credentials.yml +5 -5
  64. data/test/cassettes/ping_with_invalid_response.yml +5 -5
  65. data/test/cassettes/returned.yml +7 -7
  66. data/test/cassettes/verify_bad_address.yml +5 -5
  67. data/test/cassettes/verify_good_address.yml +5 -5
  68. data/test/helper.rb +3 -1
  69. data/test/test_address.rb +7 -5
  70. data/test/test_cart_item.rb +3 -1
  71. data/test/test_client.rb +4 -2
  72. data/test/test_configuration_optional_keys.rb +44 -0
  73. data/test/{test_configuration.rb → test_configuration_required_keys.rb} +6 -4
  74. data/test/test_lookup_response.rb +22 -0
  75. data/test/test_setup.rb +3 -1
  76. data/test/test_soap.rb +3 -1
  77. data/test/test_tax_code_groups.rb +4 -2
  78. data/test/test_tax_codes.rb +3 -1
  79. data/test/test_transaction.rb +3 -1
  80. data/test/test_transaction_ny.rb +3 -1
  81. data/test/vcr_setup.rb +2 -0
  82. metadata +37 -91
  83. data/.travis.yml +0 -6
  84. data/CHANGELOG.rdoc +0 -42
  85. data/LICENSE.rdoc +0 -22
  86. data/README.rdoc +0 -140
@@ -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
- params = params.merge(
23
- 'uspsUserID' => TaxCloud.configuration.usps_username
24
- ) if TaxCloud.configuration.usps_username
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.length > 0
33
- [zip5, zip4].select { |z| z && z.length > 0 }.join('-')
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module TaxCloud #:nodoc:
2
4
  # A <tt>CartItem</tt> defines a single line item for the purchase. Used to calculate the tax amount.
3
5
  class CartItem < Record
@@ -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 wsdl: TaxCloud::WSDL_URL
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 safe(&block)
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.new(e)
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
- fail TaxCloud::Errors::MissingConfigOption.new('api_login_id') unless api_login_id && api_login_id.strip.length > 0
16
- fail TaxCloud::Errors::MissingConfigOption.new('api_key') unless api_key && api_key.strip.length > 0
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
- # encoding: utf-8
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
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  module TaxCloud #:nodoc:
3
4
  module Errors #:nodoc:
4
5
  # This error is raised when attempting to create a new client
@@ -1,4 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  module TaxCloud #:nodoc:
3
4
  module Errors #:nodoc:
4
5
  # This error is raised when a configuration
@@ -1,4 +1,5 @@
1
- # encoding: utf-8
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(e)
13
- @fault = e
14
- e.to_hash.tap do |fault|
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
- # encoding: utf-8
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
- # encoding: utf-8
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'tax_cloud/errors/tax_cloud_error'
2
4
  require 'tax_cloud/errors/missing_config_error'
3
5
  require 'tax_cloud/errors/missing_config_option_error'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module TaxCloud #:nodoc:
2
4
  # A generic TaxCloud record.
3
5
  class Record
@@ -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.net/1.0/TaxCloud.asmx?op=Authorized.
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.net/1.0/TaxCloud.asmx?op=AuthorizedWithCapture.
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
- fail TaxCloud::Errors::UnexpectedSoapResponse.new(raw, key, chain)
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.net/1.0/TaxCloud.asmx?op=Captured.
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.net/1.0/TaxCloud.asmx?op=Lookup.
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].to_f
21
+ self.tax_amount = BigDecimal(savon_response[:tax_amount])
18
22
  end
19
23
  end
20
24
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module TaxCloud #:nodoc:
2
4
  module Responses #:nodoc:
3
5
  # A generic response to a TaxCloud API call.
@@ -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.net/1.0/TaxCloud.asmx?op=Lookup.
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
- self.cart_items = cart_item_responses.map do |cart_item_response|
25
- TaxCloud::Responses::CartItem.new(cart_item_response)
26
- end
27
- else
28
- self.cart_items = [TaxCloud::Responses::CartItem.new(cart_item_responses)]
29
- end
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.net/1.0/TaxCloud.asmx?op=Ping.
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.net/1.0/TaxCloud.asmx?op=Returned.
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.net/1.0/TaxCloud.asmx?op=GetTICGroups
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.net/1.0/TaxCloud.asmx?op=GetTICs.
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.net/1.0/TaxCloud.asmx?op=GetTICsByGroup.
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.net/1.0/TaxCloud.asmx?op=VerifyAddress.
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'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'tax_cloud/responses/base'
2
4
  require 'tax_cloud/responses/generic'
3
5
  require 'tax_cloud/responses/ping'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module TaxCloud #:nodoc:
2
4
  # A TIC (Taxability Information Code), otherwise known as a Tax Code.
3
5
  #