class Banks::BankOfAmerica

Note: If you are running the script for the first time, you need to go online

and validate your computer by answering security questions.

TODO: Ask the user to enter security questions.

Public Instance Methods

get_data(user, password) click to toggle source

Returns all accounts with all transactions. Currently supports Credit and Debit accounts.

# File lib/banks/bofa.rb, line 8
def get_data (user, password)
  # Connect
  browser = ::Watir::Browser.new #:"phantomjs"
  browser.goto 'http://bankofamerica.com'
  browser.text_field(:id => 'onlineId1').set user
  browser.text_field(:id => 'passcode1').set password
  browser.button(:id => 'hp-sign-in-btn').click

  # Wait until logged in.
  # Watir wait did not work on Windows, so we do a hack.
  # http://watirwebdriver.com/waiting/
  # http://stackoverflow.com/questions/3504322/watir-webdriver-wait-for-page-load
  until browser.ul(:class=>"AccountItems").exists? do sleep 1 end

  # Get accounts
  accounts = get_accounts browser.html

  accounts.each do |account|
    browser.goto "https://secure.bankofamerica.com" + account.link
    transactions = nil
    if account.type == Account::DEBIT
      transactions = get_debit_transactions browser.html
    elsif account.type == Account::CREDIT
      transactions = get_credit_transactions browser
    end
    account.transactions = transactions
  end

  # Clean-up
  browser.close

  # Return accounts.
  accounts
end

Protected Instance Methods

get_accounts(html) click to toggle source

Pass the browser and return an array with accounts.

# File lib/banks/bofa.rb, line 58
def get_accounts(html)
  accounts = Array.new
  html_doc = ::Nokogiri::HTML(html)
  html_doc.css('ul.AccountItems li').each do |account_li|
    account = Account.new
    account.name = account_li.css('span.AccountName a').text.strip
    account.link = account_li.css('span.AccountName a')[0]['href']
    account.balance = account_li.css('span.balanceValue').text.strip

    account_type_text = account_li.css('div.AccountItem')[0]['class']
    if account_type_text.include? "AccountItemDeposit"
      account.type = Account::DEBIT
    elsif account_type_text.include? "AccountItemCreditCard"
      account.type = Account::CREDIT
    else
      account.type = Account::UNKNOWN
    end

    accounts << account
  end

  return accounts
end
get_credit_transactions(browser) click to toggle source
# File lib/banks/bofa.rb, line 98
def get_credit_transactions(browser)
  transactions = TransactionArray.new
  html_doc = ::Nokogiri::HTML(browser.html)

  # Navigate through each statement.
  statement_quantity = html_doc.css('select#goto_select_trans_top option').length
  statement_quantity.times do |i|
    browser.select(:id => 'goto_select_trans_top').options[i].select
    html_doc = ::Nokogiri::HTML(browser.html)
    html_doc.css('table#transactions tbody tr').each do |record_tr|
      t = Transaction.new
      t.date = to_date(record_tr.css('td.trans-date-cell').text.strip)
      t.description = record_tr.css('td.trans-desc-cell a.expand-trans-from-desc')[0].children[2].text.strip
      t.amount = convert_money(record_tr.css('td.trans-amount-cell').text.strip)
      t.type = record_tr.css('td.trans-type-cell div')[0]['title']
      transactions << t
    end
  end
  return transactions
end
get_debit_transactions(html) click to toggle source
# File lib/banks/bofa.rb, line 82
def get_debit_transactions(html)
  transactions = TransactionArray.new
  html_doc = ::Nokogiri::HTML(html)

  html_doc.css('table.transaction-records tbody tr.record').each do |record_tr|
    t = Transaction.new
    t.date = to_date(record_tr.css('td.date-action span:not([class])').text.strip)
    t.description = record_tr.css('td.description span.transTitleForEditDesc').text.strip
    t.amount = convert_money(record_tr.css('td.amount').text.strip)
    t.type = record_tr.css('td.type')[0]['title']
    transactions << t
  end

  return transactions
end
to_date(date_string) click to toggle source

Returns date object based on date_string. Today’s date if string is nil or whitespace

# File lib/banks/bofa.rb, line 46
def to_date date_string
  result = nil
  date_string.strip!
  if date_string.nil? || date_string.empty? || date_string.eql?("Pending")
    result = Date.today
  elsif
    result = Date.strptime(date_string, '%m/%d/%Y')
  end
  result
end