summaryrefslogtreecommitdiff
path: root/src/filters.cc
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2010-06-09 05:44:06 -0400
committerJohn Wiegley <johnw@newartisans.com>2010-06-09 05:44:06 -0400
commit14476a63f4abbdce5311ace031b7345a34af060b (patch)
treec1900d4f2a95db2cdb4cf7404669fe668acedb4a /src/filters.cc
parente8ffbd6f2fb57f2b65f57f92edf8eb444cc2f71f (diff)
parent474d95adeb09b0c13f0e19b336b5b01ee69c6275 (diff)
downloadfork-ledger-14476a63f4abbdce5311ace031b7345a34af060b.tar.gz
fork-ledger-14476a63f4abbdce5311ace031b7345a34af060b.tar.bz2
fork-ledger-14476a63f4abbdce5311ace031b7345a34af060b.zip
Merge branch 'next'
Diffstat (limited to 'src/filters.cc')
-rw-r--r--src/filters.cc187
1 files changed, 111 insertions, 76 deletions
diff --git a/src/filters.cc b/src/filters.cc
index e5c5275c..1385a3f0 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();
@@ -466,27 +472,46 @@ void related_posts::flush()
item_handler<post_t>::flush();
}
-rounding_error_posts::rounding_error_posts(post_handler_ptr handler,
- report_t& _report)
+display_filter_posts::display_filter_posts(post_handler_ptr handler,
+ report_t& _report,
+ bool _show_rounding)
: item_handler<post_t>(handler), report(_report),
- rounding_account(temps.create_account(_("<Rounding>")))
+ show_rounding(_show_rounding),
+ rounding_account(temps.create_account(_("<Rounding>"))),
+ revalued_account(temps.create_account(_("<Revalued>")))
{
- TRACE_CTOR(rounding_error_posts, "post_handler_ptr, report_t&");
+ TRACE_CTOR(display_filter_posts,
+ "post_handler_ptr, report_t&, account_t&, bool");
display_amount_expr = report.HANDLER(display_amount_).expr;
display_total_expr = report.HANDLER(display_total_).expr;
}
-void rounding_error_posts::output_rounding(post_t& post)
+bool display_filter_posts::output_rounding(post_t& post)
{
bind_scope_t bound_scope(report, post);
- value_t new_display_total(display_total_expr.calc(bound_scope));
+ value_t new_display_total;
+
+ if (show_rounding) {
+ new_display_total = display_total_expr.calc(bound_scope);
- DEBUG("filters.changed_value.rounding",
- "rounding.new_display_total = " << new_display_total);
+ DEBUG("filters.changed_value.rounding",
+ "rounding.new_display_total = " << new_display_total);
+ }
+
+ // Allow the posting to be displayed if:
+ // 1. It's display_amount would display as non-zero
+ // 2. The --empty option was specified
+ // 3. The account of the posting is <Revalued>
+
+ if (post.account == &revalued_account) {
+ if (show_rounding)
+ last_display_total = new_display_total;
+ return true;
+ }
- if (! last_display_total.is_null()) {
- if (value_t repriced_amount = display_amount_expr.calc(bound_scope)) {
+ if (value_t repriced_amount = display_amount_expr.calc(bound_scope)) {
+ if (! last_display_total.is_null()) {
DEBUG("filters.changed_value.rounding",
"rounding.repriced_amount = " << repriced_amount);
@@ -502,29 +527,29 @@ void rounding_error_posts::output_rounding(post_t& post)
DEBUG("filters.changed_value.rounding",
"rounding.diff = " << diff);
- xact_t& xact = temps.create_xact();
- xact.payee = _("Commodity rounding");
- xact._date = post.date();
-
handle_value(/* value= */ diff,
/* account= */ &rounding_account,
- /* xact= */ &xact,
+ /* xact= */ post.xact,
/* temps= */ temps,
/* handler= */ handler,
- /* date= */ *xact._date,
+ /* date= */ date_t(),
+ /* act_date_p= */ true,
/* total= */ precise_display_total,
/* direct_amount= */ true);
}
- }
+ }
+ if (show_rounding)
+ last_display_total = new_display_total;
+ return true;
+ } else {
+ return report.HANDLED(empty);
}
- last_display_total = new_display_total;
}
-void rounding_error_posts::operator()(post_t& post)
+void display_filter_posts::operator()(post_t& post)
{
- output_rounding(post);
-
- item_handler<post_t>::operator()(post);
+ if (output_rounding(post))
+ item_handler<post_t>::operator()(post);
}
changed_value_posts::changed_value_posts
@@ -532,12 +557,13 @@ changed_value_posts::changed_value_posts
report_t& _report,
bool _for_accounts_report,
bool _show_unrealized,
- rounding_error_posts * _rounding_handler)
+ display_filter_posts * _display_filter)
: item_handler<post_t>(handler), report(_report),
for_accounts_report(_for_accounts_report),
show_unrealized(_show_unrealized), last_post(NULL),
- revalued_account(temps.create_account(_("<Revalued>"))),
- rounding_handler(_rounding_handler)
+ revalued_account(_display_filter ? _display_filter->revalued_account :
+ temps.create_account(_("<Revalued>"))),
+ display_filter(_display_filter)
{
TRACE_CTOR(changed_value_posts, "post_handler_ptr, report_t&, bool");
@@ -604,7 +630,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
@@ -614,6 +640,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) {
@@ -626,6 +653,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);
@@ -649,7 +677,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);
@@ -711,9 +739,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());
@@ -755,8 +783,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)
@@ -780,11 +808,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();
@@ -806,11 +835,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();
}
@@ -919,17 +950,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;
}