little_finger 0.0.4 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/lib/little_finger.rb +2 -0
- data/lib/little_finger/parsers/tax_sales_file.rb +30 -0
- data/lib/little_finger/server_file.rb +59 -0
- data/spec/config.yml +40 -5
- data/spec/spec_helper.rb +5 -0
- metadata +23 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NzNmOTQyN2E2NGNlODIyNDc5OGVhM2UwMGY3ZWE2ODU3NWMxYWZhNA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MGJhNTI5NTYyZjQ3ZTcyNjI3MWM2ZDg4ZmY1YjhkZjRmNmI2ZTJjMQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
OGIzMTRhYTRkZDk3NzA0YTMzNTc2N2Y5Mjc0YjkxMWJlYWZkOWQ5NWI1MDIw
|
10
|
+
MGVkNzVjNDQxNDcxZDM4MjM1M2FkMjA2MzIzYzhiY2Q0MjY3MzMyMGVmNGFk
|
11
|
+
MTE5YmFhODA4NWIxNjM1NTU2ZTQyMzNkYTYwZjc3NWQwODQxN2Q=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YTU2MzI2YTA2YzM5MjE2ZjAyZDRmZjljMjg4NDM5ZDhhNjE5OGZhYjllNjk4
|
14
|
+
NzMwOGFkM2JkZDE1MTc4Y2JlMTdkM2YwMmVkODQyOThiMjE4MTdiMjYyZDMz
|
15
|
+
MWQ4ZGQ3MDIzYzEyZjk0NGJjZGI2ZjFkODNmMjY3ZWRiZmI0ZTE=
|
data/lib/little_finger.rb
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
module LittleFinger
|
2
|
+
module Parsers
|
3
|
+
class TaxSalesFile
|
4
|
+
STATE_IDX = 0
|
5
|
+
STATE_NAME_IDX = 1
|
6
|
+
CITY_IDX = 2
|
7
|
+
COMBINED_RATE_IDX = 86
|
8
|
+
EFFECTIVE_DATE_IDX = 87
|
9
|
+
ZIP_CODE_IDX = 89
|
10
|
+
def parse(tax_file)
|
11
|
+
tax_data = {}
|
12
|
+
File.open(tax_file,"r").each_line do |line|
|
13
|
+
data = line.split(",")
|
14
|
+
zip_code = data[ZIP_CODE_IDX]
|
15
|
+
effective_date = data[EFFECTIVE_DATE_IDX]
|
16
|
+
rate = data[COMBINED_RATE_IDX]
|
17
|
+
state = data[STATE_IDX]
|
18
|
+
city = data[CITY_IDX]
|
19
|
+
description = "#{city}, #{state}"
|
20
|
+
|
21
|
+
entry = [zip_code,effective_date, rate, description, state, city]
|
22
|
+
raise StandardError.new("Avatax file format is incorrect: #{entry}") if entry.any?{|elem| elem.nil?}
|
23
|
+
key = (zip_code + city).strip
|
24
|
+
tax_data[key] = { zip: zip_code, city: city, state: state, tax_rate: BigDecimal.new(rate), effective_at: DateTime.strptime(effective_date, "%Y/%m/%d") }
|
25
|
+
end
|
26
|
+
tax_data
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'zip'
|
2
|
+
class LittleFinger::ServerFile
|
3
|
+
attr_reader :username
|
4
|
+
attr_reader :password
|
5
|
+
attr_reader :host
|
6
|
+
attr_reader :folder_name
|
7
|
+
attr_reader :ftp_site
|
8
|
+
|
9
|
+
def self.fetch
|
10
|
+
settings = LittleFinger::Configuration.configuration[:avatax][:ftp]
|
11
|
+
obj = LittleFinger::ServerFile.new(settings[:username], settings[:password], settings[:ftp_site])
|
12
|
+
obj.fetch
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(username, password, ftp_site)
|
16
|
+
@username = username
|
17
|
+
@password = password
|
18
|
+
@ftp_site = ftp_site
|
19
|
+
portions = @ftp_site.split("/", 2)
|
20
|
+
@host = portions[0]
|
21
|
+
@folder_name = ""
|
22
|
+
@folder_name = portions[1] if portions.count > 1
|
23
|
+
@ftp_iface = nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def fetch()
|
27
|
+
connect
|
28
|
+
filename = retrieve_file
|
29
|
+
# unzipped_files = unzip(filename)
|
30
|
+
# parse(unzipped_files.first)
|
31
|
+
unzip(filename)
|
32
|
+
end
|
33
|
+
|
34
|
+
def connect
|
35
|
+
@ftp_iface = ftp = Net::FTP.new(@host)
|
36
|
+
# This HAS to be done when we are connecting to the Windows FTP server for some reason.
|
37
|
+
@ftp_iface.passive = true
|
38
|
+
@ftp_iface.login(@username, @password)
|
39
|
+
@ftp_iface.chdir(@folder_name) if @folder_name.present?
|
40
|
+
end
|
41
|
+
|
42
|
+
def retrieve_file(filename)
|
43
|
+
out_file ="/tmp/#{filename}"
|
44
|
+
@ftp_iface.getbinaryfile(filename, out_file)
|
45
|
+
out_file
|
46
|
+
end
|
47
|
+
|
48
|
+
def unzip(zip_file)
|
49
|
+
file_names = []
|
50
|
+
zip_obj = Zip::File.open(zip_file)
|
51
|
+
zip_obj.each do |one_file|
|
52
|
+
file_name = File.join(File.dirname(zip_file), one_file.name)
|
53
|
+
# force override
|
54
|
+
one_file.extract(file_name) { true }
|
55
|
+
file_names << file_name
|
56
|
+
end
|
57
|
+
file_names
|
58
|
+
end
|
59
|
+
end
|
data/spec/config.yml
CHANGED
@@ -1,9 +1,44 @@
|
|
1
|
-
|
1
|
+
defaults: &defaults
|
2
2
|
enabled: true
|
3
3
|
avatax:
|
4
|
-
company_code: "
|
5
|
-
account_number: "
|
6
|
-
license_key: "
|
4
|
+
company_code: "ABC"
|
5
|
+
account_number: "1234567890"
|
6
|
+
license_key: "A1B2C3D4E5F6G7H8"
|
7
7
|
service_url: "https://development.avalara.net"
|
8
8
|
tax_service_path: "/1.0/tax/"
|
9
|
-
address_service_path: "/1.0/address/"
|
9
|
+
address_service_path: "/1.0/address/"
|
10
|
+
ftp:
|
11
|
+
username: 'user'
|
12
|
+
password: 'password'
|
13
|
+
ftp_site: 'ftp.taxrates.com/your_directory'
|
14
|
+
|
15
|
+
|
16
|
+
development:
|
17
|
+
<<: *defaults
|
18
|
+
|
19
|
+
profile:
|
20
|
+
<<: *defaults
|
21
|
+
|
22
|
+
test:
|
23
|
+
<<: *defaults
|
24
|
+
|
25
|
+
qa:
|
26
|
+
<<: *defaults
|
27
|
+
|
28
|
+
staging:
|
29
|
+
<<: *defaults
|
30
|
+
|
31
|
+
production:
|
32
|
+
<<: *defaults
|
33
|
+
enabled: false
|
34
|
+
avatax:
|
35
|
+
company_code: "ABC"
|
36
|
+
account_number: "1234567890"
|
37
|
+
license_key: "A1B2C3D4E5F6G7H8"
|
38
|
+
service_url: "https://avatax.avalara.net"
|
39
|
+
tax_service_path: "/1.0/tax/"
|
40
|
+
address_service_path: "/1.0/address/"
|
41
|
+
ftp:
|
42
|
+
username: 'user'
|
43
|
+
password: 'password'
|
44
|
+
ftp_site: 'ftp.taxrates.com/your_directory'
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: little_finger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
+
- The Honest Company
|
7
8
|
- Michelle Yung
|
9
|
+
- Thanh Lim
|
8
10
|
autorequire:
|
9
11
|
bindir: bin
|
10
12
|
cert_chain: []
|
@@ -122,6 +124,20 @@ dependencies:
|
|
122
124
|
- - ! '>='
|
123
125
|
- !ruby/object:Gem::Version
|
124
126
|
version: '3.2'
|
127
|
+
- !ruby/object:Gem::Dependency
|
128
|
+
name: rubyzip
|
129
|
+
requirement: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - ~>
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '1.1'
|
134
|
+
type: :runtime
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ~>
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '1.1'
|
125
141
|
- !ruby/object:Gem::Dependency
|
126
142
|
name: awesome_print
|
127
143
|
requirement: !ruby/object:Gem::Requirement
|
@@ -207,7 +223,10 @@ dependencies:
|
|
207
223
|
- !ruby/object:Gem::Version
|
208
224
|
version: '0'
|
209
225
|
description: AvaTax REST API wrapper plus backup tax calculation
|
210
|
-
email:
|
226
|
+
email:
|
227
|
+
- webadmin@honest.com
|
228
|
+
- michelle@honest.com
|
229
|
+
- thanh@honest.com
|
211
230
|
executables: []
|
212
231
|
extensions: []
|
213
232
|
extra_rdoc_files: []
|
@@ -218,6 +237,8 @@ files:
|
|
218
237
|
- lib/little_finger.rb
|
219
238
|
- lib/little_finger/avatax.rb
|
220
239
|
- lib/little_finger/configuration.rb
|
240
|
+
- lib/little_finger/parsers/tax_sales_file.rb
|
241
|
+
- lib/little_finger/server_file.rb
|
221
242
|
- spec/config.yml
|
222
243
|
- spec/config.yml.example
|
223
244
|
- spec/little_finger_spec.rb
|