package ledger import ( "fmt" ) type Files []string func NewFiles(p string, q ...string) (Files, error) { f := Files(append([]string{p}, q...)) _, err := f.Deltas() return f, err } func Balances(deltas []Delta) (map[string]map[Currency]float64, error) { 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 (files Files) Deltas(like ...Like) ([]Delta, error) { transactions, err := files.transactions() if err != nil { return nil, err } result := make([]Delta, 0, len(transactions)*2) for _, transaction := range transactions { sums := map[string]float64{} for _, acc := range transaction.recipients { sums[acc.currency] += acc.value delta := newDelta( transaction.date, transaction.description, acc.name, acc.value, acc.currency, ) if likes(like).all(delta) { result = append(result, delta) } } for currency, value := range sums { if value == 0 { continue } if transaction.payee == "" { return nil, fmt.Errorf("didnt find net zero and no dumping ground payee set: %+v", transaction) } delta := newDelta( transaction.date, transaction.description, transaction.payee, -1.0*value, currency, ) if likes(like).all(delta) { result = append(result, delta) } } } return result, nil }