summaryrefslogtreecommitdiff
path: root/src/account.cc
diff options
context:
space:
mode:
authorJohn Lee <jjl@pobox.com>2017-10-25 22:17:47 +0100
committerJohn Lee <jjl@pobox.com>2017-10-26 22:35:24 +0100
commitde1b48a013b6f4bdf68f7edf333db63a0994ef20 (patch)
treee031ee8c1a499d8205490e6583d58c876c3118ed /src/account.cc
parentb41454477a0576952f77a20ee32c38eb1b9c1442 (diff)
downloadfork-ledger-de1b48a013b6f4bdf68f7edf333db63a0994ef20.tar.gz
fork-ledger-de1b48a013b6f4bdf68f7edf333db63a0994ef20.tar.bz2
fork-ledger-de1b48a013b6f4bdf68f7edf333db63a0994ef20.zip
Fix bug where .total used in value exprs breaks totals
* Re-initialize (to VOID) totals for the account and its ancestors on adding postings. Otherwise the cache intended for use by recursive calls of C++ function total() in computing family (i.e. account hierarchy) totals is incorrectly retained from one top-level call to the next, causing inconsistent and broken behaviour. * Re-initialize (to false) calculated and gathered. Otherwise we won't e.g. recalculate stale totals for ancestor accounts (e.g. won't recalculate Assets:Savings total if Assets:Savings changes via a posting). Although the value expression total function is used by ledger itself in computing totals, this bug would only appear on use of .total in user-supplied value expressions computed *during parsing* of ledger files, rather than after parsing (I believe ledger only ever calls it for internal purposes after parsing is complete). It is possible this bug also affected other functions than total (perhaps even in circumstances other than analagous to that described in the preceding paragraph). I have not checked that.
Diffstat (limited to 'src/account.cc')
-rw-r--r--src/account.cc13
1 files changed, 13 insertions, 0 deletions
diff --git a/src/account.cc b/src/account.cc
index 14e8b0a9..da8b0b8e 100644
--- a/src/account.cc
+++ b/src/account.cc
@@ -136,6 +136,19 @@ void account_t::add_post(post_t * post)
xdata_->self_details.calculated = false;
xdata_->family_details.gathered = false;
xdata_->family_details.calculated = false;
+ if (! xdata_->family_details.total.is_null()) {
+ xdata_->family_details.total = ledger::value_t();
+ }
+ account_t *ancestor = this;
+ while (ancestor->parent) {
+ ancestor = ancestor->parent;
+ if (ancestor->has_xdata()) {
+ xdata_t &xdata = ancestor->xdata();
+ xdata.family_details.gathered = false;
+ xdata.family_details.calculated = false;
+ xdata.family_details.total = ledger::value_t();
+ }
+ }
}
}