taxjar-ruby 1.0.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 +19 -0
- data/.rspec +2 -0
- data/Gemfile +11 -0
- data/LICENSE.txt +22 -0
- data/README.md +173 -0
- data/Rakefile +2 -0
- data/lib/taxjar.rb +15 -0
- data/lib/taxjar/api/api.rb +37 -0
- data/lib/taxjar/api/request.rb +70 -0
- data/lib/taxjar/api/utils.rb +40 -0
- data/lib/taxjar/base.rb +88 -0
- data/lib/taxjar/breakdown.rb +16 -0
- data/lib/taxjar/breakdown_line_item.rb +10 -0
- data/lib/taxjar/category.rb +7 -0
- data/lib/taxjar/client.rb +25 -0
- data/lib/taxjar/error.rb +74 -0
- data/lib/taxjar/line_item.rb +9 -0
- data/lib/taxjar/order.rb +13 -0
- data/lib/taxjar/rate.rb +9 -0
- data/lib/taxjar/refund.rb +13 -0
- data/lib/taxjar/shipping.rb +9 -0
- data/lib/taxjar/tax.rb +11 -0
- data/lib/taxjar/version.rb +38 -0
- data/spec/fixtures/categories.json +39 -0
- data/spec/fixtures/order.json +26 -0
- data/spec/fixtures/rates.json +13 -0
- data/spec/fixtures/refund.json +27 -0
- data/spec/fixtures/taxes.json +42 -0
- data/spec/helper.rb +45 -0
- data/spec/taxjar/api/api_spec.rb +207 -0
- data/spec/taxjar/api/request_spec.rb +134 -0
- data/spec/taxjar/base_spec.rb +28 -0
- data/spec/taxjar/client_spec.rb +23 -0
- data/spec/taxjar/error_spec.rb +21 -0
- data/spec/taxjar/version_spec.rb +34 -0
- data/taxjar-ruby.gemspec +26 -0
- metadata +163 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'taxjar/base'
|
2
|
+
require 'taxjar/shipping'
|
3
|
+
|
4
|
+
module Taxjar
|
5
|
+
class Breakdown < Taxjar::Base
|
6
|
+
attr_reader :state_taxable_amount, :state_tax_collectable, :county_taxable_amount,
|
7
|
+
:county_tax_collectable, :city_tax_collectable,
|
8
|
+
:special_district_taxable_amount, :special_district_tax_collectable
|
9
|
+
|
10
|
+
object_attr_reader Taxjar::Shipping, :shipping
|
11
|
+
|
12
|
+
def line_items
|
13
|
+
@line_items ||= map_collection(Taxjar::BreakdownLineItem, :line_items)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'taxjar/base'
|
2
|
+
|
3
|
+
module Taxjar
|
4
|
+
class BreakdownLineItem < Taxjar::Base
|
5
|
+
attr_reader :id, :state_taxable_amount, :state_sales_tax_rate, :county_taxable_amount,
|
6
|
+
:county_tax_rate, :city_taxable_amount, :city_tax_rate, :special_district_taxable_amount
|
7
|
+
:special_tax_rate
|
8
|
+
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'taxjar/api/api'
|
2
|
+
require 'taxjar/error'
|
3
|
+
require 'taxjar/api/request'
|
4
|
+
require 'taxjar/api/utils'
|
5
|
+
module Taxjar
|
6
|
+
class Client
|
7
|
+
include Taxjar::API
|
8
|
+
attr_accessor :api_key
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
options.each do |key, value|
|
12
|
+
instance_variable_set("@#{key}", value)
|
13
|
+
end
|
14
|
+
yield(self) if block_given?
|
15
|
+
end
|
16
|
+
|
17
|
+
def api_key?
|
18
|
+
!!@api_key
|
19
|
+
end
|
20
|
+
|
21
|
+
def user_agent
|
22
|
+
"TaxjarRubyGem/#{Taxjar::Version}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/taxjar/error.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
module Taxjar
|
2
|
+
class Error < StandardError
|
3
|
+
attr_reader :code
|
4
|
+
|
5
|
+
ClientError = Class.new(self)
|
6
|
+
|
7
|
+
ServerError = Class.new(self)
|
8
|
+
|
9
|
+
# Raised when Taxjar endpoint returns the HTTP status code 400
|
10
|
+
BadRequest = Class.new(ClientError)
|
11
|
+
|
12
|
+
# Raised when Taxjar endpoint returns the HTTP status code 401
|
13
|
+
Unauthorized = Class.new(ClientError)
|
14
|
+
|
15
|
+
# Raised when Taxjar endpoint returns the HTTP status code 403
|
16
|
+
Forbidden = Class.new(ClientError)
|
17
|
+
|
18
|
+
# Raised when Taxjar endpoint returns the HTTP status code 404
|
19
|
+
NotFound = Class.new(ClientError)
|
20
|
+
|
21
|
+
# Raised when Taxjar endpoint returns the HTTP status code 405
|
22
|
+
MethodNotAllowed = Class.new(ClientError)
|
23
|
+
|
24
|
+
# Raised when Taxjar endpoint returns the HTTP status code 406
|
25
|
+
NotAcceptable = Class.new(ClientError)
|
26
|
+
|
27
|
+
# Raised when Taxjar endpoint returns the HTTP status code 410
|
28
|
+
Gone = Class.new(ClientError)
|
29
|
+
|
30
|
+
# Raised when Taxjar endpoint returns the HTTP status code 422
|
31
|
+
UnprocessableEntity = Class.new(ClientError)
|
32
|
+
|
33
|
+
# Raised when Taxjar endpoint returns the HTTP status code 429
|
34
|
+
TooManyRequests = Class.new(ClientError)
|
35
|
+
|
36
|
+
# Raised when Taxjar endpoint returns the HTTP status code 500
|
37
|
+
InternalServerError = Class.new(ServerError)
|
38
|
+
|
39
|
+
# Raised when Taxjar endpoint returns the HTTP status code 503
|
40
|
+
ServiceUnavailable = Class.new(ServerError)
|
41
|
+
|
42
|
+
ERRORS = {
|
43
|
+
400 => Taxjar::Error::BadRequest,
|
44
|
+
401 => Taxjar::Error::Unauthorized,
|
45
|
+
403 => Taxjar::Error::Forbidden,
|
46
|
+
404 => Taxjar::Error::NotFound,
|
47
|
+
405 => Taxjar::Error::MethodNotAllowed,
|
48
|
+
406 => Taxjar::Error::NotAcceptable,
|
49
|
+
410 => Taxjar::Error::Gone,
|
50
|
+
422 => Taxjar::Error::UnprocessableEntity,
|
51
|
+
429 => Taxjar::Error::TooManyRequests,
|
52
|
+
500 => Taxjar::Error::InternalServerError,
|
53
|
+
503 => Taxjar::Error::ServiceUnavailable
|
54
|
+
}
|
55
|
+
|
56
|
+
class << self
|
57
|
+
|
58
|
+
def from_response(body)
|
59
|
+
code = body[:status]
|
60
|
+
message = body[:detail]
|
61
|
+
new(message, code)
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
def initialize(message = '', code = nil)
|
67
|
+
super(message)
|
68
|
+
@code = code
|
69
|
+
end
|
70
|
+
|
71
|
+
ConfigurationError = Class.new(::ArgumentError)
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
data/lib/taxjar/order.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'taxjar/base'
|
2
|
+
|
3
|
+
module Taxjar
|
4
|
+
class Order < Taxjar::Base
|
5
|
+
attr_reader :transaction_id, :user_id, :transaction_date, :to_country, :to_zip,
|
6
|
+
:to_state, :to_city, :to_street, :amount, :shipping, :sales_tax
|
7
|
+
|
8
|
+
def line_items
|
9
|
+
@line_items ||= map_collection(Taxjar::LineItem, :line_items)
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
data/lib/taxjar/rate.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'taxjar/base'
|
2
|
+
|
3
|
+
module Taxjar
|
4
|
+
class Refund < Taxjar::Base
|
5
|
+
|
6
|
+
attr_reader :transaction_id, :user_id, :transaction_date, :transaction_reference_id, :to_country, :to_zip,
|
7
|
+
:to_state, :to_city, :to_street, :amount, :shipping, :sales_tax
|
8
|
+
|
9
|
+
def line_items
|
10
|
+
@line_items ||= map_collection(Taxjar::LineItem, :line_items)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/taxjar/tax.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
module Taxjar
|
2
|
+
module Version
|
3
|
+
module_function
|
4
|
+
|
5
|
+
def major
|
6
|
+
1
|
7
|
+
end
|
8
|
+
|
9
|
+
def minor
|
10
|
+
0
|
11
|
+
end
|
12
|
+
|
13
|
+
def patch
|
14
|
+
0
|
15
|
+
end
|
16
|
+
|
17
|
+
def pre
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_h
|
22
|
+
{
|
23
|
+
major: major,
|
24
|
+
minor: minor,
|
25
|
+
patch: patch,
|
26
|
+
pre: pre,
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_a
|
31
|
+
to_h.values.compact
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_s
|
35
|
+
to_a.join('.')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
{
|
2
|
+
"categories": [
|
3
|
+
{
|
4
|
+
"name": "Digital Goods",
|
5
|
+
"product_tax_code": "31000",
|
6
|
+
"description": "Digital products transferred electronically, meaning obtained by the purchaser by means other than tangible storage media."
|
7
|
+
},
|
8
|
+
{
|
9
|
+
"name": "Clothing",
|
10
|
+
"product_tax_code": "20010",
|
11
|
+
"description": " All human wearing apparel suitable for general use"
|
12
|
+
},
|
13
|
+
{
|
14
|
+
"name": "Non-Prescription",
|
15
|
+
"product_tax_code": "51010",
|
16
|
+
"description": "Drugs for human use without a prescription"
|
17
|
+
},
|
18
|
+
{
|
19
|
+
"name": "Prescription",
|
20
|
+
"product_tax_code": "51020",
|
21
|
+
"description": "Drugs for human use with a prescription"
|
22
|
+
},
|
23
|
+
{
|
24
|
+
"name": "Food & Groceries",
|
25
|
+
"product_tax_code": "40030",
|
26
|
+
"description": "Food for humans consumption, unprepared"
|
27
|
+
},
|
28
|
+
{
|
29
|
+
"name": "Other Exempt",
|
30
|
+
"product_tax_code": "99999",
|
31
|
+
"description": "Item is exempt"
|
32
|
+
},
|
33
|
+
{
|
34
|
+
"name": "Software as a Service",
|
35
|
+
"product_tax_code": "30070",
|
36
|
+
"description": "Pre-written software, delivered electronically, but access remotely."
|
37
|
+
}
|
38
|
+
]
|
39
|
+
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
{
|
2
|
+
"order": {
|
3
|
+
"transaction_id": "123",
|
4
|
+
"user_id": 10649,
|
5
|
+
"transaction_date": "2015-05-14T00:00:00Z",
|
6
|
+
"to_country": "US",
|
7
|
+
"to_zip": "90002",
|
8
|
+
"to_state": "CA",
|
9
|
+
"to_city": "LOS ANGELES",
|
10
|
+
"to_street": "123 Palm Grove Ln",
|
11
|
+
"amount": "17.45",
|
12
|
+
"shipping": "1.5",
|
13
|
+
"sales_tax": "0.95",
|
14
|
+
"line_items": [
|
15
|
+
{
|
16
|
+
"id": 1,
|
17
|
+
"quantity": 1,
|
18
|
+
"product_identifier": "12-34243-9",
|
19
|
+
"description": "Fuzzy Widget",
|
20
|
+
"unit_price": "15.0",
|
21
|
+
"discount": "0.0",
|
22
|
+
"sales_tax": "0.95"
|
23
|
+
}
|
24
|
+
]
|
25
|
+
}
|
26
|
+
}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
{
|
2
|
+
"refund": {
|
3
|
+
"transaction_id": "321",
|
4
|
+
"user_id": 10649,
|
5
|
+
"transaction_date": "2015-05-14T00:00:00Z",
|
6
|
+
"transaction_reference_id": "123",
|
7
|
+
"to_country": "US",
|
8
|
+
"to_zip": "90002",
|
9
|
+
"to_state": "CA",
|
10
|
+
"to_city": "LOS ANGELES",
|
11
|
+
"to_street": "123 Palm Grove Ln",
|
12
|
+
"amount": "17.45",
|
13
|
+
"shipping": "1.5",
|
14
|
+
"sales_tax": "0.95",
|
15
|
+
"line_items": [
|
16
|
+
{
|
17
|
+
"id": 1,
|
18
|
+
"quantity": 1,
|
19
|
+
"product_identifier": "12-34243-9",
|
20
|
+
"description": "Fuzzy Widget",
|
21
|
+
"unit_price": "15.0",
|
22
|
+
"discount": "0.0",
|
23
|
+
"sales_tax": "0.95"
|
24
|
+
}
|
25
|
+
]
|
26
|
+
}
|
27
|
+
}
|
@@ -0,0 +1,42 @@
|
|
1
|
+
{
|
2
|
+
"tax": {
|
3
|
+
"order_total_amount": 16.5,
|
4
|
+
"amount_to_collect": 1.16,
|
5
|
+
"has_nexus": true,
|
6
|
+
"freight_taxable": true,
|
7
|
+
"tax_source": "destination",
|
8
|
+
"breakdown": {
|
9
|
+
"shipping": {
|
10
|
+
"state_amount": 0.11,
|
11
|
+
"state_sales_tax_rate": 0.07,
|
12
|
+
"county_amount": 0,
|
13
|
+
"county_tax_rate": 0,
|
14
|
+
"city_amount": 0,
|
15
|
+
"city_tax_rate": 0,
|
16
|
+
"special_district_amount": 0,
|
17
|
+
"special_tax_rate": 0
|
18
|
+
},
|
19
|
+
"state_taxable_amount": 16.5,
|
20
|
+
"state_tax_collectable": 1.16,
|
21
|
+
"county_taxable_amount": 0,
|
22
|
+
"county_tax_collectable": 0,
|
23
|
+
"city_taxable_amount": 0,
|
24
|
+
"city_tax_collectable": 0,
|
25
|
+
"special_district_taxable_amount": 0,
|
26
|
+
"special_district_tax_collectable": 0,
|
27
|
+
"line_items": [
|
28
|
+
{
|
29
|
+
"id": "1",
|
30
|
+
"state_taxable_amount": 15,
|
31
|
+
"state_sales_tax_rate": 0.07,
|
32
|
+
"county_taxable_amount": 0,
|
33
|
+
"county_tax_rate": 0,
|
34
|
+
"city_taxable_amount": 0,
|
35
|
+
"city_tax_rate": 0,
|
36
|
+
"special_district_taxable_amount": 0,
|
37
|
+
"special_tax_rate": 0
|
38
|
+
}
|
39
|
+
]
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
data/spec/helper.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'taxjar'
|
2
|
+
require 'rspec'
|
3
|
+
require 'webmock/rspec'
|
4
|
+
|
5
|
+
WebMock.disable_net_connect!(allow: 'coveralls.io')
|
6
|
+
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.expect_with :rspec do |c|
|
9
|
+
c.syntax = :expect
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
def a_get(path)
|
15
|
+
a_request(:get, Taxjar::API::Request::BASE_URL + path)
|
16
|
+
end
|
17
|
+
|
18
|
+
def a_post(path)
|
19
|
+
a_request(:post, Taxjar::API::Request::BASE_URL + path)
|
20
|
+
end
|
21
|
+
|
22
|
+
def a_put(path)
|
23
|
+
a_request(:put, Taxjar::API::Request::BASE_URL + path)
|
24
|
+
end
|
25
|
+
|
26
|
+
def stub_get(path)
|
27
|
+
stub_request(:get, Taxjar::API::Request::BASE_URL + path)
|
28
|
+
end
|
29
|
+
|
30
|
+
def stub_post(path)
|
31
|
+
stub_request(:post, Taxjar::API::Request::BASE_URL + path)
|
32
|
+
end
|
33
|
+
|
34
|
+
def stub_put(path)
|
35
|
+
stub_request(:put, Taxjar::API::Request::BASE_URL + path)
|
36
|
+
end
|
37
|
+
|
38
|
+
def fixture_path
|
39
|
+
File.expand_path('../fixtures', __FILE__)
|
40
|
+
end
|
41
|
+
|
42
|
+
def fixture(file)
|
43
|
+
File.new(fixture_path + '/' + file)
|
44
|
+
end
|
45
|
+
|