diff --git a/src/ledger/balances.go b/src/ledger/balances.go index 5bc213c..a6695b9 100644 --- a/src/ledger/balances.go +++ b/src/ledger/balances.go @@ -4,7 +4,9 @@ import ( "fmt" "maps" "regexp" + "sort" "strings" + "time" ) type Balances map[string]Balance @@ -108,22 +110,57 @@ func (balances Balances) Group(pattern string) Balances { return result } +func (balances Balances) KindaGroup(group Group) Balances { + ks := []string{} + for k := range balances { + ks = append(ks, k) + } + sort.Strings(ks) + + result := make(Balances) + for _, k := range ks { + v := balances[k] + k2 := k + if k3 := group(v.kinda(k)).Name; k2 != k3 { + k2 = k3 + } + + if _, ok := result[k2]; !ok { + result[k2] = make(Balance) + } + + for k3, v3 := range v { + result[k2][k3] += v3 + } + } + return result +} + func (balances Balances) WithBPIs(bpis BPIs) Balances { return balances.WithBPIsAt(bpis, "9") } func (balances Balances) WithBPIsAt(bpis BPIs, date string) Balances { + ks := []string{} + for k := range balances { + ks = append(ks, k) + } + sort.Strings(ks) + result := make(Balances) - for k, v := range balances { + for _, k := range ks { + v := balances[k] if _, ok := result[k]; !ok { result[k] = make(Balance) } for k2, v2 := range v { - scalar := 1.0 - if k2 != USD { - scalar = bpis[k2].Lookup(date) + if k2 == USD { + result[k][USD] = result[k][USD] + v2 + } else if scalar := bpis[k2].Lookup(date); scalar != nil { + result[k][USD] = result[k][USD] + *scalar*v2 + } else { + result[k][k2] = result[k][k2] + v2 } - result[k][USD] += v2 * scalar } } return result diff --git a/src/ledger/bpi.go b/src/ledger/bpi.go index b460ab8..80121ac 100644 --- a/src/ledger/bpi.go +++ b/src/ledger/bpi.go @@ -50,7 +50,7 @@ func NewBPIs(p string) (BPIs, error) { } } -func (bpi BPI) Lookup(date string) float64 { +func (bpi BPI) Lookup(date string) *float64 { var closestWithoutGoingOver string for k := range bpi { if k <= date && k > closestWithoutGoingOver { @@ -58,7 +58,8 @@ func (bpi BPI) Lookup(date string) float64 { } } if closestWithoutGoingOver == "" { - return 0 + return nil } - return bpi[closestWithoutGoingOver] + f := bpi[closestWithoutGoingOver] + return &f } diff --git a/src/ledger/deltas.go b/src/ledger/deltas.go index 6a326e3..d0861a3 100644 --- a/src/ledger/deltas.go +++ b/src/ledger/deltas.go @@ -63,6 +63,5 @@ func (deltas Deltas) Balances() Balances { } } } - return result } diff --git a/src/ledger/file.go b/src/ledger/file.go index 20c083e..95c8182 100644 --- a/src/ledger/file.go +++ b/src/ledger/file.go @@ -7,7 +7,9 @@ import ( "os" "path" "path/filepath" + "slices" "sort" + "strings" "unicode" ) @@ -174,6 +176,12 @@ func (files Files) Deltas(like ...Like) (Deltas, error) { for _, transaction := range transactions { result = append(result, transaction.deltas()...) } + slices.SortFunc(result, func(a, b Delta) int { + if str := strings.Compare(a.Date+a.fileName, b.Date+b.fileName); str != 0 { + return str + } + return a.lineNo - b.lineNo + }) balances := make(Balances) for i := range result {