summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2009-11-19 02:00:10 -0500
committerJohn Wiegley <johnw@newartisans.com>2009-11-19 02:00:10 -0500
commit63fee4c83775f79364199ea547dbc7e068b0abc8 (patch)
tree4230ae03ebea8e2cbc0b6e1de821730e4819af47 /src
parent3f1861fb1e9e374fb7756117638edcb6fb1e73fb (diff)
downloadfork-ledger-63fee4c83775f79364199ea547dbc7e068b0abc8.tar.gz
fork-ledger-63fee4c83775f79364199ea547dbc7e068b0abc8.tar.bz2
fork-ledger-63fee4c83775f79364199ea547dbc7e068b0abc8.zip
Added an --unrealized option, for use with bal -V
When this option is on, then in balance report which show market values, any gains or losses in value will be balanced into a pair of accounts called Equity:Unrealized Gains and Equity:Unrealized Losses.
Diffstat (limited to 'src')
-rw-r--r--src/chain.cc19
-rw-r--r--src/filters.cc58
-rw-r--r--src/filters.h8
-rw-r--r--src/report.cc1
-rw-r--r--src/report.h3
5 files changed, 74 insertions, 15 deletions
diff --git a/src/chain.cc b/src/chain.cc
index 9ab26bd6..113a71d8 100644
--- a/src/chain.cc
+++ b/src/chain.cc
@@ -77,18 +77,23 @@ post_handler_ptr chain_post_handlers(report_t& report,
report.what_to_keep());
handler.reset(new filter_posts(handler, display_predicate, report));
}
-
- // changed_value_posts adds virtual posts to the list to account for
- // changes in market value of commodities, which otherwise would affect
- // the running total unpredictably.
- if (report.HANDLED(revalued))
- handler.reset(new changed_value_posts(handler, report));
}
+ // changed_value_posts adds virtual posts to the list to account for changes
+ // in market value of commodities, which otherwise would affect the running
+ // total unpredictably.
+ if (report.HANDLED(revalued) && (! for_accounts_report ||
+ report.HANDLED(unrealized)))
+ handler.reset(new changed_value_posts(handler, report,
+ for_accounts_report,
+ report.HANDLED(unrealized)));
+
// 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, ! for_accounts_report));
+ handler.reset(new calc_posts(handler, expr, (! for_accounts_report ||
+ (report.HANDLED(revalued) &&
+ report.HANDLED(unrealized)))));
// filter_posts will only pass through posts matching the
// `secondary_predicate'.
diff --git a/src/filters.cc b/src/filters.cc
index 4ac3de4c..39097c58 100644
--- a/src/filters.cc
+++ b/src/filters.cc
@@ -249,6 +249,7 @@ namespace {
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)
{
post_t& post = temps.create_post(*xact, account);
@@ -308,6 +309,11 @@ namespace {
DEBUG("filter.changed_value.rounding", "post.amount = " << post.amount);
(*handler)(post);
+
+ if (mark_visited) {
+ post.xdata().add_flags(POST_EXT_VISITED);
+ post.account->xdata().add_flags(ACCOUNT_EXT_VISITED);
+ }
}
}
@@ -406,8 +412,12 @@ void related_posts::flush()
}
changed_value_posts::changed_value_posts(post_handler_ptr handler,
- report_t& _report)
- : item_handler<post_t>(handler), report(_report), last_post(NULL),
+ report_t& _report,
+ bool _for_accounts_report,
+ bool _show_unrealized)
+ : 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_account(temps.create_account(_("<Rounding>")))
{
@@ -419,6 +429,14 @@ changed_value_posts::changed_value_posts(post_handler_ptr handler,
report.HANDLER(display_total_).expr);
display_total_expr = report.HANDLER(display_total_).expr;
changed_values_only = report.HANDLED(revalued_only);
+
+ gains_equity_account =
+ report.session.journal->master->find_account(_("Equity:Unrealized Gains"));
+ gains_equity_account->add_flags(ACCOUNT_GENERATED);
+
+ losses_equity_account =
+ report.session.journal->master->find_account(_("Equity:Unrealized Losses"));
+ losses_equity_account->add_flags(ACCOUNT_GENERATED);
}
void changed_value_posts::flush()
@@ -460,10 +478,35 @@ void changed_value_posts::output_revaluation(post_t& post, const date_t& date)
xact.payee = _("Commodities revalued");
xact._date = is_valid(date) ? date : post.date();
- handle_value(diff, &revalued_account, &xact, temps, handler,
- *xact._date, repriced_total, false,
- optional<post_functor_t>
- (bind(&changed_value_posts::output_rounding, this, _1)));
+ if (! for_accounts_report) {
+ handle_value
+ (/* value= */ diff,
+ /* account= */ &revalued_account,
+ /* xact= */ &xact,
+ /* temps= */ temps,
+ /* handler= */ handler,
+ /* date= */ *xact._date,
+ /* total= */ repriced_total,
+ /* direct_amount= */ false,
+ /* mark_visited= */ false,
+ /* functor= */ (optional<post_functor_t>
+ (bind(&changed_value_posts::output_rounding,
+ this, _1))));
+ }
+ else if (show_unrealized) {
+ handle_value
+ (/* value= */ - diff,
+ /* account= */ (diff < 0L ?
+ losses_equity_account :
+ gains_equity_account),
+ /* xact= */ &xact,
+ /* temps= */ temps,
+ /* handler= */ handler,
+ /* date= */ *xact._date,
+ /* total= */ value_t(),
+ /* direct_amount= */ false,
+ /* mark_visited= */ true);
+ }
}
}
}
@@ -513,7 +556,8 @@ void changed_value_posts::operator()(post_t& post)
if (changed_values_only)
post.xdata().add_flags(POST_EXT_DISPLAYED);
- output_rounding(post);
+ if (! for_accounts_report)
+ output_rounding(post);
item_handler<post_t>::operator()(post);
diff --git a/src/filters.h b/src/filters.h
index f9412407..92148dbe 100644
--- a/src/filters.h
+++ b/src/filters.h
@@ -378,18 +378,24 @@ class changed_value_posts : public item_handler<post_t>
expr_t display_total_expr;
report_t& report;
bool changed_values_only;
+ bool for_accounts_report;
+ bool show_unrealized;
post_t * last_post;
value_t last_total;
value_t last_display_total;
temporaries_t temps;
account_t& revalued_account;
account_t& rounding_account;
+ account_t * gains_equity_account;
+ account_t * losses_equity_account;
changed_value_posts();
public:
changed_value_posts(post_handler_ptr handler,
- report_t& _report);
+ report_t& _report,
+ bool _for_accounts_report,
+ bool _show_unrealized);
virtual ~changed_value_posts() {
TRACE_DTOR(changed_value_posts);
diff --git a/src/report.cc b/src/report.cc
index 92525565..7da44f8c 100644
--- a/src/report.cc
+++ b/src/report.cc
@@ -887,6 +887,7 @@ option_t<report_t> * report_t::lookup_option(const char * p)
case 'u':
OPT(unbudgeted);
else OPT(uncleared);
+ else OPT(unrealized);
else OPT(unround);
else OPT(unsorted);
break;
diff --git a/src/report.h b/src/report.h
index 0b1baff1..354e31b6 100644
--- a/src/report.h
+++ b/src/report.h
@@ -301,6 +301,7 @@ public:
HANDLER(truncate_).report(out);
HANDLER(unbudgeted).report(out);
HANDLER(uncleared).report(out);
+ HANDLER(unrealized).report(out);
HANDLER(unround).report(out);
HANDLER(unsorted).report(out);
HANDLER(weekly).report(out);
@@ -873,6 +874,8 @@ public:
parent->HANDLER(limit_).on(string("--uncleared"), "uncleared|pending");
});
+ OPTION(report_t, unrealized);
+
OPTION_(report_t, unround, DO() {
parent->HANDLER(display_amount_)
.set_expr(string("--unround"), "unrounded(amount_expr)");