sunnyside 0.1.1 → 0.1.2
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/bin/sunnyside +5 -5
- data/lib/sunnyside.rb +35 -35
- data/lib/sunnyside/advanced.rb +84 -84
- data/lib/sunnyside/cash_receipts/cash_receipt.rb +14 -11
- data/lib/sunnyside/expiring_auth.rb +0 -0
- data/lib/sunnyside/ftp.rb +0 -0
- data/lib/sunnyside/ledger/auth_report.rb +0 -0
- data/lib/sunnyside/ledger/edi.rb +174 -174
- data/lib/sunnyside/ledger/ledger.rb +189 -188
- data/lib/sunnyside/ledger/private.rb +0 -0
- data/lib/sunnyside/menu.rb +52 -52
- data/lib/sunnyside/models/db_setup.rb +196 -196
- data/lib/sunnyside/models/sequel_classes.rb +13 -13
- data/lib/sunnyside/query/query.rb +46 -28
- data/lib/sunnyside/reports/mco_mltc.rb +41 -41
- data/lib/sunnyside/reports/pdf_report.rb +1 -1
- data/lib/sunnyside/reports/pdf_report_draft.rb +0 -0
- data/lib/sunnyside/reports/private.rb +0 -0
- data/lib/sunnyside/reports/report.rb +0 -0
- data/lib/sunnyside/version.rb +3 -3
- metadata +21 -35
@@ -1,189 +1,190 @@
|
|
1
|
-
require 'prawn'
|
2
|
-
module Sunnyside
|
3
|
-
# This should be redone.
|
4
|
-
def self.ledger_file
|
5
|
-
files = Dir["#{DRIVE}/sunnyside-files/summary/*.PDF"]
|
6
|
-
files.each do |file|
|
7
|
-
if Filelib.where(filename: file).count == 0
|
8
|
-
puts "processing #{file}..."
|
9
|
-
ledger = Ledger.new(file)
|
10
|
-
ledger.process_file
|
11
|
-
Filelib.insert(filename: file, purpose: 'summary')
|
12
|
-
FileUtils.mv(file, "#{DRIVE}/sunnyside-files/summary/archive/#{File.basename(file)}")
|
13
|
-
ledger.export_to_csv
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
if files.size == 0
|
18
|
-
puts "It appears there are no new files to process. Do you wish to create a csv file for a specific post date? (Y or N) "
|
19
|
-
if gets.chomp.downcase == 'y'
|
20
|
-
print "enter the date (YYYY-MM-DD): "
|
21
|
-
post_date = Date.parse(gets.chomp)
|
22
|
-
puts "File being created..."
|
23
|
-
LedgerReport.new(post_date)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
class LedgerReport
|
29
|
-
include Sunnyside
|
30
|
-
|
31
|
-
def initialize(post_date)
|
32
|
-
create_report(post_date)
|
33
|
-
end
|
34
|
-
|
35
|
-
def create_report(post_date)
|
36
|
-
Invoice.where(post_date: post_date).all.each { |inv| self.payable_csv(inv, post_date) }
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
class Ledger
|
41
|
-
include Sunnyside
|
42
|
-
attr_reader :post_date, :file, :pages
|
43
|
-
|
44
|
-
# when Ledger gets initialized, the page variable filters out the VNS clients
|
45
|
-
# and then proceeds to pass the page date onto the PageData class
|
46
|
-
|
47
|
-
def initialize(file)
|
48
|
-
@file = File.basename(file)
|
49
|
-
@pages = PDF::Reader.new(file).pages.select { |page| !page.raw_content.include?('VISITING NURSE SERVICE') }
|
50
|
-
end
|
51
|
-
|
52
|
-
def process_file
|
53
|
-
pages.each { |page| PageData.new(page.raw_content, post_date).invoice_data }
|
54
|
-
end
|
55
|
-
|
56
|
-
def post_date
|
57
|
-
Date.parse(file[0..7])
|
58
|
-
end
|
59
|
-
|
60
|
-
def export_to_csv
|
61
|
-
CSV.open("#{DRIVE}/sunnyside-files/new-ledger/#{post_date}-IMPORT-FUND-EZ-LEDGER.csv", "a+") { |row| row << ['Seq','inv','post_date','other id','prov','invoice','header memo','batch','doc date','detail memo','fund','account','cc1','cc2','cc3','debit','credit'] }
|
62
|
-
Invoice.where(post_date: post_date).all.each { |inv| self.payable_csv(inv, post_date) }
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
# in PageData, the providers name is captured from the PDF::Reader raw_content, and the post date from the file name.
|
67
|
-
# the rest of the data (the invoices) gets split by newlines (filted by those lines that fit the criteria for invoice data)
|
68
|
-
# Then, the data gets finalized (via the InvoiceLine child class of PageData) and inserted into the database.
|
69
|
-
|
70
|
-
class PageData
|
71
|
-
attr_reader :page_data, :provider, :post_date, :invoice_data
|
72
|
-
|
73
|
-
def initialize(page_data, post_date)
|
74
|
-
@provider = page_data[/CUSTOMER:\s+(.+)(?=\)')/, 1]
|
75
|
-
@post_date = post_date
|
76
|
-
@page_data = page_data.split(/\n/).select { |line| line =~ /^\([0-9\/]{8}\s/ }
|
77
|
-
end
|
78
|
-
|
79
|
-
# Since the source data is somewhat unreliable in the format, there have been two different variations of AMERIGROUP and ELDERSERVE.
|
80
|
-
# This method accounts for the aberrations while still maintaining that any provider not recognized by the DB to be saved as a PRIVATE client.
|
81
|
-
|
82
|
-
def formatted_provider
|
83
|
-
if provider_missing?
|
84
|
-
case provider
|
85
|
-
when 'ELDERSERVEHEALTH'
|
86
|
-
Provider[5]
|
87
|
-
when 'AMERIGROUP'
|
88
|
-
Provider[1]
|
89
|
-
else
|
90
|
-
Provider[16]
|
91
|
-
end
|
92
|
-
else
|
93
|
-
Provider.where(name: provider).first
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
def provider_missing?
|
98
|
-
Provider.where(name: provider).count == 0
|
99
|
-
end
|
100
|
-
|
101
|
-
def invoice_lines
|
102
|
-
page_data.map { |line|
|
103
|
-
line.gsub!(/^\(|\)'/)
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
@
|
120
|
-
@
|
121
|
-
@
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
#
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
# new
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
#
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
1
|
+
require 'prawn'
|
2
|
+
module Sunnyside
|
3
|
+
# This should be redone.
|
4
|
+
def self.ledger_file
|
5
|
+
files = Dir["#{DRIVE}/sunnyside-files/summary/*.PDF"]
|
6
|
+
files.each do |file|
|
7
|
+
if Filelib.where(filename: file).count == 0
|
8
|
+
puts "processing #{file}..."
|
9
|
+
ledger = Ledger.new(file)
|
10
|
+
ledger.process_file
|
11
|
+
Filelib.insert(filename: file, purpose: 'summary')
|
12
|
+
FileUtils.mv(file, "#{DRIVE}/sunnyside-files/summary/archive/#{File.basename(file)}")
|
13
|
+
ledger.export_to_csv
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
if files.size == 0
|
18
|
+
puts "It appears there are no new files to process. Do you wish to create a csv file for a specific post date? (Y or N) "
|
19
|
+
if gets.chomp.downcase == 'y'
|
20
|
+
print "enter the date (YYYY-MM-DD): "
|
21
|
+
post_date = Date.parse(gets.chomp)
|
22
|
+
puts "File being created..."
|
23
|
+
LedgerReport.new(post_date)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class LedgerReport
|
29
|
+
include Sunnyside
|
30
|
+
|
31
|
+
def initialize(post_date)
|
32
|
+
create_report(post_date)
|
33
|
+
end
|
34
|
+
|
35
|
+
def create_report(post_date)
|
36
|
+
Invoice.where(post_date: post_date).all.each { |inv| self.payable_csv(inv, post_date) }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class Ledger
|
41
|
+
include Sunnyside
|
42
|
+
attr_reader :post_date, :file, :pages
|
43
|
+
|
44
|
+
# when Ledger gets initialized, the page variable filters out the VNS clients
|
45
|
+
# and then proceeds to pass the page date onto the PageData class
|
46
|
+
|
47
|
+
def initialize(file)
|
48
|
+
@file = File.basename(file)
|
49
|
+
@pages = PDF::Reader.new(file).pages.select { |page| !page.raw_content.include?('VISITING NURSE SERVICE') }
|
50
|
+
end
|
51
|
+
|
52
|
+
def process_file
|
53
|
+
pages.each { |page| PageData.new(page.raw_content, post_date).invoice_data }
|
54
|
+
end
|
55
|
+
|
56
|
+
def post_date
|
57
|
+
Date.parse(file[0..7])
|
58
|
+
end
|
59
|
+
|
60
|
+
def export_to_csv
|
61
|
+
CSV.open("#{DRIVE}/sunnyside-files/new-ledger/#{post_date}-IMPORT-FUND-EZ-LEDGER.csv", "a+") { |row| row << ['Seq','inv','post_date','other id','prov','invoice','header memo','batch','doc date','detail memo','fund','account','cc1','cc2','cc3','debit','credit'] }
|
62
|
+
Invoice.where(post_date: post_date).all.each { |inv| self.payable_csv(inv, post_date) }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# in PageData, the providers name is captured from the PDF::Reader raw_content, and the post date from the file name.
|
67
|
+
# the rest of the data (the invoices) gets split by newlines (filted by those lines that fit the criteria for invoice data)
|
68
|
+
# Then, the data gets finalized (via the InvoiceLine child class of PageData) and inserted into the database.
|
69
|
+
|
70
|
+
class PageData
|
71
|
+
attr_reader :page_data, :provider, :post_date, :invoice_data
|
72
|
+
|
73
|
+
def initialize(page_data, post_date)
|
74
|
+
@provider = page_data[/CUSTOMER:\s+(.+)(?=\)')/, 1]
|
75
|
+
@post_date = post_date
|
76
|
+
@page_data = page_data.split(/\n/).select { |line| line =~ /^\([0-9\/]{8}\s/ }
|
77
|
+
end
|
78
|
+
|
79
|
+
# Since the source data is somewhat unreliable in the format, there have been two different variations of AMERIGROUP and ELDERSERVE.
|
80
|
+
# This method accounts for the aberrations while still maintaining that any provider not recognized by the DB to be saved as a PRIVATE client.
|
81
|
+
|
82
|
+
def formatted_provider
|
83
|
+
if provider_missing?
|
84
|
+
case provider
|
85
|
+
when 'ELDERSERVEHEALTH'
|
86
|
+
Provider[5]
|
87
|
+
when 'AMERIGROUP'
|
88
|
+
Provider[1]
|
89
|
+
else
|
90
|
+
Provider[16]
|
91
|
+
end
|
92
|
+
else
|
93
|
+
Provider.where(name: provider).first
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def provider_missing?
|
98
|
+
Provider.where(name: provider).count == 0
|
99
|
+
end
|
100
|
+
|
101
|
+
def invoice_lines
|
102
|
+
page_data.map { |line|
|
103
|
+
line.gsub!(/^\(|\)'/)
|
104
|
+
line.gsub!("\x00", " ")
|
105
|
+
client_name = line.slice!(20..45)
|
106
|
+
line = InvoiceLine.new(line, formatted_provider, post_date, client_name)
|
107
|
+
}
|
108
|
+
end
|
109
|
+
|
110
|
+
def invoice_data
|
111
|
+
invoice_lines.each { |inv| inv.finalize }
|
112
|
+
end
|
113
|
+
|
114
|
+
# InvoiceLine does all the nitty-gritty parsing of an invoice line into the necessary fields the DB requres.
|
115
|
+
|
116
|
+
class InvoiceLine < PageData
|
117
|
+
attr_accessor :invoice, :rate, :hours, :amount, :client_id, :client_name, :post_date, :provider
|
118
|
+
def initialize(line, provider, post_date, client_name)
|
119
|
+
@doc_date, @invoice, @client_id, @hours, @rate, @amount = line.split
|
120
|
+
@post_date = post_date
|
121
|
+
@client_name = client_name.strip
|
122
|
+
@provider = provider
|
123
|
+
end
|
124
|
+
|
125
|
+
# Some invoice totals exceed $999.99, so the strings need to be parsed into a format, sans comma, that the DB will read correctly.
|
126
|
+
# Otherwise, the DB will read 1,203.93 as 1.0.
|
127
|
+
|
128
|
+
def amt
|
129
|
+
amount.gsub(/,|\)'/, '')
|
130
|
+
end
|
131
|
+
|
132
|
+
# Ocasionally, new clients will appear on the PDF doc. If the DB does not find a client with the client_id, then it executes a method wherein
|
133
|
+
# new client gets saved into the DB with a new FUND EZ ID. It must do this before saving the invoice information.
|
134
|
+
|
135
|
+
def finalize
|
136
|
+
if !client_missing?
|
137
|
+
update_client if new_provider?
|
138
|
+
add_invoice
|
139
|
+
else
|
140
|
+
add_client
|
141
|
+
add_invoice
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def client_missing?
|
146
|
+
Client[client_id].nil?
|
147
|
+
end
|
148
|
+
|
149
|
+
def new_provider?
|
150
|
+
Client[client_id].provider_id != provider.id
|
151
|
+
end
|
152
|
+
|
153
|
+
def update_client
|
154
|
+
Client[client_id].update(provider_id: provider.id, prov_type: provider.prov_type)
|
155
|
+
end
|
156
|
+
|
157
|
+
def fund_id
|
158
|
+
print "Enter in the FUND EZ ID for this client: #{client_name} of #{provider.name}: "
|
159
|
+
return gets.chomp
|
160
|
+
end
|
161
|
+
|
162
|
+
def add_client
|
163
|
+
Client.insert(client_number: client_id, client_name: client_name.strip, fund_id: fund_id, provider_id: provider.id, prov_type: provider.prov_type)
|
164
|
+
end
|
165
|
+
|
166
|
+
# rarely there may be an invoice line that contains an invoice number that already exists. This method accounts for it, by merely updating the amount.
|
167
|
+
# There has only been two instances of this happening and both occurred in 2011.
|
168
|
+
|
169
|
+
def add_invoice
|
170
|
+
if invoice_exist?
|
171
|
+
update_invoice
|
172
|
+
else
|
173
|
+
Invoice.insert(invoice_number: invoice, rate: rate, hours: hours, amount: amt, client_id: client_id, post_date: post_date, provider_id: provider.id, client_name: client_name.strip)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def invoice_exist?
|
178
|
+
!Invoice[invoice].nil?
|
179
|
+
end
|
180
|
+
|
181
|
+
def update_invoice
|
182
|
+
Invoice[invoice].update(amount: amt.to_f)
|
183
|
+
end
|
184
|
+
|
185
|
+
def prev_amt
|
186
|
+
Invoice[invoice].amount
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
189
190
|
end
|
File without changes
|
data/lib/sunnyside/menu.rb
CHANGED
@@ -1,53 +1,53 @@
|
|
1
|
-
module Sunnyside
|
2
|
-
class Menu
|
3
|
-
def start
|
4
|
-
loop do
|
5
|
-
puts " 1.) LEDGER IMPORT"
|
6
|
-
puts " 2.) EDI IMPORT"
|
7
|
-
puts " 3.) 837 IMPORT"
|
8
|
-
puts " 4.) A/R REPORT"
|
9
|
-
puts " 5.) CASH RECEIPT IMPORT"
|
10
|
-
puts " 6.) ACCESS FTP"
|
11
|
-
puts " 7.) EXPIRING AUTHORIZATION REPORT"
|
12
|
-
puts " 8.) EXPORT PRIVATE CLIENT PDF'S"
|
13
|
-
puts " 9.) MCO - MLTC HOURS UPDATE"
|
14
|
-
puts "10.) CUSTOM QUERY"
|
15
|
-
puts "11.) ADD A NEW PROVIDER"
|
16
|
-
puts "12.) VIEW DATABASE ON WEB BROWSER"
|
17
|
-
puts "13.) ADD LOGIN CREDENTIALS FOR NEW FTP EDI FILE TRANSFER"
|
18
|
-
print "select option: "
|
19
|
-
case gets.chomp
|
20
|
-
when '1'
|
21
|
-
Sunnyside.ledger_file
|
22
|
-
Sunnyside.process_private
|
23
|
-
when '2'
|
24
|
-
Sunnyside.edi_parser
|
25
|
-
when '3'
|
26
|
-
Sunnyside.parse_pdf
|
27
|
-
when '4'
|
28
|
-
Sunnyside.run_report
|
29
|
-
when '5'
|
30
|
-
Sunnyside.cash_receipt
|
31
|
-
when '6'
|
32
|
-
Sunnyside.access_ftp
|
33
|
-
when '7'
|
34
|
-
Sunnyside.show_opts
|
35
|
-
when '8'
|
36
|
-
Sunnyside.private_clients
|
37
|
-
when '9'
|
38
|
-
Sunnyside.run_mco_mltc
|
39
|
-
when '10'
|
40
|
-
Sunnyside.query
|
41
|
-
when '11'
|
42
|
-
Sunnyside.advanced_opts
|
43
|
-
when '12'
|
44
|
-
Sunnyside.rails_server
|
45
|
-
when '13'
|
46
|
-
Sunnyside.add_provider_to_ftp
|
47
|
-
else
|
48
|
-
exit
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
1
|
+
module Sunnyside
|
2
|
+
class Menu
|
3
|
+
def start
|
4
|
+
loop do
|
5
|
+
puts " 1.) LEDGER IMPORT"
|
6
|
+
puts " 2.) EDI IMPORT"
|
7
|
+
puts " 3.) 837 IMPORT"
|
8
|
+
puts " 4.) A/R REPORT"
|
9
|
+
puts " 5.) CASH RECEIPT IMPORT"
|
10
|
+
puts " 6.) ACCESS FTP"
|
11
|
+
puts " 7.) EXPIRING AUTHORIZATION REPORT"
|
12
|
+
puts " 8.) EXPORT PRIVATE CLIENT PDF'S"
|
13
|
+
puts " 9.) MCO - MLTC HOURS UPDATE"
|
14
|
+
puts "10.) CUSTOM QUERY"
|
15
|
+
puts "11.) ADD A NEW PROVIDER"
|
16
|
+
puts "12.) VIEW DATABASE ON WEB BROWSER"
|
17
|
+
puts "13.) ADD LOGIN CREDENTIALS FOR NEW FTP EDI FILE TRANSFER"
|
18
|
+
print "select option: "
|
19
|
+
case gets.chomp
|
20
|
+
when '1'
|
21
|
+
Sunnyside.ledger_file
|
22
|
+
Sunnyside.process_private
|
23
|
+
when '2'
|
24
|
+
Sunnyside.edi_parser
|
25
|
+
when '3'
|
26
|
+
Sunnyside.parse_pdf
|
27
|
+
when '4'
|
28
|
+
Sunnyside.run_report
|
29
|
+
when '5'
|
30
|
+
Sunnyside.cash_receipt
|
31
|
+
when '6'
|
32
|
+
Sunnyside.access_ftp
|
33
|
+
when '7'
|
34
|
+
Sunnyside.show_opts
|
35
|
+
when '8'
|
36
|
+
Sunnyside.private_clients
|
37
|
+
when '9'
|
38
|
+
Sunnyside.run_mco_mltc
|
39
|
+
when '10'
|
40
|
+
Sunnyside.query
|
41
|
+
when '11'
|
42
|
+
Sunnyside.advanced_opts
|
43
|
+
when '12'
|
44
|
+
Sunnyside.rails_server
|
45
|
+
when '13'
|
46
|
+
Sunnyside.add_provider_to_ftp
|
47
|
+
else
|
48
|
+
exit
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
53
|
end
|