From 3a0879aff0b1ea0037098ae4f602b92719ff9a84 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 2 Nov 2009 01:39:18 -0500 Subject: Added "reported posts" into account xdata This is necessary because sometimes, a post from one account will get reported as though it were in another account (this happens with --budget, to show child account postings within their parent account). In that case, the account needs to remember which postings have been reported as being within it, so that it can add these amounts to its own total in the balance report. --- src/account.cc | 15 +++++++++++++++ src/account.h | 6 ++++-- src/filters.cc | 2 +- src/post.cc | 6 ++++++ src/post.h | 2 ++ test/regress/D060256A.test | 16 ++++++++++++++++ 6 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 test/regress/D060256A.test diff --git a/src/account.cc b/src/account.cc index b14520d3..23761049 100644 --- a/src/account.cc +++ b/src/account.cc @@ -397,6 +397,21 @@ value_t account_t::amount(const optional& expr) const xdata_->self_details.last_post = i; } + if (xdata_->self_details.last_reported_post) + i = *xdata_->self_details.last_reported_post; + else + i = xdata_->reported_posts.begin(); + + for (; i != xdata_->reported_posts.end(); i++) { + if ((*i)->xdata().has_flags(POST_EXT_VISITED)) { + if (! (*i)->xdata().has_flags(POST_EXT_CONSIDERED)) { + (*i)->add_to_value(xdata_->self_details.total, expr); + (*i)->xdata().add_flags(POST_EXT_CONSIDERED); + } + } + xdata_->self_details.last_reported_post = i; + } + return xdata_->self_details.total; } else { return NULL_VALUE; diff --git a/src/account.h b/src/account.h index ce0a7a66..c8f6bdbd 100644 --- a/src/account.h +++ b/src/account.h @@ -159,6 +159,7 @@ public: std::set payees_referenced; optional last_post; + optional last_reported_post; details_t() : calculated(false), @@ -176,8 +177,9 @@ public: void update(post_t& post, bool gather_all = false); }; - details_t self_details; - details_t family_details; + details_t self_details; + details_t family_details; + posts_list reported_posts; std::list sort_values; diff --git a/src/filters.cc b/src/filters.cc index 201fddf1..00e495dd 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -815,7 +815,7 @@ void budget_posts::operator()(post_t& post) post_in_budget = true; // Report the post as if it had occurred in the parent account. if (post.reported_account() != acct) - post.xdata().account = acct; + post.set_reported_account(acct); goto handle; } } diff --git a/src/post.cc b/src/post.cc index 0d6ab8a0..2a1663cb 100644 --- a/src/post.cc +++ b/src/post.cc @@ -436,4 +436,10 @@ void post_t::add_to_value(value_t& value, const optional& expr) const } } +void post_t::set_reported_account(account_t * account) +{ + xdata().account = account; + account->xdata().reported_posts.push_back(this); +} + } // namespace ledger diff --git a/src/post.h b/src/post.h index a89ce3bc..5fdee968 100644 --- a/src/post.h +++ b/src/post.h @@ -193,6 +193,8 @@ public: void add_to_value(value_t& value, const optional& expr = none) const; + void set_reported_account(account_t * account); + account_t * reported_account() { if (xdata_) if (account_t * acct = xdata_->account) diff --git a/test/regress/D060256A.test b/test/regress/D060256A.test new file mode 100644 index 00000000..26c30351 --- /dev/null +++ b/test/regress/D060256A.test @@ -0,0 +1,16 @@ +budget --now=2009/11/01 --end=2009/11/30 +<<< +~ Monthly + Expenses:Food $500.00 + Assets + +2009/11/01 Sample + Expenses:Food:Dining $20.00 + Assets +>>>1 + $-20.00 $-500.00 $480.00 4% Assets + $20.00 $500.00 $-480.00 4% Expenses:Food +------------ ------------ ------------ ----- + 0 0 0 0 +>>>2 +=== 0 -- cgit v1.2.3