suretax 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +27 -0
- data/.travis.yml +14 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +74 -0
- data/Gemfile.travis +12 -0
- data/LICENSE.txt +22 -0
- data/NOTES.md +3 -0
- data/README.md +58 -0
- data/Rakefile +1 -0
- data/circle.yml +7 -0
- data/lib/suretax.rb +24 -0
- data/lib/suretax/api.rb +7 -0
- data/lib/suretax/api/cancel_request.rb +64 -0
- data/lib/suretax/api/group.rb +16 -0
- data/lib/suretax/api/item_message.rb +13 -0
- data/lib/suretax/api/request.rb +133 -0
- data/lib/suretax/api/request_item.rb +84 -0
- data/lib/suretax/api/response.rb +53 -0
- data/lib/suretax/api/tax.rb +25 -0
- data/lib/suretax/api/tax_amount.rb +46 -0
- data/lib/suretax/concerns.rb +7 -0
- data/lib/suretax/concerns/validatable.rb +208 -0
- data/lib/suretax/configuration.rb +84 -0
- data/lib/suretax/connection.rb +48 -0
- data/lib/suretax/constants.rb +7 -0
- data/lib/suretax/constants/regulatory_codes.rb +11 -0
- data/lib/suretax/constants/response_groups.rb +8 -0
- data/lib/suretax/constants/sales_type_codes.rb +8 -0
- data/lib/suretax/constants/tax_situs_codes.rb +12 -0
- data/lib/suretax/constants/transaction_type_codes.rb +505 -0
- data/lib/suretax/response.rb +70 -0
- data/lib/suretax/version.rb +3 -0
- data/spec/lib/suretax/api/group_spec.rb +50 -0
- data/spec/lib/suretax/api/request_item_spec.rb +54 -0
- data/spec/lib/suretax/api/request_item_validations_spec.rb +237 -0
- data/spec/lib/suretax/api/request_spec.rb +197 -0
- data/spec/lib/suretax/api/request_validations_spec.rb +384 -0
- data/spec/lib/suretax/api/response_spec.rb +165 -0
- data/spec/lib/suretax/api/tax_amount_spec.rb +37 -0
- data/spec/lib/suretax/api/tax_spec.rb +59 -0
- data/spec/lib/suretax/configuration_spec.rb +97 -0
- data/spec/lib/suretax/connection_spec.rb +77 -0
- data/spec/lib/suretax/response_spec.rb +136 -0
- data/spec/spec_helper.rb +45 -0
- data/spec/support/cancellation_helper.rb +31 -0
- data/spec/support/connection_shared_examples.rb +37 -0
- data/spec/support/request_helper.rb +309 -0
- data/spec/support/suretax_helper.rb +27 -0
- data/spec/support/validations_shared_examples.rb +28 -0
- data/suretax.gemspec +33 -0
- metadata +281 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 090d466426a8ed2734e208ca3e310afa0fca041c
|
4
|
+
data.tar.gz: 890130d8629a6ff1ca5d959202a6d640753397b6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0509fea19ea7ce6a32f96a2888b8c1b170f028a9c0cdf5be786f221c9cf7f177498675795c27517c07ecd1cb6157203fb4e3b78d1f929eeddbf234446d342db5
|
7
|
+
data.tar.gz: 0daa94af83c1320f63869a7607528a45de24d8da108d7ff2e86718e4bff66f55061331d6b7317f262f804a0fe4f9cdfe5d0740095a8833ffdd36709042825c7a
|
data/.gitignore
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
._*
|
2
|
+
.bundle
|
3
|
+
.DS_Store
|
4
|
+
.rvmrc
|
5
|
+
.ruby-version
|
6
|
+
.ruby-gemset
|
7
|
+
.pow*
|
8
|
+
|
9
|
+
*.gem
|
10
|
+
*.swp
|
11
|
+
database.yml
|
12
|
+
application.yml
|
13
|
+
|
14
|
+
tmp/*
|
15
|
+
log/*
|
16
|
+
coverage/*
|
17
|
+
vendor/bundle
|
18
|
+
|
19
|
+
spec/dummy/log/*
|
20
|
+
spec/dummy/tmp/*
|
21
|
+
spec/dummy/vendor/bundle/*
|
22
|
+
spec/dummy/coverage
|
23
|
+
|
24
|
+
!spec/dummy/config/database.yml
|
25
|
+
|
26
|
+
.env
|
27
|
+
dump.rdb
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
suretax (0.1.0)
|
5
|
+
faraday
|
6
|
+
monetize
|
7
|
+
money
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
addressable (2.3.5)
|
13
|
+
awesome_print (1.2.0)
|
14
|
+
coderay (1.1.0)
|
15
|
+
crack (0.4.2)
|
16
|
+
safe_yaml (~> 1.0.0)
|
17
|
+
diff-lcs (1.2.5)
|
18
|
+
docile (1.1.3)
|
19
|
+
dotenv (0.9.0)
|
20
|
+
faraday (0.9.0)
|
21
|
+
multipart-post (>= 1.2, < 3)
|
22
|
+
i18n (0.7.0.beta1)
|
23
|
+
method_source (0.8.2)
|
24
|
+
monetize (0.4.1)
|
25
|
+
money (~> 6.2.1)
|
26
|
+
money (6.2.1)
|
27
|
+
i18n (>= 0.6.4, <= 0.7.0.dev)
|
28
|
+
multi_json (1.8.4)
|
29
|
+
multipart-post (2.0.0)
|
30
|
+
pry (0.9.12.6)
|
31
|
+
coderay (~> 1.0)
|
32
|
+
method_source (~> 0.8)
|
33
|
+
slop (~> 3.4)
|
34
|
+
rake (10.1.1)
|
35
|
+
rspec (3.0.0)
|
36
|
+
rspec-core (~> 3.0.0)
|
37
|
+
rspec-expectations (~> 3.0.0)
|
38
|
+
rspec-mocks (~> 3.0.0)
|
39
|
+
rspec-core (3.0.2)
|
40
|
+
rspec-support (~> 3.0.0)
|
41
|
+
rspec-expectations (3.0.2)
|
42
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
43
|
+
rspec-support (~> 3.0.0)
|
44
|
+
rspec-its (1.0.1)
|
45
|
+
rspec-core (>= 2.99.0.beta1)
|
46
|
+
rspec-expectations (>= 2.99.0.beta1)
|
47
|
+
rspec-mocks (3.0.2)
|
48
|
+
rspec-support (~> 3.0.0)
|
49
|
+
rspec-support (3.0.2)
|
50
|
+
safe_yaml (1.0.1)
|
51
|
+
simplecov (0.8.2)
|
52
|
+
docile (~> 1.1.0)
|
53
|
+
multi_json
|
54
|
+
simplecov-html (~> 0.8.0)
|
55
|
+
simplecov-html (0.8.0)
|
56
|
+
slop (3.4.7)
|
57
|
+
webmock (1.17.3)
|
58
|
+
addressable (>= 2.2.7)
|
59
|
+
crack (>= 0.3.2)
|
60
|
+
|
61
|
+
PLATFORMS
|
62
|
+
ruby
|
63
|
+
|
64
|
+
DEPENDENCIES
|
65
|
+
awesome_print
|
66
|
+
bundler (~> 1.3)
|
67
|
+
dotenv
|
68
|
+
pry
|
69
|
+
rake
|
70
|
+
rspec (~> 3.0.0)
|
71
|
+
rspec-its (~> 1.0)
|
72
|
+
simplecov
|
73
|
+
suretax!
|
74
|
+
webmock
|
data/Gemfile.travis
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# Special Travis Gemfile for Rubinius
|
2
|
+
source 'https://rubygems.org'
|
3
|
+
|
4
|
+
platforms :rbx do
|
5
|
+
gem 'rubysl', '~> 2.0'
|
6
|
+
gem 'rubysl-openssl', '~> 2.1.0'
|
7
|
+
gem 'psych'
|
8
|
+
gem 'rubinius-coverage'
|
9
|
+
gem 'json', '~> 1.8'
|
10
|
+
end
|
11
|
+
|
12
|
+
eval_gemfile File.expand_path('../Gemfile', __FILE__)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Damon Davison
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/NOTES.md
ADDED
data/README.md
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
[](https://codeclimate.com/github/bqsoft/suretax)
|
2
|
+
[](https://travis-ci.org/bqsoft/suretax)
|
3
|
+
# Suretax
|
4
|
+
|
5
|
+
|
6
|
+
## Synopsis
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
Suretax.configure do |c|
|
10
|
+
c.validation_key = ENV['SURETAX_VALIDATION_KEY']
|
11
|
+
c.base_url = ENV['SURETAX_BASE_URL']
|
12
|
+
c.client_number = ENV['SURETAX_CLIENT_NUMBER']
|
13
|
+
c.request_version = ENV['SURETAX_REQUEST_VERSION']
|
14
|
+
c.cancel_version = ENV['SURETAX_CANCEL_VERSION']
|
15
|
+
end
|
16
|
+
|
17
|
+
request = Suretax::Api::Request.new({ initial: data })
|
18
|
+
request.items = [ Suretax::Api::RequestItem.new({ initial: data }) ]
|
19
|
+
connection = Suretax::Connection.new
|
20
|
+
|
21
|
+
if request.valid?
|
22
|
+
response = connection.post(body: request.params)
|
23
|
+
response.params
|
24
|
+
end
|
25
|
+
```
|
26
|
+
|
27
|
+
The configuration object is used to provide default values for
|
28
|
+
Suretax transactions. The validation_key, client_number, and
|
29
|
+
base_url may be overridden by supplying the key when instantiating
|
30
|
+
a Suretax::Api::Request object.
|
31
|
+
|
32
|
+
|
33
|
+
If not supplied, the base_url will default to the Suretax test
|
34
|
+
host (https://testapi.taxrating.net) and the request version
|
35
|
+
and cancel version will default to the latest versions available
|
36
|
+
(currently V03 and V01 respectively).
|
37
|
+
|
38
|
+
|
39
|
+
You can peek inside the tests for more examples and to see what data
|
40
|
+
methods are available.
|
41
|
+
|
42
|
+
|
43
|
+
## Development Environment
|
44
|
+
|
45
|
+
Suretax uses [dotenv] to easily switch between development/test environments
|
46
|
+
and production.
|
47
|
+
|
48
|
+
You will need to set the following environment variables for the gem to work:
|
49
|
+
|
50
|
+
- `SURETAX_VALIDATION_KEY` (You can get this from [SureTax][suretax].)
|
51
|
+
- `SURETAX_BASE_URL` (This is usually `https://testapi.taxrating.net` for testing.)
|
52
|
+
|
53
|
+
You can do this by creating a .env file in the root of the Suretax gem
|
54
|
+
repository (gitignored by default). For more information, please see
|
55
|
+
the [dotenv documentation][dotenv]
|
56
|
+
|
57
|
+
[dotenv]: https://github.com/bkeepers/dotenv
|
58
|
+
[suretax]: http://suretax.com
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/circle.yml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
machine:
|
2
|
+
environment:
|
3
|
+
SURETAX_BASE_URL: "https://testapi.taxrating.net"
|
4
|
+
SURETAX_VALIDATION_KEY: "xxxxxxxxxx"
|
5
|
+
SURETAX_CLIENT_NUMBER: "000000000"
|
6
|
+
SURETAX_POST_PATH: "/Services/V01/SureTax.asmx/PostRequest"
|
7
|
+
SURETAX_CANCEL_PATH: "/Services/V01/SureTax.asmx/CancelPostRequest"
|
data/lib/suretax.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require "suretax/version"
|
2
|
+
|
3
|
+
require "suretax/concerns"
|
4
|
+
|
5
|
+
require "suretax/configuration"
|
6
|
+
require "suretax/connection"
|
7
|
+
require "suretax/response"
|
8
|
+
require "suretax/constants"
|
9
|
+
require "suretax/api"
|
10
|
+
|
11
|
+
require "money"
|
12
|
+
|
13
|
+
module Suretax
|
14
|
+
|
15
|
+
class << self
|
16
|
+
attr_accessor :configuration
|
17
|
+
|
18
|
+
def configure
|
19
|
+
yield(configuration)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
self.configuration ||= Configuration.instance
|
24
|
+
end
|
data/lib/suretax/api.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
module Suretax
|
2
|
+
module Api
|
3
|
+
#
|
4
|
+
# Given a transaction ID, sends a request to cancel
|
5
|
+
# that transaction to Suretax.
|
6
|
+
#
|
7
|
+
class CancelRequest
|
8
|
+
attr_accessor :client_number, :validation_key, :transaction,
|
9
|
+
:client_tracking
|
10
|
+
|
11
|
+
attr_reader :response
|
12
|
+
|
13
|
+
def initialize(options = {})
|
14
|
+
self.client_number = options.fetch(:client_number,
|
15
|
+
configuration.client_number)
|
16
|
+
self.validation_key = options.fetch(:validation_key,
|
17
|
+
configuration.validation_key)
|
18
|
+
|
19
|
+
options.each_pair do |key, value|
|
20
|
+
send("#{key.to_s}=", value.to_s)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def submit
|
25
|
+
log_request
|
26
|
+
suretax_response = connection.cancel(params)
|
27
|
+
|
28
|
+
log_response(suretax_response)
|
29
|
+
@response = Suretax::Api::Response.new(suretax_response.body)
|
30
|
+
end
|
31
|
+
|
32
|
+
def params
|
33
|
+
{
|
34
|
+
'ClientNumber' => client_number,
|
35
|
+
'ClientTracking' => client_tracking,
|
36
|
+
'TransId' => transaction,
|
37
|
+
'ValidationKey' => validation_key
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def log_request
|
44
|
+
logger.info "\nSureTax Cancellation sent:\n#{params.inspect}" if logger
|
45
|
+
end
|
46
|
+
|
47
|
+
def log_response(response)
|
48
|
+
logger.info("\nSureTax Cancellation resp:\n#{response.inspect}") if logger
|
49
|
+
end
|
50
|
+
|
51
|
+
def logger
|
52
|
+
configuration.logger
|
53
|
+
end
|
54
|
+
|
55
|
+
def configuration
|
56
|
+
Suretax.configuration
|
57
|
+
end
|
58
|
+
|
59
|
+
def connection
|
60
|
+
@connection ||= Connection.new
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Suretax
|
2
|
+
module Api
|
3
|
+
class Group
|
4
|
+
attr_reader :state, :customer, :invoice, :taxes, :line
|
5
|
+
|
6
|
+
def initialize(response_params)
|
7
|
+
@state = response_params.fetch('StateCode')
|
8
|
+
@invoice = response_params.fetch('InvoiceNumber')
|
9
|
+
@line = response_params['LineNumber']
|
10
|
+
@customer = response_params.fetch('CustomerNumber')
|
11
|
+
@taxes = response_params.fetch('TaxList').map { |tax| Tax.new(tax) }
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Suretax
|
2
|
+
module Api
|
3
|
+
class ItemMessage
|
4
|
+
attr_reader :line_number, :response_code, :message
|
5
|
+
|
6
|
+
def initialize(response_params)
|
7
|
+
@line_number = response_params.fetch('LineNumber')
|
8
|
+
@response_code = response_params.fetch('ResponseCode')
|
9
|
+
@message = response_params.fetch('Message')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
module Suretax
|
2
|
+
module Api
|
3
|
+
class ValidationError < StandardError; end
|
4
|
+
|
5
|
+
class Request
|
6
|
+
include Suretax::Concerns::Validatable
|
7
|
+
|
8
|
+
attr_accessor :business_unit,
|
9
|
+
:client_number,
|
10
|
+
:client_tracking,
|
11
|
+
:data_month,
|
12
|
+
:data_year,
|
13
|
+
:industry_exemption,
|
14
|
+
:response_group,
|
15
|
+
:response_type,
|
16
|
+
:return_file_code,
|
17
|
+
:total_revenue,
|
18
|
+
:validation_key,
|
19
|
+
:items
|
20
|
+
|
21
|
+
attr_reader :response
|
22
|
+
|
23
|
+
validate :client_number,
|
24
|
+
:business_unit,
|
25
|
+
:validation_key,
|
26
|
+
:data_year,
|
27
|
+
:data_month,
|
28
|
+
:total_revenue,
|
29
|
+
:return_file_code,
|
30
|
+
:client_tracking,
|
31
|
+
:response_group,
|
32
|
+
:response_type,
|
33
|
+
:items
|
34
|
+
|
35
|
+
def initialize(options = {})
|
36
|
+
self.return_file_code = '0'
|
37
|
+
self.client_number = options.delete(:client_number) || configuration.client_number
|
38
|
+
self.validation_key = options.delete(:validation_key) || configuration.validation_key
|
39
|
+
|
40
|
+
default_data_date(options)
|
41
|
+
|
42
|
+
options.each_pair do |key,value|
|
43
|
+
self.send("#{key.to_s}=", value.to_s)
|
44
|
+
end
|
45
|
+
|
46
|
+
initialize_items(options)
|
47
|
+
|
48
|
+
validate!
|
49
|
+
end
|
50
|
+
|
51
|
+
def submit
|
52
|
+
if valid?
|
53
|
+
log_request
|
54
|
+
suretax_response = connection.post(params)
|
55
|
+
@response = Suretax::Api::Response.new(suretax_response.body)
|
56
|
+
else
|
57
|
+
raise(ValidationError, errors.messages.join(", "))
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def valid?
|
62
|
+
!errors.any?
|
63
|
+
end
|
64
|
+
|
65
|
+
def rollback
|
66
|
+
if response
|
67
|
+
CancelRequest.new(transaction: response.transaction,
|
68
|
+
client_number: client_number, validation_key: validation_key,
|
69
|
+
client_tracking: client_tracking).submit
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def params
|
74
|
+
{
|
75
|
+
"ClientNumber" => client_number,
|
76
|
+
"BusinessUnit" => business_unit || '',
|
77
|
+
"ValidationKey" => validation_key,
|
78
|
+
"DataYear" => data_year,
|
79
|
+
"DataMonth" => data_month,
|
80
|
+
"TotalRevenue" => total_revenue.to_f,
|
81
|
+
"ReturnFileCode" => return_file_code,
|
82
|
+
"ClientTracking" => client_tracking || '',
|
83
|
+
"IndustryExemption" => industry_exemption,
|
84
|
+
"ResponseType" => response_type,
|
85
|
+
"ResponseGroup" => response_group,
|
86
|
+
"ItemList" => items.map { |item| item.params }
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def default_data_date(options)
|
93
|
+
max_date = configuration.test? ? Date.today.prev_month : Date.today
|
94
|
+
|
95
|
+
requested_date = begin
|
96
|
+
Date.new(options[:data_year].to_i, options[:data_month].to_i, 1)
|
97
|
+
rescue
|
98
|
+
max_date
|
99
|
+
end
|
100
|
+
|
101
|
+
data_date = [requested_date, max_date].min
|
102
|
+
|
103
|
+
self.data_month = data_date.strftime('%m')
|
104
|
+
self.data_year = data_date.strftime('%Y')
|
105
|
+
end
|
106
|
+
|
107
|
+
def initialize_items(options)
|
108
|
+
self.items = []
|
109
|
+
if options[:items].respond_to?(:each)
|
110
|
+
options[:items].each do |item_args|
|
111
|
+
self.items << RequestItem.new(item_args)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def log_request
|
117
|
+
logger.info "\nSureTax Request sent:\n#{params.inspect}" if logger
|
118
|
+
end
|
119
|
+
|
120
|
+
def logger
|
121
|
+
configuration.logger
|
122
|
+
end
|
123
|
+
|
124
|
+
def configuration
|
125
|
+
Suretax.configuration
|
126
|
+
end
|
127
|
+
|
128
|
+
def connection
|
129
|
+
@connection ||= Connection.new
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|