diff --git a/ledger/file.go b/ledger/file.go index cda1ee2..0ff7624 100644 --- a/ledger/file.go +++ b/ledger/file.go @@ -12,6 +12,26 @@ func NewFile(p string) (File, error) { return f, err } +func (file File) Balances(like ...Like) (map[string]map[Currency]float64, error) { + deltas, err := file.Deltas(like...) + if err != nil { + return nil, err + } + + result := make(map[string]map[Currency]float64) + for _, delta := range deltas { + if _, ok := result[delta.Account]; !ok { + result[delta.Account] = make(map[Currency]float64) + } + if _, ok := result[delta.Account][delta.Currency]; !ok { + result[delta.Account][delta.Currency] = 0 + } + result[delta.Account][delta.Currency] += delta.Value + } + + return result, nil +} + func (file File) Deltas(like ...Like) ([]Delta, error) { transactions, err := file.transactions() if err != nil { diff --git a/ledger/file_test.go b/ledger/file_test.go index 59694a1..3bd7d5f 100644 --- a/ledger/file_test.go +++ b/ledger/file_test.go @@ -18,13 +18,36 @@ func TestFileTestdata(t *testing.T) { if err != nil { t.Fatal(err) } - transactions, err := f.Deltas() - if err != nil { - t.Fatal(err) - } - for i := range transactions { - t.Logf("%+v", transactions[i].Debug()) - } + + t.Run("deltas", func(t *testing.T) { + deltas, err := f.Deltas() + if err != nil { + t.Fatal(err) + } + for i := range deltas { + t.Logf("%+v", deltas[i].Debug()) + } + }) + + t.Run("balances", func(t *testing.T) { + balances, err := f.Balances() + if err != nil { + t.Fatal(err) + } + for k, v := range balances { + t.Logf("%s: %+v", k, v) + } + }) + + t.Run("balances like", func(t *testing.T) { + balances, err := f.Balances(LikeAcc(`AssetAccount:Cash:Fidelity76`)) + if err != nil { + t.Fatal(err) + } + for k, v := range balances { + t.Logf("%s: %+v", k, v) + } + }) }) } }