diff options
author | John Wiegley <johnw@newartisans.com> | 2010-06-09 01:23:38 -0400 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2010-06-09 02:22:50 -0400 |
commit | fc09b69fb765dc934be10d0544b1366f86f21ee2 (patch) | |
tree | 755313686184c4f538c27f12c474266f61d22148 /src | |
parent | 524c98244ec19e6a0368deb1e05c69955bcf2e34 (diff) | |
download | fork-ledger-fc09b69fb765dc934be10d0544b1366f86f21ee2.tar.gz fork-ledger-fc09b69fb765dc934be10d0544b1366f86f21ee2.tar.bz2 fork-ledger-fc09b69fb765dc934be10d0544b1366f86f21ee2.zip |
Fixed interaction with -V/X and grouped postings
With -s, -M/Y/D, -n, and a few other flags, postings get "grouped" into
meta-transactions that contain more postings than before. In all these
cases, -V use the date of the *earliest* posting in that group, which
makes little sense and caused breakages with -J. It now uses the latest
date.
Fixes #197 / 68EAF363-D0FE-4127-866E-A5AEBACB65D6
Diffstat (limited to 'src')
-rw-r--r-- | src/filters.cc | 118 | ||||
-rw-r--r-- | src/item.cc | 5 | ||||
-rw-r--r-- | src/post.cc | 17 | ||||
-rw-r--r-- | src/post.h | 2 | ||||
-rw-r--r-- | src/report.cc | 5 | ||||
-rw-r--r-- | src/report.h | 12 |
6 files changed, 103 insertions, 56 deletions
diff --git a/src/filters.cc b/src/filters.cc index e7109f95..ebe70181 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -289,18 +289,16 @@ void calc_posts::operator()(post_t& post) } namespace { - typedef function<void (post_t&)> post_functor_t; - - void handle_value(const value_t& value, - account_t * account, - xact_t * xact, - temporaries_t& temps, - post_handler_ptr handler, - const date_t& date = date_t(), - const value_t& total = value_t(), - const bool direct_amount = false, - const bool mark_visited = false, - const optional<post_functor_t>& functor = none) + void handle_value(const value_t& value, + account_t * account, + xact_t * xact, + temporaries_t& temps, + post_handler_ptr handler, + const date_t& date = date_t(), + const bool act_date_p = true, + const value_t& total = value_t(), + const bool direct_amount = false, + const bool mark_visited = false) { post_t& post = temps.create_post(*xact, account); post.add_flags(ITEM_GENERATED); @@ -319,8 +317,12 @@ namespace { post_t::xdata_t& xdata(post.xdata()); - if (is_valid(date)) - xdata.date = date; + if (is_valid(date)) { + if (act_date_p) + xdata.date = date; + else + xdata.value_date = date; + } value_t temp(value); @@ -353,9 +355,6 @@ namespace { if (direct_amount) xdata.add_flags(POST_EXT_DIRECT_AMT); - if (functor) - (*functor)(post); - DEBUG("filters.changed_value.rounding", "post.amount = " << post.amount); (*handler)(post); @@ -388,12 +387,15 @@ void collapse_posts::report_subtotal() } else { date_t earliest_date; + date_t latest_date; foreach (post_t * post, component_posts) { - date_t reported = post->date(); - if (! is_valid(earliest_date) || - reported < earliest_date) - earliest_date = reported; + date_t date = post->date(); + date_t value_date = post->value_date(); + if (! is_valid(earliest_date) || date < earliest_date) + earliest_date = date; + if (! is_valid(latest_date) || value_date > latest_date) + latest_date = value_date; } xact_t& xact = temps.create_xact(); @@ -401,12 +403,16 @@ void collapse_posts::report_subtotal() xact._date = (is_valid(earliest_date) ? earliest_date : last_xact->_date); DEBUG("filters.collapse", "Pseudo-xact date = " << *xact._date); - - handle_value(/* value= */ subtotal, - /* account= */ &totals_account, - /* xact= */ &xact, - /* temps= */ temps, - /* handler= */ handler); + DEBUG("filters.collapse", "earliest date = " << earliest_date); + DEBUG("filters.collapse", "latest date = " << latest_date); + + handle_value(/* value= */ subtotal, + /* account= */ &totals_account, + /* xact= */ &xact, + /* temps= */ temps, + /* handler= */ handler, + /* date= */ latest_date, + /* act_date_p= */ false); } component_posts.clear(); @@ -526,6 +532,7 @@ bool display_filter_posts::output_rounding(post_t& post) /* temps= */ temps, /* handler= */ handler, /* date= */ *xact._date, + /* act_date_p= */ true, /* total= */ precise_display_total, /* direct_amount= */ true); } @@ -627,7 +634,7 @@ void changed_value_posts::output_revaluation(post_t& post, const date_t& date) xact_t& xact = temps.create_xact(); xact.payee = _("Commodities revalued"); - xact._date = is_valid(date) ? date : post.date(); + xact._date = is_valid(date) ? date : post.value_date(); if (! for_accounts_report) { handle_value @@ -637,6 +644,7 @@ void changed_value_posts::output_revaluation(post_t& post, const date_t& date) /* temps= */ temps, /* handler= */ handler, /* date= */ *xact._date, + /* act_date_p= */ true, /* total= */ repriced_total); } else if (show_unrealized) { @@ -649,6 +657,7 @@ void changed_value_posts::output_revaluation(post_t& post, const date_t& date) /* temps= */ temps, /* handler= */ handler, /* date= */ *xact._date, + /* act_date_p= */ true, /* total= */ value_t(), /* direct_amount= */ false, /* mark_visited= */ true); @@ -672,7 +681,7 @@ void changed_value_posts::output_intermediate_prices(post_t& post, xact_t& xact(temps.create_xact()); xact.payee = _("Commodities revalued"); - xact._date = is_valid(current) ? current : post.date(); + xact._date = is_valid(current) ? current : post.value_date(); post_t& temp(temps.copy_post(post, xact)); temp.add_flags(ITEM_GENERATED); @@ -734,9 +743,9 @@ void changed_value_posts::output_intermediate_prices(post_t& post, hist->histories) { foreach (const commodity_t::history_map::value_type& price, comm_hist.second.prices) { - if (price.first.date() > post.date() && + if (price.first.date() > post.value_date() && price.first.date() < current) { - DEBUG("filters.revalued", post.date() << " < " + DEBUG("filters.revalued", post.value_date() << " < " << price.first.date() << " < " << current); DEBUG("filters.revalued", "inserting " << price.second << " at " << price.first.date()); @@ -778,8 +787,8 @@ void changed_value_posts::operator()(post_t& post) { if (last_post) { if (! for_accounts_report) - output_intermediate_prices(*last_post, post.date()); - output_revaluation(*last_post, post.date()); + output_intermediate_prices(*last_post, post.value_date()); + output_revaluation(*last_post, post.value_date()); } if (changed_values_only) @@ -803,11 +812,12 @@ void subtotal_posts::report_subtotal(const char * spec_fmt, if (! range_start || ! range_finish) { foreach (post_t * post, component_posts) { - date_t date = post->date(); + date_t date = post->date(); + date_t value_date = post->value_date(); if (! range_start || date < *range_start) range_start = date; - if (! range_finish || date > *range_finish) - range_finish = date; + if (! range_finish || value_date > *range_finish) + range_finish = value_date; } } component_posts.clear(); @@ -829,11 +839,13 @@ void subtotal_posts::report_subtotal(const char * spec_fmt, xact._date = *range_start; foreach (values_map::value_type& pair, values) - handle_value(/* value= */ pair.second.value, - /* account= */ pair.second.account, - /* xact= */ &xact, - /* temps= */ temps, - /* handler= */ handler); + handle_value(/* value= */ pair.second.value, + /* account= */ pair.second.account, + /* xact= */ &xact, + /* temps= */ temps, + /* handler= */ handler, + /* date= */ *range_finish, + /* act_date_p= */ false); values.clear(); } @@ -942,17 +954,21 @@ void posts_as_equity::report_subtotal() if (pair.second.value.is_balance()) { foreach (const balance_t::amounts_map::value_type& amount_pair, pair.second.value.as_balance().amounts) - handle_value(/* value= */ amount_pair.second, - /* account= */ pair.second.account, - /* xact= */ &xact, - /* temps= */ temps, - /* handler= */ handler); + handle_value(/* value= */ amount_pair.second, + /* account= */ pair.second.account, + /* xact= */ &xact, + /* temps= */ temps, + /* handler= */ handler, + /* date= */ finish, + /* act_date_p= */ false); } else { - handle_value(/* value= */ pair.second.value, - /* account= */ pair.second.account, - /* xact= */ &xact, - /* temps= */ temps, - /* handler= */ handler); + handle_value(/* value= */ pair.second.value, + /* account= */ pair.second.account, + /* xact= */ &xact, + /* temps= */ temps, + /* handler= */ handler, + /* date= */ finish, + /* act_date_p= */ false); } total += pair.second.value; } diff --git a/src/item.cc b/src/item.cc index fea73066..6a948ae4 100644 --- a/src/item.cc +++ b/src/item.cc @@ -465,6 +465,11 @@ expr_t::ptr_op_t item_t::lookup(const symbol_t::kind_t kind, return WRAP_FUNCTOR(get_wrapper<&get_uncleared>); break; + case 'v': + if (name == "value_date") + return WRAP_FUNCTOR(get_wrapper<&get_date>); + break; + case 'L': if (name[1] == '\0') return WRAP_FUNCTOR(get_wrapper<&get_actual>); diff --git a/src/post.cc b/src/post.cc index 7dc15830..e182a731 100644 --- a/src/post.cc +++ b/src/post.cc @@ -78,6 +78,13 @@ optional<string> post_t::get_tag(const mask_t& tag_mask, return none; } +date_t post_t::value_date() const +{ + if (xdata_ && is_valid(xdata_->value_date)) + return xdata_->value_date; + return date(); +} + date_t post_t::date() const { if (xdata_ && is_valid(xdata_->date)) @@ -319,6 +326,14 @@ namespace { return long(post.reported_account()->depth); } + value_t get_value_date(post_t& post) { + if (post.has_xdata()) { + post_t::xdata_t& xdata(post.xdata()); + if (! xdata.value_date.is_not_a_date()) + return xdata.value_date; + } + return post.date(); + } value_t get_datetime(post_t& post) { return post.xdata().datetime; } @@ -479,6 +494,8 @@ expr_t::ptr_op_t post_t::lookup(const symbol_t::kind_t kind, case 'v': if (name == "virtual") return WRAP_FUNCTOR(get_wrapper<&get_virtual>); + else if (name == "value_date") + return WRAP_FUNCTOR(get_wrapper<&get_value_date>); break; case 'x': @@ -106,6 +106,7 @@ public: virtual optional<string> get_tag(const mask_t& tag_mask, const optional<mask_t>& value_mask = none) const; + virtual date_t value_date() const; virtual date_t date() const; virtual date_t actual_date() const; virtual optional<date_t> effective_date() const; @@ -141,6 +142,7 @@ public: value_t total; std::size_t count; date_t date; + date_t value_date; datetime_t datetime; account_t * account; diff --git a/src/report.cc b/src/report.cc index 680205fa..662db746 100644 --- a/src/report.cc +++ b/src/report.cc @@ -1308,6 +1308,11 @@ expr_t::ptr_op_t report_t::lookup(const symbol_t::kind_t kind, return MAKE_FUNCTOR(report_t::fn_unrounded); break; + case 'v': + if (is_eq(p, "value_date")) + return MAKE_FUNCTOR(report_t::fn_now); + break; + case 'w': if (is_eq(p, "white")) return WRAP_FUNCTOR(fn_white); diff --git a/src/report.h b/src/report.h index e4eaeaaa..f8fdf507 100644 --- a/src/report.h +++ b/src/report.h @@ -586,16 +586,16 @@ public: "use_direct_amount ? amount :" " (is_seq(get_at(amount_expr, 0)) ?" " get_at(get_at(amount_expr, 0), 0) :" - " market(get_at(amount_expr, 0), date, exchange)" + " market(get_at(amount_expr, 0), value_date, exchange)" " - get_at(amount_expr, 1))"); parent->HANDLER(revalued_total_) .set_expr(string("--gain"), - "(market(get_at(total_expr, 0), date, exchange), " + "(market(get_at(total_expr, 0), value_date, exchange), " "get_at(total_expr, 1))"); parent->HANDLER(display_total_) .set_expr(string("--gain"), "use_direct_amount ? total_expr :" - " market(get_at(total_expr, 0), date, exchange)" + " market(get_at(total_expr, 0), value_date, exchange)" " - get_at(total_expr, 1)"); }); @@ -642,9 +642,11 @@ public: OPTION_(report_t, market, DO() { // -V parent->HANDLER(revalued).on_only(string("--market")); parent->HANDLER(display_amount_) - .set_expr(string("--market"), "market(amount_expr, date, exchange)"); + .set_expr(string("--market"), + "market(amount_expr, value_date, exchange)"); parent->HANDLER(display_total_) - .set_expr(string("--market"), "market(total_expr, date, exchange)"); + .set_expr(string("--market"), + "market(total_expr, value_date, exchange)"); }); OPTION(report_t, meta_); |