Added an Account#path method to get the path of an account, from root to literal...
[fin.git] / ledger.rb
blob5db70c441e578aece73d8dfb790f227b534aaabc
1 require 'tabdelimited'
3 ################################################################################
4 # A collection of transactions.
5 ################################################################################
6 class Ledger
7   
8   # Initializes a _Transactions_ object.
9   def initialize(filename)
10     @filename = filename
11     @transactions = []
12     @account_register = AccountRegister.new
13     sync :write => false
14   end
16   # Synchronizes the the data store with the data store source.
17   def sync(options = {})
18     options = { :read => true, :write => true }.merge options
19     import if options[:read]
20     export if options[:write]
21   end
23   def length
24     @transactions.length
25   end
27   alias size length
29   def each
30     @transactions.each { |transaction| yield(transaction) }
31   end
33   # Add one or more transactions to the ledger.
34   def add(*transactions)
35     transactions.each do |transaction|
36       transaction.from.balance -= transaction.amount
37       transaction.to.balance += transaction.amount
38     end
39     @transactions.push(*transactions)
40   end
42   # Accumulate transactions corresponding to a given predicate block.
43   def accumulate
44     register = AccountRegister.new # fresh register with 0 balances
45     @transactions.each do |transaction|
46       next unless yield(transaction)
47       from = register.open(*transaction.from.path)
48       from.balance -= transaction.amount
49       to = register.open(*transaction.to.path)
50       to.balance += transaction.amount
51     end
52     register.accounts
53   end
55   # Get a collection of the accounts defined.
56   def accounts
57     @account_register.accounts
58   end
60   private
61   include TabDelimited
62 end