Count hand-valued assets into the wealth figure

A wealth figure that ignores the house is not a wealth figure. Assets
without a market feed - a house, a car, a private loan - are now added
by hand on the Wealth page with a stated value, a currency and the day
the estimate was made; a negative value records a liability. They are
registry entities in assets.finance like everything else, join the
per-currency totals immediately, and a currency held only in an asset
earns its own line.
This commit is contained in:
Lars Nolden
2026-09-14 09:29:19 +02:00
parent a1480af74d
commit 77f4ea5655
15 changed files with 564 additions and 29 deletions
+28
View File
@@ -104,6 +104,25 @@ func SaveInstrument(d *domain.Dataset, v domain.Instrument) error {
d.Instruments = append(d.Instruments, v)
return nil
}
// SaveAsset registers or revalues a hand-valued possession. The value and the
// day it was stated travel together; full validation happens at commit.
func SaveAsset(d *domain.Dataset, v domain.Asset) error {
v.Name = strings.TrimSpace(v.Name)
v.Kind = strings.TrimSpace(v.Kind)
v.Currency = strings.ToUpper(strings.TrimSpace(v.Currency))
if v.ID == "" {
v.ID = domain.NewID("asset")
}
for i, x := range d.Assets {
if x.ID == v.ID {
d.Assets[i] = v
return nil
}
}
d.Assets = append(d.Assets, v)
return nil
}
func SaveCategory(d *domain.Dataset, v domain.Category) error {
v.Name = strings.TrimSpace(v.Name)
if v.ID == "" {
@@ -203,6 +222,15 @@ func Manage(d *domain.Dataset, entity, action, id, target string) error {
if n == len(d.Instruments) {
return errors.New("unknown instrument")
}
case "asset":
if action != "delete" {
return errors.New("asset merging is not supported")
}
n := len(d.Assets)
d.Assets = slices.DeleteFunc(d.Assets, func(v domain.Asset) bool { return v.ID == id })
if n == len(d.Assets) {
return errors.New("unknown asset")
}
case "tag":
if !slices.ContainsFunc(d.Tags, func(v domain.Tag) bool { return v.ID == id }) {
return errors.New("unknown tag")