-V/-X options now take price history into account

This commit is contained in:
John Wiegley 2010-05-30 20:49:50 -06:00
parent 58621a96a2
commit 5a2644c1b7
4 changed files with 84 additions and 5 deletions

View file

@ -503,6 +503,8 @@ changed_value_posts::changed_value_posts(post_handler_ptr handler,
void changed_value_posts::flush()
{
if (last_post && last_post->date() <= report.terminus.date()) {
if (! for_accounts_report)
output_intermediate_prices(*last_post, report.terminus.date());
output_revaluation(*last_post, report.terminus.date());
last_post = NULL;
}
@ -514,7 +516,6 @@ void changed_value_posts::output_revaluation(post_t& post, const date_t& date)
if (is_valid(date))
post.xdata().date = date;
value_t repriced_total;
try {
bind_scope_t bound_scope(report, post);
repriced_total = total_expr.calc(bound_scope);
@ -573,6 +574,78 @@ void changed_value_posts::output_revaluation(post_t& post, const date_t& date)
}
}
void changed_value_posts::output_intermediate_prices(post_t& post,
const date_t& current)
{
// To fix BZ#199, examine the balance of last_post and determine whether the
// price of that amount changed after its date and before the new post's
// date. If so, generate an output_revaluation for that price change.
// Mostly this is only going to occur if the user has a series of pricing
// entries, since a posting-based revaluation would be seen here as a post.
assert(! last_total.is_null());
switch (last_total.type()) {
case value_t::INTEGER:
case value_t::SEQUENCE:
break;
case value_t::AMOUNT:
last_total.in_place_cast(value_t::BALANCE);
// fall through...
case value_t::BALANCE: {
commodity_t::history_map all_prices;
foreach (const balance_t::amounts_map::value_type& amt_comm,
last_total.as_balance().amounts) {
if (optional<commodity_t::varied_history_t&> hist =
amt_comm.first->varied_history()) {
foreach
(const commodity_t::history_by_commodity_map::value_type& comm_hist,
hist->histories) {
foreach (const commodity_t::history_map::value_type& price,
comm_hist.second.prices) {
if (price.first.date() > post.date() &&
price.first.date() < current) {
DEBUG("filters.revalued", post.date() << " < "
<< price.first.date() << " < " << current);
DEBUG("filters.revalued", "inserting "
<< price.second << " at " << price.first.date());
all_prices.insert(price);
}
}
}
}
}
// Choose the last price from each day as the price to use
typedef std::map<const date_t,
std::pair<const datetime_t,
amount_t> > history_by_date_map;
history_by_date_map all_prices_by_date;
BOOST_REVERSE_FOREACH
(const commodity_t::history_map::value_type& price, all_prices) {
// This insert will fail if a later price has already been inserted
// for that date.
DEBUG("filters.revalued",
"re-inserting " << price.second << " at " << price.first.date());
all_prices_by_date.insert(history_by_date_map::value_type
(price.first.date(), price));
}
// Go through the time-sorted prices list, outputting a revaluation for
// each price difference.
foreach (const history_by_date_map::value_type& price, all_prices_by_date) {
output_revaluation(post, price.first);
last_total = repriced_total;
}
break;
}
default:
assert(false);
break;
}
}
void changed_value_posts::output_rounding(post_t& post)
{
bind_scope_t bound_scope(report, post);
@ -612,8 +685,11 @@ void changed_value_posts::output_rounding(post_t& post)
void changed_value_posts::operator()(post_t& post)
{
if (last_post)
if (last_post) {
if (! for_accounts_report)
output_intermediate_prices(*last_post, post.date());
output_revaluation(*last_post, post.date());
}
if (changed_values_only)
post.xdata().add_flags(POST_EXT_DISPLAYED);

View file

@ -499,6 +499,7 @@ class changed_value_posts : public item_handler<post_t>
post_t * last_post;
value_t last_total;
value_t last_display_total;
value_t repriced_total;
temporaries_t temps;
account_t& revalued_account;
account_t& rounding_account;
@ -521,6 +522,7 @@ public:
virtual void flush();
void output_revaluation(post_t& post, const date_t& current);
void output_intermediate_prices(post_t& post, const date_t& current);
void output_rounding(post_t& post);
virtual void operator()(post_t& post);

View file

@ -28,7 +28,8 @@ reg --end 2009/06/26 -V equities
08-Jan-01 Purchase Apple shares Equities $2000 $2000
08-Jun-30 Commodities revalued <Revalued> $500 $2500
08-Jun-30 Sell some Apple sha.. Equities $-1250 $1250
09-Jun-26 Commodities revalued <Revalued> $750 $2000
09-Jan-31 Commodities revalued <Revalued> $250 $1500
09-Jun-26 Commodities revalued <Revalued> $500 $2000
>>>2
=== 0
reg --end 2009/06/26 -G equities

View file

@ -1,4 +1,4 @@
reg -V --end=2009/06/16
reg -V
<<<
D 1000.00 EUR
@ -10,6 +10,6 @@ P 2008/04/20 00:00:00 CAD 1.20 EUR
>>>1
08-Apr-15 Paid expenses back .. Ex:Cie-Reimbursements 2200.00 EUR 2200.00 EUR
Assets:Checking -2200.00 EUR 0
09-Jun-16 Commodities revalued <Revalued> 200.00 EUR 200.00 EUR
08-Apr-20 Commodities revalued <Revalued> 200.00 EUR 200.00 EUR
>>>2
=== 0