ana-ledger/ledger/balances.go

93 lines
1.8 KiB
Go

package ledger
import (
"fmt"
"maps"
"regexp"
"strings"
)
type Balances map[string]Balance
type Balance map[Currency]float64
func (balances Balances) Like(pattern string) Balances {
result := make(Balances)
p := regexp.MustCompile(pattern)
for k, v := range balances {
if p.MatchString(k) {
result[k] = maps.Clone(v)
}
}
return result
}
func (balances Balances) WithBPIs(bpis BPIs) Balances {
return balances.WithBPIsAt(bpis, "9")
}
func (balances Balances) WithBPIsAt(bpis BPIs, date string) Balances {
result := make(Balances)
for k, v := range balances {
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)
}
result[k][USD] += v2 * scalar
}
}
return result
}
func (balances Balances) PushAll(other Balances) {
for k, v := range other {
if _, ok := balances[k]; !ok {
balances[k] = make(Balance)
}
for k2, v2 := range v {
if _, ok := balances[k][k2]; !ok {
balances[k][k2] = 0
}
balances[k][k2] += v2
}
}
}
func (balances Balances) Push(d Delta) {
if _, ok := balances[d.Name]; !ok {
balances[d.Name] = make(Balance)
}
balances[d.Name].Push(d)
}
func (balance Balance) Push(d Delta) {
if _, ok := balance[d.Currency]; !ok {
balance[d.Currency] = 0
}
balance[d.Currency] += d.Value
}
func (balances Balances) Debug() string {
result := []string{}
for k, v := range balances {
result = append(result, fmt.Sprintf("%s:[%s]", k, v.Debug()))
}
return strings.Join(result, " ")
}
func (balance Balance) Debug() string {
result := []string{}
for k, v := range balance {
if k == USD {
result = append(result, fmt.Sprintf("%s%.2f", k, v))
} else {
result = append(result, fmt.Sprintf("%.3f %s", v, k))
}
}
return strings.Join(result, " + ")
}