Class: LedgerRest::Ledger::Balance

Inherits:
Object
  • Object
show all
Defined in:
lib/ledger-rest/ledger/balance.rb

Constant Summary collapse

FORMAT =
[
 '{',
 '"totals":[[%(quoted(scrub(display_total)))]],',
 '"name":%(quoted(partial_account)),',
 '"depth":%(depth), "fullname": %(quoted(account))',
 '},%/],',
 '"totals":[[%(quoted(scrub(display_total)))]]'
].join

Class Method Summary collapse

Class Method Details

.expand_accounts(accounts) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/ledger-rest/ledger/balance.rb', line 41

def expand_accounts(accounts)
  accounts.inject([]) do |acc, elem|
    fullname = elem[:fullname].gsub(/:?#{elem[:name]}/, '')
    acc + elem[:name].split(':').map do |name|
      fullname << "#{':' unless fullname.empty?}#{name}"
      parent = elem.dup
      parent[:fullname], parent[:name], parent[:depth] =
        fullname.dup, name.dup, fullname.count(':')+1
      parent
    end
  end
end

.get(query = nil, params = {}) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
# File 'lib/ledger-rest/ledger/balance.rb', line 15

def get(query = nil, params = {})
  data = JSON.parse(json(query, params), symbolize_names: true)

  data[:accounts] = expand_accounts(data[:accounts])

  unless query =~ /--flat/
    data[:accounts] = wrap_accounts(data[:accounts])
  end

  data
end

.json(query = nil, params = {}) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/ledger-rest/ledger/balance.rb', line 27

def json(query = nil, params = {})
  params = { '--format' => FORMAT }.merge(params)
  result = Ledger.exec("bal #{query.gsub('--flat', '')}", params)

  parser = Ledger::Parser.new
  result.gsub! /\[\["(?<amounts>[^"]+)"\]\]/m do |a, b|
    $~[:amounts].split("\n").map do |str|
      amount, commodity = parser.parse_amount_parts(str)
      { amount: amount, commodity: commodity }
    end.to_json
  end
  "{\"accounts\":[#{result.gsub(',]', ']')}}"
end

.wrap_accounts(accounts) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/ledger-rest/ledger/balance.rb', line 54

def wrap_accounts(accounts)
  stack = []
  accounts.inject([]) do |acc, elem|
    stack.pop while stack.last && stack.last[:depth] >= elem[:depth]
    if stack.empty?
      stack << elem
      acc << elem
    else
      (stack.last[:accounts] ||= []) << elem
      stack << elem
    end
    acc
  end
end