sunnyside 0.0.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.
@@ -0,0 +1,181 @@
1
+ module Sunnyside
2
+ def self.edi_parser
3
+ print "checking for new files...\n"
4
+ Dir["#{LOCAL_FILES}/835/*.txt"].select { |file| Filelib.where(:filename => file).count == 0 }.each do |file|
5
+ print "processing #{file}...\n"
6
+ data = File.open(file).read.split(/~CLP\*/)
7
+ edi = Edi.new(data, file)
8
+ edi.parse_claim_header
9
+ Filelib.insert(filename: file, created_at: Time.now, purpose: 'EDI Import', file_type: '835 Remittance')
10
+ edi.save_payment_to_db
11
+ end
12
+ end
13
+ class Edi
14
+ attr_reader :header, :claims, :file
15
+ def initialize(data, file)
16
+ @header, @claims = data[0], data.drop(1)
17
+ @file = file
18
+ end
19
+
20
+ def process_file
21
+ claims.map { |clm| clm.split(/~(?=SVC)/) }.each do |claim|
22
+ claim_head = claim[0]
23
+ services = claim.select { |section| section =~ /^SVC/ }
24
+ InvoiceHeader.new(claim_head, services).parse_data
25
+ end
26
+ end
27
+
28
+ def check_number
29
+ header[/(?<=~TRN\*\d\*)\w+/, 0]
30
+ end
31
+
32
+ def check_total
33
+ header[/(?<=~BPR\*\w\*)[0-9\.\-]+/] || 0.0
34
+ end
35
+
36
+ def type
37
+ if header[/(?<=\*C\*)ACH/] == 'ACH'
38
+ 'Electronic Funds Transfer'
39
+ elsif header[/(?<=\*C\*)CHK/] == 'CHK'
40
+ 'Physical Check Issued'
41
+ else
42
+ 'Non Payment'
43
+ end
44
+ end
45
+
46
+ # not working
47
+
48
+ # def check
49
+ # if check_number.include?('E') # E for Fidelis
50
+ # check_number[/\d+[A-Z]+(\d+)/, 1]
51
+ # else
52
+ # check_number
53
+ # end
54
+ # end
55
+
56
+ def separate_claims_from_services
57
+ claims.map {|clm| clm.split(/~(?=SVC)/)}
58
+ end
59
+
60
+ def parse_claim_header
61
+ separate_claims_from_services.each do |clm|
62
+ claim_data = clm[0]
63
+ services = clm.reject{|x| x !~ /^SVC/}
64
+ claims = InvoiceHeader.new(claim_data, check_number)
65
+ claims.format_data
66
+ claims.add_to_db(check_number, file)
67
+ parse_service(services) {|svc| claims.parse_svc(svc, check_number)}
68
+ end
69
+ end
70
+
71
+ def save_payment_to_db
72
+ provider = Claim.where(check_number: check_number).get(:provider_id) || 17
73
+ Payment.insert(provider_id: provider, filelib_id: filelib_id, check_total: check_total, check_number: check_number)
74
+ end
75
+
76
+ def filelib_id
77
+ Filelib.where(filename: file).get(:id)
78
+ end
79
+
80
+ def parse_service(services)
81
+ services.map{|x| x.split(/~/).reject{|x| x !~ /CAS|SVC|DTM/}}.each {|svc| yield svc}
82
+ end
83
+ end
84
+
85
+ class InvoiceHeader < Edi
86
+ attr_accessor :claim_number, :invoice_number, :response_code, :amt_charged, :amt_paid, :check_number
87
+ def initialize(claim, check_number)
88
+ @invoice_number, @response_code, @amt_charged, @amt_paid, @whatever, @claim_number = claim.match(/^([\w\.]+)\*(\d+)\*([0-9\.\-]+)\*([0-9\.\-]+)\*([0-9\.\-]+)?\*+\w+\*(\w+)/).captures
89
+ @check_number = check_number
90
+ end
91
+
92
+ def format_data
93
+ @invoice_number = invoice_number[/^\w+/].gsub(/[OLD]/, 'O' => '0', 'D' => '8', 'L' => '1').gsub(/^0/, '')[0..5].to_i
94
+ end
95
+
96
+ def claim_id
97
+ Claim.where(invoice_id: invoice_number, check_number: check_number).get(:id)
98
+ end
99
+
100
+ def parse_svc(service, check_number)
101
+ if service.length == 2
102
+ svc = Detail.new(service[0], service[1])
103
+ elsif service.length > 2
104
+ svc = Detail.new(service[0], service[1])
105
+ svc.set_denial(service[2])
106
+ end
107
+ svc.display(invoice_number)
108
+ svc.save_to_db(invoice_number, check_number, claim_id)
109
+ end
110
+
111
+ def prov
112
+ Invoice.where(invoice_number: invoice_number).get(:provider_id)
113
+ end
114
+
115
+ def add_to_db(check, file)
116
+ Claim.insert(provider_id: prov, invoice_id: invoice_number, billed: amt_charged, paid: amt_paid, check_number: check_number, control_number: claim_number, status: response_code)
117
+ end
118
+ end
119
+
120
+ class Detail < Edi
121
+
122
+ attr_reader :billed, :paid, :denial_reason, :date, :billed, :paid, :units, :service_code
123
+ def initialize(service, date, denial_reason=nil, denial_code=nil)
124
+ @service_code, @billed, @paid, @units = service.match(/HC:([A-Z0-9\:]+)\*([0-9\.\-]+)\*([0-9\.\-]+)?\**([0-9\-]+)?/).captures
125
+ @date = Date.parse(date[/\d+$/])
126
+ end
127
+
128
+ def display(inv)
129
+ print "#{inv} #{@service_code} #{@date} #{client(inv)} #{denial}\n"
130
+ end
131
+
132
+ def client(inv)
133
+ Invoice.where(invoice_number: inv).get(:client_name)
134
+ end
135
+
136
+ def denial
137
+ (billed.to_f - paid.to_f).round(2) if billed > paid
138
+ end
139
+
140
+ def set_denial(denial)
141
+ @denial_reason = set_code(denial[/\d+/])
142
+ end
143
+
144
+ def save_to_db(invoice, check, claim_id)
145
+ Service.insert(invoice_id: invoice, service_code: service_code, units: units.to_f, billed: billed.to_f, paid: paid.to_f, denial_reason: denial_reason, dos: date, claim_id: claim_id)
146
+ end
147
+
148
+ def set_code(code)
149
+ case code
150
+ when '125' then return 'Submission/billing error(s). At least one Remark Code must be provided'
151
+ when '140' then return 'Patient/Insured health identification number and name do not match.'
152
+ when '31' then return 'INVALID MEMBER ID'
153
+ when '62' then return 'PAID AUTHORIZED UNITS'
154
+ when '96' then return 'NO AUTHORIZATION FOR DOS'
155
+ when '146' then return 'DIAGNOSIS WAS INVALID FOR DATES LISTED'
156
+ when '197' then return 'Precertification/authorization/notification absent'
157
+ when '198' then return 'Precertification/authorization exceeded'
158
+ when '199' then return 'Revenue code and Procedure code do not match'
159
+ when '9' then return 'DIAGNOSIS ISSUE'
160
+ when '15' then return 'AUTHORIZATION MISSING/INVALID'
161
+ when '18' then return 'Exact Duplicate Claim/Service'
162
+ when '19' then return 'Expenses incurred prior to coverage'
163
+ when '27' then return 'Expenses incurred after coverage terminated'
164
+ when '29' then return 'Timely Filing'
165
+ when '39' then return 'Services denied at the time authorization/pre-certification was requested'
166
+ when '45' then return 'Charge exceeds fee schedule/maximum allowable'
167
+ when '16' then return 'Claim/service lacks information which is needed for adjudication'
168
+ when '50' then return 'These are non-covered services because this is not deemed a medical necessity by the payer'
169
+ when '192' then return 'Non standard adjustment code from paper remittance'
170
+ when '181' then return 'Procedure code was invalid on the date of service'
171
+ when '182' then return 'Procedure modifier was invalid on the date of service'
172
+ when '204' then return 'This service/equipment/drug is not covered under the patients current benefit plan'
173
+ when '151' then return '151 Payment adjusted because the payer deems the information submitted does not support this many/frequency of services'
174
+ when '177' then return 'Patient has not met the required eligibility requirements'
175
+ when '109' then return 'Claim/service not covered by this payer/contractor. You must send the claim/service to the correct payer/contractor.'
176
+ else
177
+ return "#{code} is UNIDENTIFIED"
178
+ end
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,142 @@
1
+ require 'prawn'
2
+ module Sunnyside
3
+ # This should be redone.
4
+ def self.ledger_file
5
+ Dir["#{LOCAL_FILES}/summary/*.PDF", "#{LOCAL_FILES}/summary/*.pdf"].each {|file|
6
+ if Filelib.where(filename: file).count == 0
7
+ puts "processing #{file}..."
8
+ ledger = Ledger.new(file)
9
+ ledger.process_file
10
+ Filelib.insert(filename: file, purpose: 'summary')
11
+ end
12
+ }
13
+ end
14
+
15
+ class Ledger
16
+ attr_reader :post_date, :file, :pages
17
+
18
+ # when Ledger gets initialized, the page variable filters out the VNS clients
19
+ # and then proceeds to pass the page date onto the PageData class
20
+
21
+ def initialize(file)
22
+ @file = File.basename(file)
23
+ @pages = PDF::Reader.new(file).pages.select { |page| !page.raw_content.include?('VISITING NURSE SERVICE') }
24
+ end
25
+
26
+ def providers
27
+ pages.map { |page| PageData.new(page.raw_content, file) }
28
+ end
29
+
30
+ def process_file
31
+ providers.each { |page| page.invoice_data }
32
+ end
33
+ end
34
+
35
+ # in PageData, the providers name is captured from the PDF::Reader raw_content, and the post date from the file name.
36
+ # the rest of the data (the invoices) gets split by newlines (filted by those lines that fit the criteria for invoice data)
37
+ # Then, the data gets finalized (via the InvoiceLine child class of PageData) and inserted into the database.
38
+
39
+ class PageData
40
+ include Sunnyside
41
+ attr_reader :page_data, :provider, :post_date
42
+
43
+ def initialize(page_data, file, provider = nil)
44
+ @provider = page_data[/CUSTOMER:\s+(.+)(?=\)')/, 1]
45
+ @post_date = Date.parse(file[0..7])
46
+ @page_data = page_data.split(/\n/).select { |line| line =~ /^\([0-9\/]+\s/ }
47
+ end
48
+
49
+ # Since the source data is somewhat unreliable in the format, there have been two different variations of AMERIGROUP and ELDERSERVE.
50
+ # This method accounts for the aberrations while still maintaining that any provider not recognized by the DB to be saved as a PRIVATE client.
51
+
52
+ def formatted_provider
53
+ if provider_missing?
54
+ case provider
55
+ when 'ELDERSERVEHEALTH'
56
+ Provider.where(name: 'ELDERSERVE HEALTH').first
57
+ when 'AMERIGROUP'
58
+ Provider.where(name: 'AMERIGROUP 2').first
59
+ else
60
+ Provider.where(name: 'PRIVATE').first
61
+ end
62
+ else
63
+ Provider.where(name: provider).first
64
+ end
65
+ end
66
+
67
+ def provider_missing?
68
+ Provider.where(name: provider).count == 0
69
+ end
70
+
71
+ def invoice_lines
72
+ page_data.map { |line| InvoiceLine.new(line, formatted_provider, post_date) }
73
+ end
74
+
75
+ def invoice_data
76
+ invoice_lines.each { |inv| inv.finalize }
77
+ # Invoice.where(post_date: post_date).all.each { |inv| self.payable_csv(inv, post_date, formatted_provider) }
78
+ end
79
+
80
+ # InvoiceLine does all the nitty-gritty parsing of an invoice line into the necessary fields the DB requres.
81
+
82
+ class InvoiceLine < PageData
83
+ attr_accessor :invoice, :rate, :hours, :amount, :client_id, :client_name, :post_date, :provider
84
+ def initialize(line, provider, post_date)
85
+ @provider = provider
86
+ @post_date = post_date
87
+ @client_name = line.slice!(20..45)
88
+ @doc_date, @invoice, @client_id, @hours, @rate, @amount = line.split
89
+ end
90
+
91
+ # Some invoice totals exceed $999.99, so the strings need to be parsed into a format, sans comma, that the DB will read correctly.
92
+ # Otherwise, the DB will read 1,203.93 as 1.0.
93
+
94
+ def amt
95
+ amount.gsub(/,/, '')
96
+ end
97
+
98
+ # 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
99
+ # new client gets saved into the DB with a new FUND EZ ID. It must do this before saving the invoice information.
100
+
101
+ def finalize
102
+ if !client_missing?
103
+ add_invoice
104
+ else
105
+ add_client
106
+ finalize
107
+ end
108
+ end
109
+
110
+ def client_missing?
111
+ Client[client_id].nil?
112
+ end
113
+
114
+ def add_client
115
+ Client.insert(client_number: client_id, client_name: client_name)
116
+ end
117
+
118
+ # 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.
119
+ # There has only been two instances of this happening and both occurred in 2011.
120
+
121
+ def add_invoice
122
+ if invoice_exist?
123
+ update_invoice
124
+ else
125
+ 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)
126
+ end
127
+ end
128
+
129
+ def invoice_exist?
130
+ Invoice.where(invoice_number: invoice).count > 0
131
+ end
132
+
133
+ def update_invoice
134
+ Invoice.where(invoice_number: invoice).update(amount: amt.to_f)
135
+ end
136
+
137
+ def prev_amt
138
+ Invoice.where(invoice_number: invoice).get(:amount)
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,70 @@
1
+ module Sunnyside
2
+ def self.process_private
3
+ Dir["#{LOCAL_FILES}/private/*.PDF", "#{LOCAL_FILES}/private/*.pdf"].select { |file| Filelib.where(filename: file).count == 0 }.each do |file|
4
+ puts "processing #{file}..."
5
+ PDF::Reader.new(file).pages.each { |inv|
6
+ page = inv.text.split(/\n/)
7
+ InvoiceParse.new(page).process if page.include?('Remit')
8
+ }
9
+ Filelib.insert(filename: file, purpose: 'private client visit data')
10
+ end
11
+ end
12
+
13
+ class InvoiceParse
14
+ attr_reader :invoice_line, :client_line, :service_lines
15
+ def initialize(page)
16
+ @invoice_line = page.select { |line| line =~ /[0-9\/]{8}\s+\d{7}/ }.join
17
+ @client_line = page.select { |line| line =~ /[0-9]{7}\s+[0-9]{7}/ }.join
18
+ @service_lines = page.map { |line| ServiceLine.new(line) if line =~ /\sHHA\s|\sPCA\s/ }.compact
19
+ end
20
+
21
+ def invoice
22
+ invoice_line[/(\d{7})$/, 1].gsub(/^0/, '')
23
+ end
24
+
25
+ def client_number
26
+ client_line[/[0-9]{7}/, 0]
27
+ end
28
+
29
+ def process
30
+ service_lines.each { |line| line.to_db(invoice, client_number) }
31
+ end
32
+ end
33
+
34
+ class ServiceLine
35
+ attr_reader :line
36
+
37
+ def initialize(line)
38
+ @line = line
39
+ end
40
+
41
+ def to_db(invoice, client_number)
42
+ Visit.insert(invoice_id: invoice, client_id: client_number, dos: Date.strptime(service_date, '%m/%d/%y'), service_code: code, amount: amount)
43
+ end
44
+
45
+ def service_date
46
+ line[/[0-9\/]{8}/, 0]
47
+ end
48
+
49
+ def code
50
+ if line =~ / HHA /
51
+ 'HHA'
52
+ else
53
+ 'PCA'
54
+ end
55
+ end
56
+
57
+ def line_split
58
+ line.split
59
+ end
60
+
61
+ def amount
62
+ line_split[-1]
63
+ end
64
+
65
+ def rate
66
+ line_split[-2]
67
+ end
68
+ end
69
+ end
70
+
@@ -0,0 +1,41 @@
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 "9.) MCO - MLTC HOURS UPDATE"
13
+ print "select option: "
14
+ case gets.chomp
15
+ when '1'
16
+ Sunnyside.ledger_file
17
+ Sunnyside.process_private
18
+ when '2'
19
+ Sunnyside.edi_parser
20
+ when '3'
21
+ Sunnyside.parse_pdf
22
+ when '4'
23
+ Sunnyside::Report.new
24
+ when '5'
25
+ Sunnyside::CashReceipt.new.process
26
+ when '6'
27
+ Sunnyside.access_ftp(:download)
28
+ Sunnyside.access_ftp(:upload)
29
+ when '7'
30
+ Sunnyside.show_opts
31
+ when '8'
32
+ Sunnyside.process_private
33
+ when '9'
34
+ Sunnyside.run_mco_mltc
35
+ else
36
+ exit
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,158 @@
1
+ module Sunnyside
2
+ class << self
3
+ def create_tables
4
+ DB.create_table :charges do
5
+ primary_key :id
6
+ foreign_key :invoice_id, :invoices
7
+ foreign_key :provider_id, :providers
8
+ Date :dos
9
+ Float :amount
10
+ Float :units
11
+ String :service_code
12
+ String :filename
13
+ end
14
+
15
+ DB.create_table :invoices do
16
+ Integer :invoice_number, :primary_key=>true
17
+ index :invoice_number
18
+ Float :amount
19
+ Date :post_date, :default=>Date.today
20
+ foreign_key :client_id, :clients
21
+ foreign_key :provider_id, :providers
22
+ foreign_key :filelib_id, :filelibs
23
+ String :client_name
24
+ Float :rate
25
+ Float :hours
26
+ end
27
+
28
+ DB.create_table :payments do
29
+ primary_key :id
30
+ foreign_key :provider_id, :providers
31
+ foreign_key :filelib_id, :filelibs
32
+ Float :check_total
33
+ String :status
34
+ Integer :check_number
35
+ end
36
+
37
+ DB.create_table :claims do
38
+ primary_key :id
39
+ index :id
40
+ String :control_number
41
+ foreign_key :payment_id, :payments
42
+ foreign_key :invoice_id, :invoices
43
+ foreign_key :client_id, :clients
44
+ Float :paid
45
+ Float :billed
46
+ String :status
47
+ String :recipient_id
48
+ foreign_key :provider_id, :providers
49
+ Date :post_date
50
+ end
51
+
52
+ DB.create_table :services do
53
+ primary_key :id
54
+ foreign_key :claim_id, :claims
55
+ foreign_key :payment_id, :payments
56
+ foreign_key :invoice_id, :invoices
57
+ foreign_key :client_id, :clients
58
+ String :service_code
59
+ Float :paid
60
+ Float :billed
61
+ String :denial_reason
62
+ Float :units
63
+ Date :dos
64
+ end
65
+
66
+ DB.create_table :clients do
67
+ Integer :client_number, :primary_key=>true
68
+ String :client_name
69
+ String :fund_id
70
+ String :recipient_id
71
+ end
72
+
73
+ DB.create_table :providers do
74
+ primary_key :id
75
+ Integer :credit_account
76
+ Integer :fund
77
+ Integer :debit_account
78
+ String :name
79
+ String :abbreviation
80
+ String :type
81
+ String :edi_identifier
82
+ end
83
+
84
+ DB.create_table :filelibs do
85
+ primary_key :id
86
+ String :filename
87
+ String :purpose
88
+ String :file_type
89
+ Time :created_at
90
+ end
91
+
92
+ DB.create_table :visits do
93
+ primary_key :id
94
+ String :service_code
95
+ String :modifier
96
+ foreign_key :invoice_id, :invoices
97
+ foreign_key :client_id, :clients
98
+ Float :amount
99
+ Float :units
100
+ Date :dos
101
+ end
102
+
103
+ DB.create_table :denials do
104
+ primary_key :denial_code, :primary_key=>true
105
+ String :denial_explanation
106
+ end
107
+
108
+ DB[:providers].insert(:credit_account=>1206, :fund=>500, :debit_account=>5005, :name=>"AMERIGROUP 2", :abbreviation=>"AMG", :type=>"MCO")
109
+ DB[:providers].insert(:credit_account=>1207, :fund=>300, :debit_account=>5007, :name=>"CHILDREN'S AID SOCIETY", :abbreviation=>"CAS", :type=>"MLTC")
110
+ DB[:providers].insert(:credit_account=>1226, :fund=>300, :debit_account=>5026, :name=>"COMPREHENSIVE CARE MANAGEMENT", :abbreviation=>"CCM", :type=>"MLTC")
111
+ DB[:providers].insert(:credit_account=>1203, :fund=>300, :debit_account=>5002, :name=>"DOMINICAN SISTERS FAM HLTH", :abbreviation=>"DSF", :type=>"MLTC")
112
+ DB[:providers].insert(:credit_account=>1209, :fund=>300, :debit_account=>5009, :name=>"ELDERSERVE HEALTH", :abbreviation=>"ELD", :type=>"MLTC")
113
+ DB[:providers].insert(:credit_account=>1212, :fund=>300, :debit_account=>5012, :name=>"EMBLEM HEALTH", :abbreviation=>"EMB", :type=>"MLTC")
114
+ DB[:providers].insert(:credit_account=>1201, :fund=>300, :debit_account=>5001, :name=>"GUILDNET", :abbreviation=>"G", :type=>"MLTC")
115
+ DB[:providers].insert(:credit_account=>1227, :fund=>500, :debit_account=>5027, :name=>"HEALTH CARE PARTNERS", :abbreviation=>"HCP", :type=>"MCO")
116
+ DB[:providers].insert(:credit_account=>1218, :fund=>500, :debit_account=>5018, :name=>"HEALTH FIRST", :abbreviation=>"HFS", :type=>"MCO")
117
+ DB[:providers].insert(:credit_account=>1216, :fund=>500, :debit_account=>5016, :name=>"HEALTH INSURANCE PLAN OF NY", :abbreviation=>"HIP", :type=>"MCO")
118
+ DB[:providers].insert(:credit_account=>1223, :fund=>300, :debit_account=>5023, :name=>"HHH LONG TERM HOME HLTH CARE", :abbreviation=>"HHH", :type=>"MLTC")
119
+ DB[:providers].insert(:credit_account=>1228, :fund=>300, :debit_account=>5028, :name=>"INDEPENDENCE CARE SYSTEMS", :abbreviation=>"ICS", :type=>"MLTC")
120
+ DB[:providers].insert(:credit_account=>1217, :fund=>500, :debit_account=>5017, :name=>"METROPLUS HEALTH", :abbreviation=>"MPH", :type=>"MCO")
121
+ DB[:providers].insert(:credit_account=>1219, :fund=>500, :debit_account=>5019, :name=>"NEIGHBORHOOD HEALTH PROVIDERS", :abbreviation=>"NHP", :type=>"MCO")
122
+ DB[:providers].insert(:credit_account=>1221, :fund=>500, :debit_account=>5021, :name=>"NYS CATHOLIC/FIDELIS", :abbreviation=>"FID", :type=>"MCO")
123
+ DB[:providers].insert(:credit_account=>1200, :fund=>300, :debit_account=>5000, :name=>"PRIVATE", :abbreviation=>"P", :type=>"MLTC")
124
+ DB[:providers].insert(:credit_account=>1204, :fund=>300, :debit_account=>5004, :name=>"SENIOR HEALTH PARTNERS", :abbreviation=>"SHP", :type=>"MLTC")
125
+ DB[:providers].insert(:credit_account=>1202, :fund=>300, :debit_account=>5003, :name=>"SUNNYSIDE COMMUNITY SERVICES", :abbreviation=>"SCS", :type=>"MLTC")
126
+ DB[:providers].insert(:credit_account=>1213, :fund=>500, :debit_account=>5013, :name=>"UNITED HEALTH CARE", :abbreviation=>"UHC", :type=>"MCO")
127
+ DB[:providers].insert(:credit_account=>1229, :fund=>500, :debit_account=>5029, :name=>"VNSNY CHOICE SELECT HEALTH", :abbreviation=>"VCS", :type=>"MCO")
128
+ DB[:providers].insert(:credit_account=>1224, :fund=>500, :debit_account=>5024, :name=>"WELCARE OF NEW YORK, INC.", :abbreviation=>"WEL", :type=>"MCO")
129
+ DB[:providers].insert(:credit_account=>1310, :fund=>300, :debit_account=>5030, :name=>"VILLAGE CARE MAX", :abbreviation=>"VIL", :type=>"MLTC")
130
+ DB[:providers].insert(:credit_account=>1222, :fund=>500, :debit_account=>5022, :name=>"AFFINITY HEALTH PLUS", :abbreviation=>"AFF", :type=>"MCO")
131
+ DB[:providers].insert(:credit_account=>1218, :fund=>500, :debit_account=>5018, :name=>"HEALTH PLUS PHSP,INC", :abbreviation=>"HFS", :type=>"MCO")
132
+
133
+ end
134
+ end
135
+ end
136
+
137
+ # DB[:denials].insert(denial_code: 1, denial_explanation: 'not implemented yet')
138
+ # DB[:denials].insert(denial_code: 96, denial_explanation: "NO AUTHORIZATION FOR DOS")
139
+ # DB[:denials].insert(denial_code: 197, denial_explanation: "Precertification/authorization/notification absent")
140
+ # DB[:denials].insert(denial_code: 198, denial_explanation: "Precertification/authorization exceeded")
141
+ # DB[:denials].insert(denial_code: 199, denial_explanation: "Revenue code and Procedure code do not match")
142
+ # DB[:denials].insert(denial_code: 9, denial_explanation: "DIAGNOSIS ISSUE")
143
+ # DB[:denials].insert(denial_code: 15, denial_explanation: "AUTHORIZATION MISSING/INVALID")
144
+ # DB[:denials].insert (denial_code: 18, denial_explanation: "Exact Duplicate Claim/Service")
145
+ # DB[:denials].insert(denial_code: 19, denial_explanation: "Expenses incurred prior to coverage")
146
+ # DB[:denials].insert(denial_code: 27, denial_explanation: "Expenses incurred after coverage terminated")
147
+ # DB[:denials].insert(denial_code: 29, denial_explanation: "Timely Filing")
148
+ # DB[:denials].insert(denial_code: 39, denial_explanation: "Services denied at the time authorization/pre-certification was requested")
149
+ # DB[:denials].insert(denial_code: 45, denial_explanation: "Charge exceeds fee schedule/maximum allowable")
150
+ # DB[:denials].insert(denial_code: 16, denial_explanation: "Claim/service lacks information which is needed for adjudication")
151
+ # DB[:denials].insert(denial_code: 50, denial_explanation: "These are non-covered services because this is not deemed a 'medical necessity' by the payer")
152
+ # DB[:denials].insert(denial_code: 192, denial_explanation: "Non standard adjustment code from paper remittance")
153
+ # DB[:denials].insert(denial_code: 181, denial_explanation: "Procedure code was invalid on the date of service")
154
+ # DB[:denials].insert(denial_code: 182, denial_explanation: "Procedure modifier was invalid on the date of service")
155
+ # DB[:denials].insert(denial_code: 204, denial_explanation: "This service/equipment/drug is not covered under the patients current benefit plan")
156
+ # DB[:denials].insert(denial_code: 151, denial_explanation: "151 Payment adjusted because the payer deems the information submitted does not support this many/frequency of services")
157
+ # DB[:denials].insert(denial_code: 177, denial_explanation: "Patient has not met the required eligibility requirements")
158
+ # DB[:denials].insert(denial_code: 109, denial_explanation: "Claim/service not covered by this payer/contractor. You must send the claim/service to the correct payer/contractor.")
@@ -0,0 +1,12 @@
1
+ module Sunnyside
2
+ class Auth < Sequel::Model; end
3
+ class Charge < Sequel::Model; end
4
+ class Invoice < Sequel::Model; end
5
+ class Filelib < Sequel::Model; end
6
+ class Payment < Sequel::Model; end
7
+ class Claim < Sequel::Model; end
8
+ class Client < Sequel::Model; end
9
+ class Service < Sequel::Model; end
10
+ class Provider < Sequel::Model; end
11
+ class Visit < Sequel::Model; end
12
+ end
@@ -0,0 +1,43 @@
1
+ module Sunnyside
2
+ def self.run_mco_mltc
3
+ print "Type in post date (YYYY-MM-DD): "
4
+ post_date = gets.chomp
5
+ Provider.map(:name).each do |provider|
6
+ ReportMCO.new(provider, post_date).run
7
+ end
8
+ end
9
+
10
+ class ReportMCO
11
+ attr_reader :provider, :post_date, :clients
12
+ # attr_accessor :mco_total, :mltc_total
13
+
14
+ def initialize(provider, post_date)
15
+ @provider = provider
16
+ @post_date = post_date
17
+ @clients = Client.where(provider: provider)
18
+ # @mco_total = 0.0
19
+ # @mltc_total = 0.0
20
+ end
21
+
22
+ def run
23
+ mco_total = 0.0
24
+ mltc_total = 0.0
25
+ invoices.each do |inv|
26
+ if inv[:type] == 'MCO'
27
+ mco_total += inv[:hours]
28
+ # mco_total += inv.hours
29
+ elsif inv[:type] == 'MLTC'
30
+ mltc_total += inv[:hours]
31
+ end
32
+ end
33
+ puts "#{provider}: MCO => #{mco_total} MLTC => #{mltc_total}"
34
+ end
35
+
36
+ def invoices
37
+ Invoice.where(provider: provider, post_date: post_date).all.map { |invoice|
38
+ { :type => Client.where(med_id: invoice.service_number).exclude(type: nil).get(:type),
39
+ :hours => invoice.hours }
40
+ }
41
+ end
42
+ end
43
+ end