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.
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
  #