diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/account.cc | 157 | ||||
-rw-r--r-- | src/account.h | 86 | ||||
-rw-r--r-- | src/chain.cc | 6 | ||||
-rw-r--r-- | src/filters.cc | 45 | ||||
-rw-r--r-- | src/filters.h | 29 | ||||
-rw-r--r-- | src/global.cc | 3 | ||||
-rw-r--r-- | src/output.cc | 16 | ||||
-rw-r--r-- | src/post.cc | 41 | ||||
-rw-r--r-- | src/post.h | 41 | ||||
-rw-r--r-- | src/report.cc | 8 | ||||
-rw-r--r-- | src/report.h | 7 | ||||
-rw-r--r-- | src/session.cc | 7 | ||||
-rw-r--r-- | src/textual.cc | 13 | ||||
-rw-r--r-- | src/value.h | 2 | ||||
-rw-r--r-- | src/xact.cc | 16 |
15 files changed, 316 insertions, 161 deletions
diff --git a/src/account.cc b/src/account.cc index 56555d61..b9955120 100644 --- a/src/account.cc +++ b/src/account.cc @@ -30,6 +30,8 @@ */ #include "account.h" +#include "post.h" +#include "xact.h" #include "interactive.h" namespace ledger { @@ -166,33 +168,20 @@ namespace { return string_value(account.name); } - value_t get_total(account_t& account) { - if (! account.xdata_ || account.xdata_->family_details.total.is_null()) - return 0L; - else - return account.xdata_->family_details.total; + value_t get_amount(account_t& account) { + return VALUE_OR_ZERO(account.self_total()); } - value_t get_count(account_t& account) { - if (account.xdata_) - return long(account.xdata_->family_details.posts_count); - else - return 0L; + value_t get_total(account_t& account) { + return VALUE_OR_ZERO(account.family_total()); } value_t get_subcount(account_t& account) { - if (account.xdata_) - return long(account.xdata_->self_details.posts_count); - else - return 0L; + return long(account.self_details().posts_count); } - value_t get_amount(account_t& account) { - if (! account.xdata_ || - account.xdata_->self_details.total.is_null()) - return 0L; - else - return account.xdata_->self_details.total; + value_t get_count(account_t& account) { + return long(account.family_details().posts_count); } value_t get_depth(account_t& account) { @@ -317,4 +306,132 @@ std::size_t account_t::children_with_flags(xdata_t::flags_t flags) const return count; } +account_t::xdata_t::details_t& +account_t::xdata_t::details_t::operator+=(const details_t& other) +{ + // jww (2009-03-05): NYI + return *this; +} + +value_t account_t::self_total(const optional<expr_t&>& expr) const +{ + if (xdata_ && xdata_->has_flags(ACCOUNT_EXT_VISITED)) { + if (! xdata_) xdata_ = xdata_t(); + + posts_deque::const_iterator i = + posts.begin() + xdata_->self_details.last_size; + + for (; i != posts.end(); i++) { + if ((*i)->xdata().has_flags(POST_EXT_VISITED) && + ! (*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_size = posts.size(); + + return xdata_->self_details.total; + } else { + return NULL_VALUE; + } +} + +value_t account_t::family_total(const optional<expr_t&>& expr) const +{ + if (! (xdata_ && xdata_->family_details.calculated)) { + const_cast<account_t&>(*this).xdata().family_details.calculated = true; + + value_t temp; + foreach (const accounts_map::value_type& pair, accounts) { + temp = pair.second->family_total(expr); + if (! temp.is_null()) + add_or_set_value(xdata_->family_details.total, temp); + } + + temp = self_total(expr); + if (! temp.is_null()) + add_or_set_value(xdata_->family_details.total, temp); + } + return xdata_->family_details.total; +} + +const account_t::xdata_t::details_t& +account_t::self_details(bool gather_all) const +{ + if (! (xdata_ && xdata_->self_details.gathered)) { + const_cast<account_t&>(*this).xdata().self_details.gathered = true; + + foreach (const post_t * post, posts) + xdata_->self_details.update(const_cast<post_t&>(*post), gather_all); + } + return xdata_->self_details; +} + +const account_t::xdata_t::details_t& +account_t::family_details(bool gather_all) const +{ + if (! (xdata_ && xdata_->family_details.gathered)) { + const_cast<account_t&>(*this).xdata().family_details.gathered = true; + + foreach (const accounts_map::value_type& pair, accounts) + xdata_->family_details += pair.second->family_details(gather_all); + + xdata_->self_details += self_details(gather_all); + } + return xdata_->family_details; +} + +void account_t::xdata_t::details_t::update(post_t& post, + bool gather_all) +{ + if (last_xact != post.xact) { + xacts_count++; + last_xact = post.xact; + } + if (last_post == &post) + return; + + last_post = &post; + + posts_count++; + if (post.has_flags(POST_VIRTUAL)) + posts_virtuals_count++; + + if (gather_all) + filenames.insert(post.pathname); + + date_t date = post.date(); + + if (date.year() == CURRENT_DATE().year() && + date.month() == CURRENT_DATE().month()) + posts_this_month_count++; + + if ((CURRENT_DATE() - date).days() <= 30) + posts_last_30_count++; + if ((CURRENT_DATE() - date).days() <= 7) + posts_last_7_count++; + + if (! is_valid(earliest_post) || post.date() < earliest_post) + earliest_post = post.date(); + if (! is_valid(latest_post) || post.date() > latest_post) + latest_post = post.date(); + + if (post.state() == item_t::CLEARED) { + posts_cleared_count++; + + if (! is_valid(earliest_cleared_post) || + post.date() < earliest_cleared_post) + earliest_cleared_post = post.date(); + if (! is_valid(latest_cleared_post) || + post.date() > latest_cleared_post) + latest_cleared_post = post.date(); + } + + if (gather_all) { + accounts_referenced.insert(post.account->fullname()); + payees_referenced.insert(post.xact->payee); + } +} + } // namespace ledger diff --git a/src/account.h b/src/account.h index d0516e78..f161a11f 100644 --- a/src/account.h +++ b/src/account.h @@ -50,9 +50,12 @@ namespace ledger { -class account_t; class session_t; +class account_t; +class xact_t; +class post_t; +typedef std::deque<post_t *> posts_deque; typedef std::map<const string, account_t *> accounts_map; /** @@ -68,14 +71,15 @@ class account_t : public scope_t optional<string> note; unsigned short depth; accounts_map accounts; + posts_deque posts; bool known; mutable void * data; mutable string _fullname; - account_t(account_t * _parent = NULL, - const string& _name = "", - const optional<string>& _note = none) + account_t(account_t * _parent = NULL, + const string& _name = "", + const optional<string>& _note = none) : scope_t(), parent(_parent), name(_name), note(_note), depth(static_cast<unsigned short>(parent ? parent->depth + 1 : 0)), known(false), data(NULL) { @@ -112,6 +116,10 @@ class account_t : public scope_t account_t * find_account(const string& name, bool auto_create = true); account_t * find_account_re(const string& regexp); + void add_post(post_t * post) { + posts.push_back(post); + } + virtual expr_t::ptr_op_t lookup(const string& name); bool valid() const; @@ -123,20 +131,68 @@ class account_t : public scope_t #define ACCOUNT_EXT_SORT_CALC 0x01 #define ACCOUNT_EXT_HAS_NON_VIRTUALS 0x02 #define ACCOUNT_EXT_HAS_UNB_VIRTUALS 0x04 -#define ACCOUNT_EXT_VISITED 0x08 -#define ACCOUNT_EXT_MATCHING 0x10 -#define ACCOUNT_EXT_DISPLAYED 0x20 +#define ACCOUNT_EXT_AUTO_VIRTUALIZE 0x08 +#define ACCOUNT_EXT_VISITED 0x10 +#define ACCOUNT_EXT_MATCHING 0x20 +#define ACCOUNT_EXT_DISPLAYED 0x40 struct details_t { - value_t total; + value_t total; + bool calculated; + bool gathered; + + // The following are only calculated if --totals is enabled + std::size_t xacts_count; + + std::size_t posts_count; + std::size_t posts_virtuals_count; + std::size_t posts_cleared_count; + std::size_t posts_last_7_count; + std::size_t posts_last_30_count; + std::size_t posts_this_month_count; + + date_t earliest_post; + date_t earliest_cleared_post; + date_t latest_post; + date_t latest_cleared_post; + + xact_t * last_xact; + post_t * last_post; + + std::size_t last_size; - std::size_t posts_count; - std::size_t posts_virtuals_count; + // The following are only calculated if --gather is enabled + std::set<path> filenames; + std::set<string> accounts_referenced; + std::set<string> payees_referenced; details_t() - : posts_count(0), - posts_virtuals_count(0) {} + : calculated(false), + gathered(false), + + xacts_count(0), + + posts_count(0), + posts_virtuals_count(0), + posts_cleared_count(0), + posts_last_7_count(0), + posts_last_30_count(0), + posts_this_month_count(0), + + earliest_post(0), + earliest_cleared_post(0), + latest_post(0), + latest_cleared_post(0), + + last_xact(NULL), + last_post(NULL), + + last_size(0) {} + + details_t& operator+=(const details_t& other); + + void update(post_t& post, bool gather_all = false); }; details_t self_details; @@ -184,6 +240,12 @@ class account_t : public scope_t return *xdata_; } + value_t self_total(const optional<expr_t&>& expr = none) const; + value_t family_total(const optional<expr_t&>& expr = none) const; + + const xdata_t::details_t& self_details(bool gather_all = true) const; + const xdata_t::details_t& family_details(bool gather_all = true) const; + bool has_flags(xdata_t::flags_t flags) const { return xdata_ && xdata_->has_flags(flags); } diff --git a/src/chain.cc b/src/chain.cc index 9d74f744..e3bf2443 100644 --- a/src/chain.cc +++ b/src/chain.cc @@ -93,11 +93,7 @@ post_handler_ptr chain_post_handlers(report_t& report, // calc_posts computes the running total. When this appears will determine, // for example, whether filtered posts are included or excluded from the // running total. - handler.reset(new calc_posts(handler, expr, report.HANDLED(totals))); - - // unround_posts will unround the amounts in all postings - if (report.HANDLED(unround)) - handler.reset(new unround_posts(handler)); + handler.reset(new calc_posts(handler, expr, only_preliminaries)); // filter_posts will only pass through posts matching the // `secondary_predicate'. diff --git a/src/filters.cc b/src/filters.cc index adf8b33a..f8736667 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -194,43 +194,21 @@ void calc_posts::operator()(post_t& post) if (last_post) { assert(last_post->has_xdata()); - add_or_set_value(xdata.total, last_post->xdata().total); + if (! account_wise) + xdata.total = last_post->xdata().total; xdata.count = last_post->xdata().count + 1; } else { xdata.count = 1; } - value_t amount; - post.add_to_value(amount, amount_expr); + post.add_to_value(xdata.visited_value, amount_expr); + xdata.add_flags(POST_EXT_VISITED); - add_or_set_value(xdata.total, amount); - - if (calc_totals) { - account_t * acct = post.reported_account(); - - account_t::xdata_t * acct_xdata = &acct->xdata(); - - add_or_set_value(acct_xdata->self_details.total, amount); - - acct_xdata->self_details.posts_count++; - acct_xdata->self_details.posts_virtuals_count++; - - acct_xdata->add_flags(ACCOUNT_EXT_VISITED); - - while (true) { - add_or_set_value(acct_xdata->family_details.total, amount); - acct_xdata->family_details.posts_count++; - - if (post.has_flags(POST_VIRTUAL)) - acct_xdata->family_details.posts_virtuals_count++; + account_t * acct = post.reported_account(); + acct->xdata().add_flags(ACCOUNT_EXT_VISITED); - acct = acct->parent; - if (acct) - acct_xdata = &acct->xdata(); - else - break; - } - } + if (! account_wise) + add_or_set_value(xdata.total, xdata.visited_value); item_handler<post_t>::operator()(post); @@ -259,7 +237,8 @@ namespace { // If the account for this post is all virtual, then report the post as // such. This allows subtotal reports to show "(Account)" for accounts // that contain only virtual posts. - if (account && account->has_xdata()) { + if (account && account->has_xdata() && + account->xdata().has_flags(ACCOUNT_EXT_AUTO_VIRTUALIZE)) { if (! account->xdata().has_flags(ACCOUNT_EXT_HAS_NON_VIRTUALS)) { post.add_flags(POST_VIRTUAL); if (! account->xdata().has_flags(ACCOUNT_EXT_HAS_UNB_VIRTUALS)) @@ -286,7 +265,7 @@ namespace { case value_t::BALANCE: case value_t::SEQUENCE: - xdata.value = temp; + xdata.compound_value = temp; xdata.add_flags(POST_EXT_COMPOUND); break; @@ -567,6 +546,8 @@ void subtotal_posts::operator()(post_t& post) // such, so that `handle_value' can show "(Account)" for accounts // that contain only virtual posts. + post.reported_account()->xdata().add_flags(ACCOUNT_EXT_AUTO_VIRTUALIZE); + if (! post.has_flags(POST_VIRTUAL)) post.reported_account()->xdata().add_flags(ACCOUNT_EXT_HAS_NON_VIRTUALS); else if (! post.has_flags(POST_MUST_BALANCE)) diff --git a/src/filters.h b/src/filters.h index 68df6e06..d3968c51 100644 --- a/src/filters.h +++ b/src/filters.h @@ -82,29 +82,6 @@ public: } }; -/** - * @brief Brief - * - * Long. - */ -class unround_posts : public item_handler<post_t> -{ -public: - unround_posts(post_handler_ptr handler) - : item_handler<post_t>(handler) { - TRACE_CTOR(unround_posts, "posts_list&"); - } - virtual ~unround_posts() { - TRACE_DTOR(unround_posts); - } - - virtual void operator()(post_t& post) { - post.xdata().value = post.amount.unrounded(); - post.xdata().add_flags(POST_EXT_COMPOUND); - item_handler<post_t>::operator()(post); - } -}; - class posts_iterator; /** @@ -342,16 +319,16 @@ class calc_posts : public item_handler<post_t> { post_t * last_post; expr_t& amount_expr; - bool calc_totals; + bool account_wise; calc_posts(); public: calc_posts(post_handler_ptr handler, expr_t& _amount_expr, - bool _calc_totals = false) + bool _account_wise = false) : item_handler<post_t>(handler), last_post(NULL), - amount_expr(_amount_expr), calc_totals(_calc_totals) { + amount_expr(_amount_expr), account_wise(_account_wise) { TRACE_CTOR(calc_posts, "post_handler_ptr, expr_t&, bool"); } virtual ~calc_posts() { diff --git a/src/global.cc b/src/global.cc index 0afe16d6..509ceb5e 100644 --- a/src/global.cc +++ b/src/global.cc @@ -413,9 +413,6 @@ void global_scope_t::normalize_report_options(const string& verb) if (verb[0] != 'b' && verb[0] != 'r') rep.HANDLER(base).on_only(); - if (verb[0] == 'b' || verb == "equity") - rep.HANDLER(totals).on_only(); - if (rep.HANDLED(period_) && ! rep.HANDLED(sort_all_)) rep.HANDLER(sort_xacts_).on_only(); diff --git a/src/output.cc b/src/output.cc index f10de042..975d8077 100644 --- a/src/output.cc +++ b/src/output.cc @@ -297,17 +297,11 @@ void format_accounts::flush() } } - if (report.session.master->has_xdata()) { - account_t::xdata_t& xdata(report.session.master->xdata()); - - if (! report.HANDLED(no_total) && top_displayed > 1 && - xdata.family_details.total) { - xdata.self_details.total = xdata.family_details.total; - - bind_scope_t bound_scope(report, *report.session.master); - separator_format.format(out, bound_scope); - total_line_format.format(out, bound_scope); - } + if (! report.HANDLED(no_total) && top_displayed > 1 && + report.session.master->family_total()) { + bind_scope_t bound_scope(report, *report.session.master); + separator_format.format(out, bound_scope); + total_line_format.format(out, bound_scope); } out.flush(); diff --git a/src/post.cc b/src/post.cc index 4289433e..2c303a87 100644 --- a/src/post.cc +++ b/src/post.cc @@ -140,12 +140,10 @@ namespace { } value_t get_amount(post_t& post) { - if (post.has_xdata() && - post.xdata().has_flags(POST_EXT_COMPOUND)) { - return post.xdata().value; - } else { + if (post.has_xdata() && post.xdata().has_flags(POST_EXT_COMPOUND)) + return post.xdata().compound_value; + else return post.amount; - } } value_t get_use_direct_amount(post_t& post) { @@ -169,7 +167,7 @@ namespace { return *post.cost; else if (post.has_xdata() && post.xdata().has_flags(POST_EXT_COMPOUND)) - return post.xdata().value; + return post.xdata().compound_value; else return post.amount; } @@ -233,10 +231,11 @@ namespace { DEBUG("post.account_amount", "Found account: " << account->fullname()); - if (account->xdata().self_details.total.is_null()) + value_t total = account->self_total(); + if (total.is_null()) return 0L; else - return account->xdata().self_details.total.simplified(); + return total.simplified(); } value_t get_account_depth(post_t& post) { @@ -365,13 +364,31 @@ bool post_t::valid() const return true; } -void post_t::add_to_value(value_t& value, expr_t& expr) +void post_t::add_to_value(value_t& value, const optional<expr_t&>& expr) const { if (xdata_ && xdata_->has_flags(POST_EXT_COMPOUND)) { + add_or_set_value(value, xdata_->compound_value); + } + else if (expr) { + bind_scope_t bound_scope(*expr->get_context(), + const_cast<post_t&>(*this)); +#if 1 + value_t temp(expr->calc(bound_scope)); + add_or_set_value(value, temp); +#else + if (! xdata_) xdata_ = xdata_t(); + xdata_->value = expr->calc(bound_scope); + xdata_->add_flags(POST_EXT_COMPOUND); + add_or_set_value(value, xdata_->value); - } else { - bind_scope_t bound_scope(*expr.get_context(), *this); - add_or_set_value(value, expr.calc(bound_scope)); +#endif + } + else if (xdata_ && xdata_->has_flags(POST_EXT_VISITED) && + ! xdata_->visited_value.is_null()) { + add_or_set_value(value, xdata_->visited_value); + } + else { + add_or_set_value(value, amount); } } @@ -53,9 +53,6 @@ namespace ledger { class xact_t; class account_t; -class post_t; -typedef std::list<post_t *> posts_list; - /** * @brief Brief * @@ -126,20 +123,22 @@ public: bool valid() const; - struct xdata_t : public supports_flags<> + struct xdata_t : public supports_flags<uint_least16_t> { -#define POST_EXT_RECEIVED 0x01 -#define POST_EXT_HANDLED 0x02 -#define POST_EXT_TO_DISPLAY 0x04 -#define POST_EXT_DISPLAYED 0x08 -#define POST_EXT_DIRECT_AMT 0x10 -#define POST_EXT_SORT_CALC 0x20 -#define POST_EXT_COMPOUND 0x40 -#define POST_EXT_MATCHES 0x80 - +#define POST_EXT_RECEIVED 0x0001 +#define POST_EXT_HANDLED 0x0002 +#define POST_EXT_DISPLAYED 0x0004 +#define POST_EXT_DIRECT_AMT 0x0008 +#define POST_EXT_SORT_CALC 0x0010 +#define POST_EXT_COMPOUND 0x0020 +#define POST_EXT_VISITED 0x0040 +#define POST_EXT_MATCHES 0x0080 +#define POST_EXT_CONSIDERED 0x0100 + + value_t visited_value; + value_t compound_value; value_t total; std::size_t count; - value_t value; date_t date; account_t * account; void * ptr; @@ -147,14 +146,16 @@ public: std::list<sort_value_t> sort_values; xdata_t() - : supports_flags<>(), count(0), account(NULL), ptr(NULL) { + : supports_flags<uint_least16_t>(), count(0), + account(NULL), ptr(NULL) { TRACE_CTOR(post_t::xdata_t, ""); } xdata_t(const xdata_t& other) - : supports_flags<>(other.flags()), + : supports_flags<uint_least16_t>(other.flags()), + visited_value(other.visited_value), + compound_value(other.compound_value), total(other.total), count(other.count), - value(other.value), date(other.date), account(other.account), ptr(NULL), @@ -184,8 +185,12 @@ public: xdata_ = xdata_t(); return *xdata_; } + const xdata_t& xdata() const { + return const_cast<post_t *>(this)->xdata(); + } - void add_to_value(value_t& value, expr_t& expr); + void add_to_value(value_t& value, + const optional<expr_t&>& expr = none) const; account_t * reported_account() { if (xdata_) diff --git a/src/report.cc b/src/report.cc index 080ba433..e4eef741 100644 --- a/src/report.cc +++ b/src/report.cc @@ -196,6 +196,11 @@ value_t report_t::fn_rounded(call_scope_t& args) return args.value().rounded(); } +value_t report_t::fn_unrounded(call_scope_t& args) +{ + return args.value().unrounded(); +} + value_t report_t::fn_quantity(call_scope_t& scope) { interactive_t args(scope, "a"); @@ -606,7 +611,6 @@ option_t<report_t> * report_t::lookup_option(const char * p) OPT_CH(amount_); else OPT(tail_); else OPT(total_); - else OPT(totals); else OPT(total_data); else OPT(truncate_); else OPT(total_width_); @@ -859,6 +863,8 @@ expr_t::ptr_op_t report_t::lookup(const string& name) case 'u': if (is_eq(p, "underline")) return WRAP_FUNCTOR(fn_underline); + else if (is_eq(p, "unrounded")) + return MAKE_FUNCTOR(report_t::fn_unrounded); break; case 'w': diff --git a/src/report.h b/src/report.h index b39cd53a..a8f048d3 100644 --- a/src/report.h +++ b/src/report.h @@ -145,6 +145,7 @@ public: value_t fn_scrub(call_scope_t& scope); value_t fn_quantity(call_scope_t& scope); value_t fn_rounded(call_scope_t& scope); + value_t fn_unrounded(call_scope_t& scope); value_t fn_truncated(call_scope_t& scope); value_t fn_abs(call_scope_t& scope); value_t fn_justify(call_scope_t& scope); @@ -613,8 +614,6 @@ public: set_expr(args[0].to_string()); }); - OPTION(report_t, totals); - OPTION_(report_t, total_data, DO() { // -J parent->HANDLER(format_).on_with(parent->HANDLER(plot_total_format_).value); }); @@ -641,7 +640,9 @@ public: parent->HANDLER(limit_).on("uncleared|pending"); }); - OPTION(report_t, unround); + OPTION_(report_t, unround, DO() { + parent->HANDLER(amount_).set_expr("unrounded(amount)"); + }); OPTION_(report_t, weekly, DO() { // -W parent->HANDLER(period_).on("weekly"); diff --git a/src/session.cc b/src/session.cc index ff23719b..e171ff4d 100644 --- a/src/session.cc +++ b/src/session.cc @@ -87,9 +87,14 @@ std::size_t session_t::read_journal(std::istream& in, { if (! master) master = journal->master; + std::size_t count = journal->parse(in, *this, master, &pathname, HANDLED(strict)); - clean_accounts(); // remove calculated totals + + // remove calculated totals and flags + clean_posts(); + clean_accounts(); + return count; } diff --git a/src/textual.cc b/src/textual.cc index 1c3bcb02..3652176a 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -1013,25 +1013,24 @@ post_t * instance_t::parse_post(char * line, DEBUG("textual.parse", "line " << linenum << ": " << "POST assign: parsed amt = " << *post->assigned_amount); - account_t::xdata_t& xdata(post->account->xdata()); - amount_t& amt(*post->assigned_amount); + amount_t& amt(*post->assigned_amount); + value_t account_total(post->account->self_total(false)); DEBUG("post.assign", "line " << linenum << ": " - "account balance = " << xdata.self_details.total); + "account balance = " << account_total); DEBUG("post.assign", "line " << linenum << ": " "post amount = " << amt); amount_t diff; - switch (xdata.self_details.total.type()) { + switch (account_total.type()) { case value_t::AMOUNT: - diff = amt - xdata.self_details.total.as_amount(); + diff = amt - account_total.as_amount(); break; case value_t::BALANCE: if (optional<amount_t> comm_bal = - xdata.self_details.total.as_balance() - .commodity_amount(amt.commodity())) + account_total.as_balance().commodity_amount(amt.commodity())) diff = amt - *comm_bal; else diff = amt; diff --git a/src/value.h b/src/value.h index 410ff22a..1e972558 100644 --- a/src/value.h +++ b/src/value.h @@ -930,6 +930,8 @@ inline value_t string_value(const string& str) { return value_t(str, true); } +#define VALUE_OR_ZERO(val) ((val).is_null() ? value_t(0L) : (val)) + inline value_t mask_value(const string& str) { return value_t(mask_t(str)); } diff --git a/src/xact.cc b/src/xact.cc index 8fb1d14c..0ad223a1 100644 --- a/src/xact.cc +++ b/src/xact.cc @@ -306,7 +306,7 @@ bool xact_base_t::finalize() throw_(balance_error, _("Transaction does not balance")); } - // Add the final calculated totals each to their related account + // Add a pointer to each posting to their related accounts if (dynamic_cast<xact_t *>(this)) { bool all_null = true; @@ -314,19 +314,15 @@ bool xact_base_t::finalize() foreach (post_t * post, posts) { if (! post->amount.is_null()) { all_null = false; - post->amount.in_place_reduce(); - - add_or_set_value(post->account->xdata().self_details.total, - post->amount); - - DEBUG("xact.finalize.totals", - "Total for " << post->account->fullname() << " + " - << post->amount << ": " - << post->account->xdata().self_details.total); } else { some_null = true; } + + post->account->add_post(post); + + post->xdata().add_flags(POST_EXT_VISITED); + post->account->xdata().add_flags(ACCOUNT_EXT_VISITED); } if (all_null) return false; // ignore this xact completely |