little_finger 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NmI2OTgwMTAwNjFlMzg3NWVkYTI4YmFlOTEyYTMwY2I2NDhjZDk3Mg==
4
+ MmYzZTlkNGNjY2Q4YWQ5ZTM0OTc1NDMzZjJkYzA4YmRiYmY3ZGUxYQ==
5
5
  data.tar.gz: !binary |-
6
- Yzk2MjhiY2FlMDU5ZjA1YjYyNDdmMTI3ZTVmMmZjMGQ1MTFjM2RjZQ==
6
+ OGIwNWI1YmIyZGZkNDY0N2Q5OTJlZWJmZjI0ZTgxODJkNTRmMWVjYg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MjdlNzdlM2JhNTkxY2VkYzQ4NDMzMGM5ODBiMmU2MTgyZWEwZGRlYjQ0NWQy
10
- ZjhmMTViZDFkOWNkYTZiZDhkYWJhOGQ0M2JiMThhMzlmYWViY2RjZTUzOGE4
11
- ZjlmODIwMGI0NjFhYjc2MTYyNGJjMzM3NjhjNzYzNjNiYjVmNmM=
9
+ ZGExYTM4NTUwZmE1NTEzNjUwMmM2NjRmMGQwN2EyYTZlYmFlMjVhODRiNGJj
10
+ NjI2YzNmMDkyYWI3ZmI0MTUzNzYwMThlMzQ3YjU1MGE4NjUyNTNkMzNlZmM2
11
+ NWU1YWI2OWFiMmQ1YTc2NDJhNWUwMzNjNjY2N2FkZTUxNmE5NjY=
12
12
  data.tar.gz: !binary |-
