module SpsBill::BillParser
all the bill scanning and parsing intelligence
Constants
- ELECTRICITY_SERVICE_FOOTER
- ELECTRICITY_SERVICE_HEADER
- GAS_SERVICE_FOOTER
- GAS_SERVICE_HEADER
- WATER_SERVICE_FOOTER
- WATER_SERVICE_HEADER
Public Instance Methods
do_complete_parse()
click to toggle source
Command: scans and extracts billing details from the pdf doc
# File lib/sps_bill/bill_parser.rb, line 19 def do_complete_parse return unless reader methods.select{|m| m =~ /^parse_/ }.each do |m| begin send(m) rescue => e errors << "failure parsing #{source_file}:#{m} #{e.inspect}" end end end
errors()
click to toggle source
Returns a collection of parser errors
# File lib/sps_bill/bill_parser.rb, line 14 def errors @errors ||= [] end
parse_account_number()
click to toggle source
Command: extracts the account number
# File lib/sps_bill/bill_parser.rb, line 31 def parse_account_number region = reader.bounding_box do exclusive! below 'Dated' above 'Type' right_of 'Account No' end # text will be returned like this: # [[":", "8123123123"]] @account_number = region.text.flatten.last end
parse_electricity_usage()
click to toggle source
Command: extracts an array of electricity usage charges. Each element is a Hash:
{ kwh: float, rate: float, amount: float }
# File lib/sps_bill/bill_parser.rb, line 89 def parse_electricity_usage region = reader.bounding_box do exclusive! below ELECTRICITY_SERVICE_HEADER above ELECTRICITY_SERVICE_FOOTER right_of 240.0 left_of 450.0 end # text will be returned like this: # [["4 kWh", "0.2410", "0.97"], ["616 kWh", "0.2558", "157.57"]] @electricity_usage = unless (raw_data = region.text).empty? raw_data.map{|l| {:kwh => l[0].gsub(/kwh/i,'').to_f, :rate => l[1].to_f, :amount => l[2].to_f} } end end
parse_gas_usage()
click to toggle source
Command: extracts an array of gas usage charges. Each element is a Hash:
{ kwh: float, rate: float, amount: float }
# File lib/sps_bill/bill_parser.rb, line 106 def parse_gas_usage region = reader.bounding_box do exclusive! below GAS_SERVICE_HEADER above GAS_SERVICE_FOOTER right_of 240.0 left_of 450.0 end # text will be returned like this: # [["4 kWh", "0.2410", "0.97"], ["616 kWh", "0.2558", "157.57"]] @gas_usage = unless (raw_data = region.text).empty? raw_data.map{|l| {:kwh => l[0].gsub(/kwh/i,'').to_f, :rate => l[1].to_f, :amount => l[2].to_f} } end end
parse_invoice_date()
click to toggle source
Command: extracts the invoice date
# File lib/sps_bill/bill_parser.rb, line 58 def parse_invoice_date region = reader.bounding_box do inclusive! below 'Dated' above 'Dated' right_of 'Dated' end # text will be returned like this: # [["Dated", "31", "May", "2011"]] date_string = region.text.flatten.slice(1..3).join('-') @invoice_date = Date.parse(date_string) end
parse_invoice_month()
click to toggle source
Command: extracts the invoice month (as Date, set to 1st of the month)
# File lib/sps_bill/bill_parser.rb, line 72 def parse_invoice_month region = reader.bounding_box do inclusive! below 'Dated' above 'Dated' end # text will be returned like this: # [["May", "11", "Bill", "Dated", "31", "May", "2011"]] date_array = ['01'] + region.text.flatten.slice(0..1) if (yy = date_array[2]).length == 2 date_array[2] = "20#{yy}" # WARNING: converting 2-digit date. Assumed to be 21st C end @invoice_month = Date.parse(date_array.join('-')) end
parse_total_amount()
click to toggle source
Command: extracts the total amount due for the current month
# File lib/sps_bill/bill_parser.rb, line 44 def parse_total_amount region = reader.bounding_box do inclusive! below /^Total Current Charges due on/ above /^Total Current Charges due on/ right_of /^Total Current Charges due on/ left_of 400.0 end # text will be returned like this: # [["Total Current Charges due on 14 Jun 2011 (Tue)", "251.44"]] @total_amount = region.text.flatten.last.to_f end
parse_water_usage()
click to toggle source
Command: extracts an array of water usage charges. Each element is a Hash:
{ cubic_m: float, rate: float, amount: float }
# File lib/sps_bill/bill_parser.rb, line 123 def parse_water_usage region = reader.bounding_box do exclusive! below WATER_SERVICE_HEADER above WATER_SERVICE_FOOTER right_of 240.0 left_of 450.0 end # text will be returned like this: # [["36.1 Cu M", "1.1700", "42.24"], ["-3.0 Cu M", "1.4000", "-4.20"]] @water_usage = unless (raw_data = region.text).empty? raw_data.map{|l| {:cubic_m => l[0].gsub(/cu m/i,'').to_f, :rate => l[1].to_f, :amount => l[2].to_f} } end end