avalara 0.0.1

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 (47) hide show
  1. data/.gitignore +1 -0
  2. data/.rvmrc +1 -0
  3. data/CHANGELOG +5 -0
  4. data/Gemfile +8 -0
  5. data/Gemfile.lock +71 -0
  6. data/LICENSE +20 -0
  7. data/README +5 -0
  8. data/avalara.gemspec +28 -0
  9. data/lib/avalara.rb +101 -0
  10. data/lib/avalara/api.rb +23 -0
  11. data/lib/avalara/configuration.rb +29 -0
  12. data/lib/avalara/errors.rb +8 -0
  13. data/lib/avalara/parser.rb +41 -0
  14. data/lib/avalara/request.rb +11 -0
  15. data/lib/avalara/request/address.rb +19 -0
  16. data/lib/avalara/request/detail_level.rb +13 -0
  17. data/lib/avalara/request/invoice.rb +46 -0
  18. data/lib/avalara/request/line.rb +21 -0
  19. data/lib/avalara/response.rb +11 -0
  20. data/lib/avalara/response/invoice.rb +48 -0
  21. data/lib/avalara/response/message.rb +13 -0
  22. data/lib/avalara/response/tax_address.rb +16 -0
  23. data/lib/avalara/response/tax_detail.rb +16 -0
  24. data/lib/avalara/response/tax_line.rb +25 -0
  25. data/lib/avalara/types.rb +8 -0
  26. data/lib/avalara/types/date.rb +10 -0
  27. data/lib/avalara/types/stash.rb +28 -0
  28. data/lib/avalara/version.rb +5 -0
  29. data/spec/avalara.yml.example +2 -0
  30. data/spec/factories/addresses.rb +13 -0
  31. data/spec/factories/detail_levels.rb +7 -0
  32. data/spec/factories/invoices.rb +17 -0
  33. data/spec/factories/lines.rb +14 -0
  34. data/spec/fixtures/net/geographical_tax_no_sales.yml +95 -0
  35. data/spec/fixtures/net/get_tax/failure.yml +68 -0
  36. data/spec/fixtures/net/get_tax/success.yml +106 -0
  37. data/spec/models/avalara/configuration_spec.rb +55 -0
  38. data/spec/models/avalara/request/address_spec.rb +24 -0
  39. data/spec/models/avalara/request/detail_level_spec.rb +18 -0
  40. data/spec/models/avalara/request/invoice_spec.rb +33 -0
  41. data/spec/models/avalara/request/line_spec.rb +25 -0
  42. data/spec/models/avalara_spec.rb +204 -0
  43. data/spec/spec_helper.rb +17 -0
  44. data/spec/support/avalara.rb +38 -0
  45. data/spec/support/factory_girl.rb +20 -0
  46. data/spec/support/vcr.rb +14 -0
  47. metadata +204 -0