13
- NzExYzQxOTljOGZiNjBlYjNhYTczOWVjYzc4NjNhNTk2NTg2NzU1YWVhYzYw
14
- OWU1MzY1Y2QyMWRiMTZiNTYzY2I4ZmNkODJjYWU5OWUwMDlkYWI0MjAxMGJi
15
- MTJlN2JlMzI1YjBmOWNiMDZjYmJhZjNmNWE1MjUwNTgxZTFlYjQ=
13
+ ZjhkYWFiZjI3MTgyNzIyMWQ3YWM0YWU3NjJlZTkzOWUxYjZlMDBkNTA4MDdl
14
+ ODkyNjUwODQzZWE2ZGUxZDlmNTYyZTA0NzMxMDZjNWJmYTk2NWEzYzI4YmQ4
15
+ ODdlZjcxZTRjMmU5N2NhNmVmNGQwNzg1MzA4NjYyMTIzMjE5Yzg=
data/README.md ADDED
@@ -0,0 +1,45 @@
1
+ little_finger
2
+ ============
3
+ [![Build Status](https://travis-ci.org/honest/little_finger.svg?branch=master)](https://travis-ci.org/honest/little_finger)
4
+ [![Gem Version](https://badge.fury.io/rb/little_finger.svg)](http://badge.fury.io/rb/little_finger)
5
+
6
+ Little Finger is an AvaTax REST API wrapper plus backup tax calculation.
7
+
8
+ Please visit the AvaTax [developer site](http://developer.avalara.com/) for more information on their REST API.
9
+
10
+ Dependencies
11
+ -----------
12
+ TBD
13
+
14
+ Requirements
15
+ ----------
16
+ - Ruby 1.9.3 or later
17
+
18
+ Getting Started
19
+ ----------
20
+ - Add the `little_finger` gem to your Gemfile with `gem 'little_finger'`
21
+ - Run `bundle install` to retrieve `little_finger` and all its dependencies
22
+ - Authentication requires an valid **Account Number** and **License Key**. If you do not have an AvaTax account, a free trial account can be acquired through the [developer site](http://developer.avalara.com/api-get-started)
23
+ - Specify your authentication credentials in the YAML file (see `little_finger.yml.example`) and place it in your config folder
24
+
25
+ Usage
26
+ ----------
27
+ ```
28
+ To get the connection status to AvaTax:
29
+ LittleFinger::Avatax.new.status
30
+
31
+ To get a tax estimate via geographic coordinates:
32
+ LittleFinger::Avatax.new.estimate(coordinates, sale_amount)
33
+
34
+ To validate an address:
35
+ LittleFinger::Avatax.new.validate(address)
36
+
37
+ To get the tax and optionally create or update a transaction in AvaTax:
38
+ LittleFinger::Avatax.new.get(payload)
39
+
40
+ To cancel an existing transaction:
41
+ LittleFinger::Avatax.new.cancel(cancel_code, lookup_opts)
42
+
43
+ Backup: TBD
44
+
45
+ ```
data/lib/little_finger.rb CHANGED
@@ -1,6 +1,14 @@
1
- class LittleFinger
2
- def self.hi
3
- puts 'Hello world'
1
+ require "active_support/all"
2
+ require "awesome_print"
3
+ require "yaml"
4
+ require "hashie"
5
+ require_relative "little_finger/configuration"
6
+
7
+ module LittleFinger
8
+
9
+ def self.yolo
10
+ "#yolo"
4
11
  end
5
-
12
+
6
13
  end
14
+ require_relative "little_finger/avatax"
@@ -0,0 +1,96 @@
1
+ require "json"
2
+ require "base64"
3
+ require "rest-client"
4
+ require_relative "configuration"
5
+
6
+ class LittleFinger::Avatax
7
+ attr_accessor :company_code, :account_number, :license_key, :credentials, :tax_service_url, :address_service_url
8
+
9
+ def initialize()
10
+ @company_code = LittleFinger::Configuration.configuration[:avatax][:company_code]
11
+ @account_number = LittleFinger::Configuration.configuration[:avatax][:account_number]
12
+ @license_key = LittleFinger::Configuration.configuration[:avatax][:license_key]
13
+ @credentials = ["Basic ",Base64.encode64(@account_number + ":"+ @license_key)].join
14
+ @tax_service_url = [LittleFinger::Configuration.configuration[:avatax][:service_url], LittleFinger::Configuration.configuration[:avatax][:tax_service_path]].join
15
+ @address_service_url = [LittleFinger::Configuration.configuration[:avatax][:service_url], LittleFinger::Configuration.configuration[:avatax][:address_service_path]].join
16
+ end
17
+
18
+ # Since the REST API does not provide an explicit ping function, the estimate method can also be used to test connectivity to the service.
19
+ # @return [Fixnum] response code
20
+ def status
21
+ coordinates = { latitude: "34.030291", longitude: "-118.468925"}
22
+ uri = [@tax_service_url,coordinates[:latitude].to_s,",",coordinates[:longitude].to_s,"/get?saleamount=",0].join
23
+ response = send_request(:get, uri)
24
+ response.code
25
+ end
26
+
27
+ # Calculates taxes on a document such as a sales order, sales invoice, purchase order, purchase invoice, or credit memo.
28
+ # http://developer.avalara.com/api-docs/api-reference/rest-curl/gettax
29
+ # @param [Hash] payload
30
+ def get(payload)
31
+ uri = [@tax_service_url,"get"].join
32
+ response = send_request(:post, uri, payload)
33
+ JSON.parse(response.body)
34
+ end
35
+
36
+ # Voids or deletes and existing transaction record from the AvaTax system.
37
+ # http://developer.avalara.com/api-docs/api-reference/rest-curl/canceltax
38
+ # http://developer.avalara.com/api-docs/rest/tax/cancel
39
+ # @param [String] cancel_code The reason for cancelling the tax record: Unspecified, PostFailed, DocDeleted, DocVoided, AdjustmentCancelled
40
+ # @param [Hash] lookup_opts options to identify Avatax transactions by DocId or by the set of values CompanyCode, DocCode, and DocType.
41
+ # @option lookup_opts [String] DocId Avatax-assigned unique Document Id
42
+ # @option lookup_opts [String] CompanyCode Client application company reference code
43
+ # @option lookup_opts [String] DocCode Client application identifier describing this tax transaction (i.e. invoice number, sales order number, etc.)
44
+ # @option lookup_opts [String] DocType The reason for cancelling the tax record.
45
+ # @return [Hash] JSON parsed response body
46
+ def cancel(cancel_code, lookup_opts = {})
47
+ payload = lookup_opts.merge({CancelCode: cancel_code})
48
+ uri = [@tax_service_url, "cancel"].join
49
+ response = send_request(:post, uri, payload)
50
+ JSON.parse(response.body).try(:[],"CancelTaxResult")
51
+ end
52
+
53
+ # Retrieves tax rate details for the supplied geographic coordinates and sale amount.
54
+ # http://developer.avalara.com/api-docs/api-reference/rest-curl/estimatetax
55
+ # @param [Hash] coordinates geographic coordinates
56
+ # @option coordinates [String] latitude
57
+ # @option coordinates [String] longitude
58
+ # @param [Float] sale_amount
59
+ # @return [Hash] JSON parsed response body
60
+ def estimate(coordinates, sale_amount = 0)
61
+ return unless coordinates.present? && coordinates.has_key?(:latitude) && coordinates.has_key?(:longitude)
62
+ uri = [@tax_service_url,coordinates[:latitude].to_s,",",coordinates[:longitude].to_s,"/get?saleamount=",sale_amount.to_s].join
63
+ response = send_request(:get, uri)
64
+ JSON.parse(response.body)
65
+ end
66
+
67
+ # Normalizes a single US or Canadian address, providing a non-ambiguous address match.
68
+ # http://developer.avalara.com/api-docs/api-reference/rest-curl/validate
69
+ # @param [Hash] address physical shipping address to validate
70
+ # @option address [String] :Line1
71
+ # @option address [String] :Line2
72
+ # @option address [String] :Line3
73
+ # @option address [String] :City
74
+ # @option address [String] :Region
75
+ # @option address [String] :PostalCode
76
+ # @option address [String] :Country
77
+ # @return [Hash] JSON parsed response body
78
+ def validate(address)
79
+ uri = [@address_service_url, "validate?", address.to_query].join
80
+ response = send_request(:get, uri)
81
+ JSON.parse(response.body)
82
+ end
83
+
84
+ private
85
+
86
+ # Forms and sends the request
87
+ # @param [Symbol] method request method
88
+ # @param [String] uri Avatax service endpoint
89
+ # @param optional [Hash] payload
90
+ # @param optional [Hash] custom_headers
91
+ def send_request(method, uri, payload = {}, custom_headers = {})
92
+ headers = {authorization: @credentials, content_type: "application/json"}.merge(custom_headers)
93
+ RestClient::Request.execute(method: method.to_sym, url: uri, payload: JSON.generate(payload), headers: headers){|response, request, result| response }
94
+ end
95
+
96
+ end
@@ -0,0 +1,31 @@
1
+ module LittleFinger
2
+ module Configuration
3
+ @@conf = nil
4
+
5
+ def self.configure_with(environment_name, yaml_file = nil)
6
+ @@yaml_file = yaml_file.nil? ? "config/little_finger.yml" : yaml_file
7
+ @@all_conf = Hashie::Mash.new(YAML.load_file(@@yaml_file) )
8
+ @@conf = @@all_conf[environment_name]
9
+ self
10
+ end
11
+
12
+ def self.configuration
13
+ self.configure_with(self.environment) if @@conf.nil?
14
+ @@conf
15
+ end
16
+
17
+ def self.environment
18
+ val = ENV["RAILS_ENV"] || ENV["RACK_ENV"]
19
+ val = if val.present?
20
+ val.to_sym
21
+ else
22
+ if defined?(Rails)
23
+ Rails.env
24
+ else
25
+ raise "No environment can be found for configuration!"
26
+ end
27
+ end
28
+ end
29
+
30
+ end
31
+ end
data/spec/config.yml ADDED
@@ -0,0 +1,8 @@
1
+ test:
2
+ enabled: true
3
+ avatax:
4
+ account_number: "1234567890"
5
+ license_key: "A1B2C3D4E5F6G7H8"
6
+ service_url: "https://development.avalara.net"
7
+ tax_service_path: "/1.0/tax/"
8
+ address_service_path: "/1.0/address/"
@@ -0,0 +1,10 @@
1
+ require "spec_helper"
2
+
3
+ describe LittleFinger do
4
+
5
+ describe "#yolo" do
6
+ subject { LittleFinger.yolo }
7
+
8
+ it { expect(subject).to eq("#yolo") }
9
+ end
10
+ end
@@ -0,0 +1,29 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+
8
+ require "little_finger"
9
+ ENV["RAILS_ENV"] ||= "test"
10
+ require "timecop"
11
+ require "factory_girl"
12
+ require_relative "support/helpers/avatax_helper"
13
+
14
+ FactoryGirl.definition_file_paths = [File.expand_path("../factories", __FILE__)]
15
+ FactoryGirl.find_definitions
16
+
17
+ RSpec.configure do |config|
18
+ config.treat_symbols_as_metadata_keys_with_true_values = true
19
+ config.run_all_when_everything_filtered = true
20
+ config.filter_run :focus
21
+
22
+ # Run specs in random order to surface order dependencies. If you find an
23
+ # order dependency and want to debug it, you can fix the order by providing
24
+ # the seed, which is printed after each run.
25
+ # --seed 1234
26
+ config.order = "random"
27
+ end
28
+
29
+ LittleFinger::Configuration.configure_with("test", File.expand_path("../config.yml", __FILE__))
@@ -0,0 +1,24 @@
1
+ module AvataxHelper
2
+
3
+ def error_messages(messages)
4
+ messages.map{|m| m["Summary"] }
5
+ end
6
+
7
+ def simple_calculation(tax_lines)
8
+ # given no tax amount overrides
9
+ tax_sum = 0
10
+ tax_lines.each do |line|
11
+ tax_sum += line["Taxable"].to_f * line["Rate"].to_f
12
+ end
13
+ tax_sum.round(2)
14
+ end
15
+
16
+ def sum_taxes(tax_lines)
17
+ tax_sum = 0
18
+ tax_lines.each do |line|
19
+ tax_sum += line["Tax"].to_f
20
+ end
21
+ tax_sum.round(2)
22
+ end
23
+
24
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: little_finger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michelle Yung
@@ -9,14 +9,161 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 2014-12-04 00:00:00.000000000 Z
12
- dependencies: []
13
- description: Avatax REST API wrapper plus backup tax calculation
14
- email: michelle@thehonestcompany.com
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 3.0.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 3.0.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: activesupport
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '3.2'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '3.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: awesome_print
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: 1.2.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: 1.2.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: airbrake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '3.1'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '3.1'
97
+ - !ruby/object:Gem::Dependency
98
+ name: hashie
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '1.2'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '1.2'
111
+ - !ruby/object:Gem::Dependency
112
+ name: json
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '1.8'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ! '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '1.8'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rest-client
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ~>
130
+ - !ruby/object:Gem::Version
131
+ version: 1.6.7
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ~>
137
+ - !ruby/object:Gem::Version
138
+ version: 1.6.7
139
+ - !ruby/object:Gem::Dependency
140
+ name: yard
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ! '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ! '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ description: AvaTax REST API wrapper plus backup tax calculation
154
+ email: michelle@honest.com
15
155
  executables: []
16
156
  extensions: []
17
157
  extra_rdoc_files: []
18
158
  files:
159
+ - README.md
19
160
  - lib/little_finger.rb
161
+ - lib/little_finger/avatax.rb
162
+ - lib/little_finger/configuration.rb
163
+ - spec/config.yml
164
+ - spec/little_finger_spec.rb
165
+ - spec/spec_helper.rb
166
+ - spec/support/helpers/avatax_helper.rb
20
167
  homepage: https://github.com/honest/little_finger
21
168
  licenses:
22
169
  - MIT
@@ -40,6 +187,6 @@ rubyforge_project:
40
187
  rubygems_version: 2.2.2
41
188
  signing_key:
42
189
  specification_version: 4
43
- summary: Avatax with backup tax calculation
190
+ summary: AvaTax with backup tax calculation
44
191
  test_files: []
45
192
  has_rdoc: