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:
@@ -171,7 +171,7 @@ func NewDataset() Dataset {
|
||||
return Dataset{Accounts: []Account{}, Categories: []Category{
|
||||
{ID: "cat_expenses", Name: "Expenses", Kind: "expense"}, {ID: ExpenseFallback, Name: "Unclassified", ParentID: "cat_expenses", Kind: "expense"},
|
||||
{ID: "cat_income", Name: "Income", Kind: "income"}, {ID: IncomeFallback, Name: "Unclassified", ParentID: "cat_income", Kind: "income"},
|
||||
}, Tags: []Tag{}, Merchants: []Merchant{}, Instruments: []Instrument{}, Transactions: []Transaction{}}
|
||||
}, Tags: []Tag{}, Merchants: []Merchant{}, Instruments: []Instrument{}, Assets: []Asset{}, Transactions: []Transaction{}}
|
||||
}
|
||||
|
||||
// InstrumentID derives a stable registry ID from an ISIN so re-importing the
|
||||
@@ -181,7 +181,7 @@ func InstrumentID(isin string) string {
|
||||
return "ins_" + hex.EncodeToString(sum[:16])
|
||||
}
|
||||
func Clone(d Dataset) Dataset {
|
||||
c := Dataset{Accounts: append([]Account{}, d.Accounts...), Categories: append([]Category{}, d.Categories...), Tags: append([]Tag{}, d.Tags...), Merchants: append([]Merchant{}, d.Merchants...), Instruments: append([]Instrument{}, d.Instruments...), Transactions: append([]Transaction{}, d.Transactions...)}
|
||||
c := Dataset{Accounts: append([]Account{}, d.Accounts...), Categories: append([]Category{}, d.Categories...), Tags: append([]Tag{}, d.Tags...), Merchants: append([]Merchant{}, d.Merchants...), Instruments: append([]Instrument{}, d.Instruments...), Assets: append([]Asset{}, d.Assets...), Transactions: append([]Transaction{}, d.Transactions...)}
|
||||
for i := range c.Merchants {
|
||||
c.Merchants[i].Aliases = append([]string{}, d.Merchants[i].Aliases...)
|
||||
c.Merchants[i].DefaultTagIDs = append([]string{}, d.Merchants[i].DefaultTagIDs...)
|
||||
@@ -398,6 +398,22 @@ func Validate(d Dataset) error {
|
||||
isins[v.ISIN] = v.ID
|
||||
instruments[v.ID] = v
|
||||
}
|
||||
for _, v := range d.Assets {
|
||||
if err := register(v.ID, "asset"); err != nil {
|
||||
return err
|
||||
}
|
||||
if !nonblank(v.Name) || !currencyPattern.MatchString(v.Currency) || !validText(v.Kind) {
|
||||
return fmt.Errorf("asset %q: valid UTF-8 name and three-letter uppercase currency required", v.ID)
|
||||
}
|
||||
// A hand-stated value without its day cannot be judged stale, so the
|
||||
// two are recorded together, always.
|
||||
if _, err := v.Value.Minor(); err != nil {
|
||||
return fmt.Errorf("asset %q: %w", v.ID, err)
|
||||
}
|
||||
if !validDate(v.ValuedAt) {
|
||||
return fmt.Errorf("asset %q: invalid valuation date %q", v.ID, v.ValuedAt)
|
||||
}
|
||||
}
|
||||
for _, t := range d.Transactions {
|
||||
f := t.Facts
|
||||
if err := register(f.ID, "transaction"); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user