Class: Reckon::LedgerParser

Inherits:
Object
  • Object
show all
Defined in:
lib/reckon/ledger_parser.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ledger, options = {}) ⇒ LedgerParser

Returns a new instance of LedgerParser.



10
11
12
13
# File 'lib/reckon/ledger_parser.rb', line 10

def initialize(ledger, options = {})
  @entries = []
  parse(ledger)
end

Instance Attribute Details

#entriesObject

Returns the value of attribute entries.



8
9
10
# File 'lib/reckon/ledger_parser.rb', line 8

def entries
  @entries
end

Instance Method Details

#balance(accounts) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/reckon/ledger_parser.rb', line 37

def balance(accounts)
  if accounts.any? { |i| i[:amount].nil? }
    sum = accounts.inject(0) {|m, | m + ([:amount] || 0) }
    count = 0
    accounts.each do ||
      if [:amount].nil?
        count += 1
        [:amount] = 0 - sum
      end
    end
    if count > 1
      puts "Warning: unparsable entry due to more than one missing money value."
      p accounts
      puts
    end
  end

  accounts
end

#clean_money(money) ⇒ Object



57
58
59
60
# File 'lib/reckon/ledger_parser.rb', line 57

def clean_money(money)
  return nil if money.nil? || money.length == 0
  money.gsub(/[\$,]/, '').to_f
end

#parse(ledger) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/reckon/ledger_parser.rb', line 15

def parse(ledger)
  @entries = []
  date = desc = nil
  accounts = []
  ledger.strip.split("\n").each do |entry|
    next if entry =~ /^\s*$/ || entry =~ /^[^ \t\d]/
    if entry =~ /^([\d\/]+)(\=[\d\/]+)?(\s+[\*!]?\s*.*?)$/
      @entries << { :date => date.strip, :desc => desc.strip, :accounts => balance(accounts) } if date
      date = $1
      desc = $3
      accounts = []
    elsif date && entry =~ /^\s+([a-z\s:_\-]+)(\s*$|(\s+[\$\.,\-\d\+]+)($|\s+($|[^\$\.,\-\d\+])))/i
      accounts << { :name => $1.strip, :amount => clean_money($3) }
    else
      @entries << { :date => date.strip, :desc => desc.strip, :accounts => balance(accounts) } if date
      date = desc = nil
      accounts = []
    end
  end
  @entries << { :date => date.strip, :desc => desc.strip, :accounts => balance(accounts) } if date
end