@@ -0,0 +1,21 @@
1
+ # encoding: UTF-8
2
+
3
+ module Avalara
4
+ module Request
5
+ class Line < Avalara::Types::Stash
6
+ property :LineNo, :from => :line_no, :required => true
7
+ property :DestinationCode, :from => :destination_code, :required => true
8
+ property :OriginCode, :from => :origin_code, :required => true
9
+ property :ItemCode, :from => :item_code
10
+ property :TaxCode, :from => :tax_code
11
+ property :CustomerUsageType, :from => :customer_usage_type
12
+ property :Description, :from => :description
13
+ property :Qty, :from => :qty, :required => true
14
+ property :Amount, :from => :amount, :required => true
15
+ property :Discounted, :from => :discounted
16
+ property :TaxIncluded, :from => :tax_included
17
+ property :Ref1, :from => :ref_1
18
+ property :Ref2, :from => :ref_2
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: UTF-8
2
+
3
+ module Avalara
4
+ module Response
5
+ autoload :Invoice, 'avalara/response/invoice'
6
+ autoload :Message, 'avalara/response/message'
7
+ autoload :TaxLine, 'avalara/response/tax_line'
8
+ autoload :TaxDetail, 'avalara/response/tax_detail'
9
+ autoload :TaxAddress, 'avalara/response/tax_address'
10
+ end
11
+ end
@@ -0,0 +1,48 @@
1
+ # encoding: UTF-8
2
+
3
+ module Avalara
4
+ module Response
5
+ class Invoice < Avalara::Types::Stash
6
+ property :doc_code, :from => :DocCode
7
+ property :doc_date, :from => :DocDate
8
+ property :timestamp, :from => :Timestamp
9
+ property :total_amount, :from => :TotalAmount
10
+ property :total_discount, :from => :TotalDiscount
11
+ property :total_exemption, :from => :TotalExemption
12
+ property :total_taxable, :from => :TotalTaxable
13
+ property :total_tax, :from => :TotalTax
14
+ property :total_tax_calculated, :from => :TotalTaxCalculated
15
+ property :tax_date, :from => :TaxDate
16
+ property :tax_lines, :from => :TaxLines
17
+ property :tax_addresses, :from => :TaxAddresses
18
+ property :result_code, :from => :ResultCode
19
+ property :messages, :from => :Messages
20
+
21
+ def success?
22
+ result_code == 'Success'
23
+ end
24
+
25
+ def Messages=(new_messages)
26
+ self.messages = []
27
+ new_messages.each do |message|
28
+ self.messages << Message.new(message)
29
+ end
30
+ end
31
+
32
+ def TaxLines=(lines)
33
+ self.tax_lines = []
34
+ lines.each do |line|
35
+ self.tax_lines << TaxLine.new(line)
36
+ end
37
+ end
38
+
39
+ def TaxAddresses=(addresses)
40
+ self.tax_addresses = []
41
+ addresses.each do |address|
42
+ self.tax_addresses << TaxAddress.new(address)
43
+ end
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+
3
+ module Avalara
4
+ module Response
5
+ class Message < Avalara::Types::Stash
6
+ property :summary, :from => :Summary
7
+ property :details, :from => :Details
8
+ property :refers_to, :from => :RefersTo
9
+ property :severity, :from => :Severity
10
+ property :source, :from => :Source
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,16 @@
1
+ # encoding: UTF-8
2
+
3
+ module Avalara
4
+ module Response
5
+ class TaxAddress < Avalara::Types::Stash
6
+ property :address, :from => :Address
7
+ property :address_code, :from => :AddressCode
8
+ property :city, :from => :City
9
+ property :country, :from => :Country
10
+ property :postal_code, :from => :PostalCode
11
+ property :region, :from => :Region
12
+ property :tax_region_id, :from => :TaxRegionId
13
+ property :juris_code, :from => :JurisCode
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ # encoding: UTF-8
2
+
3
+ module Avalara
4
+ module Response
5
+ class TaxDetail < Avalara::Types::Stash
6
+ property :taxable, :from => :Taxable
7
+ property :rate, :from => :Rate
8
+ property :tax, :from => :Tax
9
+ property :region, :from => :Region
10
+ property :country, :from => :Country
11
+ property :juris_type, :from => :JurisType
12
+ property :juris_name, :from => :JurisName
13
+ property :tax_name, :from => :TaxName
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: UTF-8
2
+
3
+ module Avalara
4
+ module Response
5
+ class TaxLine < Avalara::Types::Stash
6
+ property :line_no, :from => :LineNo
7
+ property :tax_code, :from => :TaxCode
8
+ property :taxability, :from => :Taxability
9
+ property :taxable, :from => :Taxable
10
+ property :rate, :from => :Rate
11
+ property :tax, :from => :Tax
12
+ property :tax_details, :from => :TaxDetails
13
+ property :discount, :from => :Discount
14
+ property :tax_calculated, :from => :TaxCalculated
15
+ property :exemption, :from => :Exemption
16
+
17
+ def TaxDetails=(tax_details)
18
+ self.tax_details = []
19
+ tax_details.each do |tax_detail|
20
+ self.tax_details << TaxDetail.new(tax_detail)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,8 @@
1
+ # encoding: UTF-8
2
+
3
+ module Avalara
4
+ module Types
5
+ autoload :Date, 'avalara/types/date'
6
+ autoload :Stash, 'avalara/types/stash'
7
+ end
8
+ end
@@ -0,0 +1,10 @@
1
+ module Avalara
2
+ module Types
3
+ class Date
4
+ def self.coerce(object)
5
+ return object unless object.respond_to?(:strftime)
6
+ return object.strftime("%Y-%m-%d")
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'hashie/trash'
4
+ require 'hashie/extensions/coercion'
5
+
6
+ module Avalara
7
+ module Types
8
+ ##
9
+ # A Stash is a 'suppressing' Hashie::Trash where keys that are not defined
10
+ # are simply ignored and unavailable to the local object.
11
+ #
12
+ # A Stash is useful when you need to read data from another application,
13
+ # but you only want a predefined subset of the returned data to become
14
+ # available, locally.
15
+ #
16
+ class Stash < ::Hashie::Trash
17
+ include Hashie::Extensions::Coercion
18
+
19
+
20
+ private
21
+
22
+
23
+ def property_exists?(property)
24
+ self.class.property?(property.to_sym)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,5 @@
1
+ # encoding: UTF-8
2
+
3
+ module Avalara
4
+ VERSION = '0.0.1'
5
+ end
@@ -0,0 +1,2 @@
1
+ username: 'testaccount'
2
+ password: 'testkey'
@@ -0,0 +1,13 @@
1
+ Factory.define :address, :class => Avalara::Request::Address do |c|
2
+ c.address_code 1
3
+ c.line_1 "435 Ericksen Avenue Northeast"
4
+ c.line_2 "#250"
5
+ # c.line_3 "line_3"
6
+ # c.city "city"
7
+ # c.region "region"
8
+ # c.country "country"
9
+ c.postal_code "98110"
10
+ # c.latitude "latitude"
11
+ # c.longitude "longitude"
12
+ # c.tax_region_id "tax_region_id"
13
+ end
@@ -0,0 +1,7 @@
1
+ Factory.define :detail_level, :class => Avalara::Request::DetailLevel do |c|
2
+ c.line "line"
3
+ c.summary "summary"
4
+ c.document "document"
5
+ c.tax "tax"
6
+ c.diagnostic "diagnostic"
7
+ end
@@ -0,0 +1,17 @@
1
+ Factory.define :invoice, :class => Avalara::Request::Invoice do |c|
2
+ c.customer_code 1
3
+ c.doc_date Time.now
4
+ c.company_code 83
5
+ # c.commit "commit"
6
+ # c.customer_usage_type "customer_usage_type"
7
+ # c.discount "discount"
8
+ # c.doc_code "doc_code"
9
+ # c.purchase_order_no "purchase_order_no"
10
+ # c.exemption_no "exemption_no"
11
+ # c.detail_level
12
+ # c.doc_type "doc_type"
13
+ # c.payment_date "payment_date"
14
+ c.lines { [Factory.build_via_new(:line)] }
15
+ c.addresses { [Factory.build_via_new(:address)] }
16
+ # c.reference_code "reference_code"
17
+ end
@@ -0,0 +1,14 @@
1
+ Factory.define :line, :class => Avalara::Request::Line do |c|
2
+ c.line_no "1"
3
+ c.destination_code "1"
4
+ c.origin_code "1"
5
+ # c.item_code "item_code"
6
+ # c.tax_code "tax_code"
7
+ # c.customer_usage_type "customer_usage_type"
8
+ c.qty "1"
9
+ c.amount 10
10
+ # c.discounted "discounted"
11
+ # c.tax_included "tax_included"
12
+ # c.ref_1 "ref_1"
13
+ # c.ref_2 "ref_2"
14
+ end
@@ -0,0 +1,95 @@
1
+ ---
2
+ - !ruby/struct:VCR::HTTPInteraction
3
+ request: !ruby/struct:VCR::Request
4
+ method: :get
5
+ uri: https://%{API_USERNAME}:%{API_PASSWORD}@rest.avalara.net:443/1.0/tax/47.627935,-122.51702/get?saleamount=100
6
+ body:
7
+ headers:
8
+ date:
9
+ - Wed, 01 Feb 2012 16:23:52 GMT
10
+ user-agent:
11
+ - avalara/0.0.1 (Rubygems; Ruby 1.9.2 x86_64-darwin11.0.0)
12
+ content-length:
13
+ - "0"
14
+ response: !ruby/struct:VCR::Response
15
+ status: !ruby/struct:VCR::ResponseStatus
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ cache-control:
20
+ - private
21
+ content-type:
22
+ - text/json; charset=utf-8
23
+ server:
24
+ - Microsoft-IIS/7.5
25
+ x-aspnet-version:
26
+ - 4.0.30319
27
+ x-powered-by:
28
+ - ASP.NET
29
+ date:
30
+ - Wed, 01 Feb 2012 16:23:49 GMT
31
+ content-length:
32
+ - "200"
33
+ body: |
34
+ {
35
+ "Rate": 0,
36
+ "Tax": 0,
37
+ "TaxDetails": [
38
+ {
39
+ "Rate": 0,
40
+ "Tax": 0,
41
+ "Region": "WA",
42
+ "Country": "US",
43
+ "JurisType": "State",
44
+ "JurisName": "WASHINGTON",
45
+ "TaxName": "WA STATE TAX"}
46
+ ]
47
+ ,
48
+ "ResultCode": "Success"}
49
+
50
+ http_version: "1.1"
51
+ - !ruby/struct:VCR::HTTPInteraction
52
+ request: !ruby/struct:VCR::Request
53
+ method: :get
54
+ uri: https://rest.avalara.net:443/1.0/tax/47.627935,-122.51702/get?saleamount=100
55
+ body:
56
+ headers:
57
+ date:
58
+ - Wed, 01 Feb 2012 17:43:34 GMT
59
+ user-agent:
60
+ - avalara/0.0.1 (Rubygems; Ruby 1.9.2 x86_64-darwin11.0.0)
61
+ content-length:
62
+ - "0"
63
+ response: !ruby/struct:VCR::Response
64
+ status: !ruby/struct:VCR::ResponseStatus
65
+ code: 401
66
+ message: Unauthorized
67
+ headers:
68
+ cache-control:
69
+ - private
70
+ content-type:
71
+ - text/json; charset=utf-8
72
+ server:
73
+ - Microsoft-IIS/7.5
74
+ www-authenticate:
75
+ - Basic realm="AvaTax Services"
76
+ x-aspnet-version:
77
+ - 4.0.30319
78
+ x-powered-by:
79
+ - ASP.NET
80
+ date:
81
+ - Wed, 01 Feb 2012 17:43:30 GMT
82
+ content-length:
83
+ - "169"
84
+ body: |
85
+ {
86
+ "ResultCode": "Error",
87
+ "Messages": [
88
+ {
89
+ "Summary": "Required authentication credentials are invalid or missing",
90
+ "Severity": "Error",
91
+ "Source": "Avalara.Web.REST"}
92
+ ]
93
+ }
94
+
95
+ http_version: "1.1"
@@ -0,0 +1,68 @@
1
+ ---
2
+ - !ruby/struct:VCR::HTTPInteraction
3
+ request: !ruby/struct:VCR::Request
4
+ method: :post
5
+ uri: https://%{API_USERNAME}:%{API_PASSWORD}@rest.avalara.net:443/1.0/tax/get
6
+ body: |-
7
+ {
8
+ "CustomerCode": null,
9
+ "DocDate": "2012-02-02",
10
+ "CompanyCode": 83,
11
+ "Lines": [
12
+ {
13
+ "LineNo": "1",
14
+ "DestinationCode": "1",
15
+ "OriginCode": "1",
16
+ "Qty": "1",
17
+ "Amount": 10
18
+ }
19
+ ],
20
+ "Addresses": [
21
+ {
22
+ "AddressCode": 1,
23
+ "Line1": "435 Ericksen Avenue Northeast",
24
+ "Line2": "#250",
25
+ "PostalCode": "98110"
26
+ }
27
+ ]
28
+ }
29
+ headers:
30
+ date:
31
+ - Thu, 02 Feb 2012 16:35:49 GMT
32
+ user-agent:
33
+ - avalara/0.0.1 (Rubygems; Ruby 1.9.2 x86_64-darwin11.0.0)
34
+ content-length:
35
+ - "374"
36
+ response: !ruby/struct:VCR::Response
37
+ status: !ruby/struct:VCR::ResponseStatus
38
+ code: 500
39
+ message: Internal Server Error
40
+ headers:
41
+ cache-control:
42
+ - private
43
+ content-type:
44
+ - text/json; charset=utf-8
45
+ server:
46
+ - Microsoft-IIS/7.5
47
+ x-aspnet-version:
48
+ - 4.0.30319
49
+ x-powered-by:
50
+ - ASP.NET
51
+ date:
52
+ - Thu, 02 Feb 2012 16:35:44 GMT
53
+ content-length:
54
+ - "215"
55
+ body: |
56
+ {
57
+ "ResultCode": "Error",
58
+ "Messages": [
59
+ {
60
+ "Summary": "CustomerCode is required.",
61
+ "Details": "This value must be specified.",
62
+ "RefersTo": "CustomerCode",
63
+ "Severity": "Error",
64
+ "Source": "Avalara.AvaTax.Services"}
65
+ ]
66
+ }
67
+
68
+ http_version: "1.1"