Fixed how subtotal date ranges are computed

This commit is contained in:
John Wiegley 2009-02-16 02:31:21 -04:00
parent 4dbd124e22
commit e3b40f5bb6
2 changed files with 63 additions and 71 deletions

View file

@ -405,6 +405,17 @@ void changed_value_xacts::operator()(xact_t& xact)
void subtotal_xacts::report_subtotal(const char * spec_fmt) void subtotal_xacts::report_subtotal(const char * spec_fmt)
{ {
date_t start;
date_t finish;
foreach (xact_t * xact, component_xacts) {
date_t date = xact->reported_date();
if (! is_valid(start) || date < start)
start = date;
if (! is_valid(finish) || date > finish)
finish = date;
}
component_xacts.clear();
std::ostringstream out_date; std::ostringstream out_date;
if (spec_fmt) { if (spec_fmt) {
out_date << format_date(finish, string(spec_fmt)); out_date << format_date(finish, string(spec_fmt));
@ -432,12 +443,7 @@ void subtotal_xacts::report_subtotal(const char * spec_fmt)
void subtotal_xacts::operator()(xact_t& xact) void subtotal_xacts::operator()(xact_t& xact)
{ {
date_t when = xact.date(); component_xacts.push_back(&xact);
if (! is_valid(start) || when < start)
start = when;
if (! is_valid(finish) || when > finish)
finish = when;
account_t * acct = xact.reported_account(); account_t * acct = xact.reported_account();
assert(acct); assert(acct);
@ -463,37 +469,23 @@ void subtotal_xacts::operator()(xact_t& xact)
xact.reported_account()->xdata().add_flags(ACCOUNT_EXT_HAS_UNB_VIRTUALS); xact.reported_account()->xdata().add_flags(ACCOUNT_EXT_HAS_UNB_VIRTUALS);
} }
void interval_xacts::report_subtotal(const date_t& date)
{
assert(last_xact);
start = interval.begin;
finish = date - gregorian::days(1);
subtotal_xacts::report_subtotal();
last_xact = NULL;
}
void interval_xacts::operator()(xact_t& xact) void interval_xacts::operator()(xact_t& xact)
{ {
date_t date = xact.date(); date_t date = xact.date();
if ((is_valid(interval.begin) && date < interval.begin) || if (! is_valid(interval.begin)) {
(is_valid(interval.end) && date >= interval.end))
return;
if (! started) {
if (! is_valid(interval.begin))
interval.set_start(date); interval.set_start(date);
start = interval.begin; }
started = true; else if ((is_valid(interval.begin) && date < interval.begin) ||
(is_valid(interval.end) && date >= interval.end)) {
return;
} }
if (interval) {
date_t quant = interval.increment(interval.begin); date_t quant = interval.increment(interval.begin);
if (date >= quant) { if (date >= quant) {
if (last_xact) if (last_xact)
report_subtotal(quant); report_subtotal();
date_t temp; date_t temp;
while (date >= (temp = interval.increment(quant))) { while (date >= (temp = interval.increment(quant))) {
@ -520,10 +512,11 @@ void interval_xacts::operator()(xact_t& xact)
last_xact = &null_xact; last_xact = &null_xact;
subtotal_xacts::operator()(null_xact); subtotal_xacts::operator()(null_xact);
report_subtotal(quant); report_subtotal();
} }
} }
start = interval.begin = quant; interval.begin = quant;
}
} }
subtotal_xacts::operator()(xact); subtotal_xacts::operator()(xact);
@ -564,9 +557,6 @@ void by_payee_xacts::operator()(xact_t& xact)
i = result.first; i = result.first;
} }
if (xact.date() > (*i).second->start)
(*i).second->start = xact.date();
(*(*i).second)(xact); (*(*i).second)(xact);
} }
@ -574,7 +564,8 @@ void set_comm_as_payee::operator()(xact_t& xact)
{ {
entry_temps.push_back(*xact.entry); entry_temps.push_back(*xact.entry);
entry_t& entry = entry_temps.back(); entry_t& entry = entry_temps.back();
entry._date = xact.date(); entry._date = xact._date;
entry._date_eff = xact._date_eff;
entry.code = xact.entry->code; entry.code = xact.entry->code;
if (xact.amount.commodity()) if (xact.amount.commodity())
@ -597,7 +588,8 @@ void set_code_as_payee::operator()(xact_t& xact)
{ {
entry_temps.push_back(*xact.entry); entry_temps.push_back(*xact.entry);
entry_t& entry = entry_temps.back(); entry_t& entry = entry_temps.back();
entry._date = xact.date(); entry._date = xact._date;
entry._date_eff = xact._date_eff;
if (xact.entry->code) if (xact.entry->code)
entry.payee = *xact.entry->code; entry.payee = *xact.entry->code;
@ -618,7 +610,6 @@ void set_code_as_payee::operator()(xact_t& xact)
void dow_xacts::flush() void dow_xacts::flush()
{ {
for (int i = 0; i < 7; i++) { for (int i = 0; i < 7; i++) {
start = finish = date_t();
foreach (xact_t * xact, days_of_the_week[i]) foreach (xact_t * xact, days_of_the_week[i])
subtotal_xacts::operator()(*xact); subtotal_xacts::operator()(*xact);
subtotal_xacts::report_subtotal("%As"); subtotal_xacts::report_subtotal("%As");

View file

@ -536,11 +536,9 @@ protected:
optional<string> date_format; optional<string> date_format;
std::list<entry_t> entry_temps; std::list<entry_t> entry_temps;
std::list<xact_t> xact_temps; std::list<xact_t> xact_temps;
std::list<xact_t *> component_xacts;
public: public:
date_t start;
date_t finish;
subtotal_xacts(xact_handler_ptr handler, expr_t& _amount_expr, subtotal_xacts(xact_handler_ptr handler, expr_t& _amount_expr,
const optional<string>& _date_format = none) const optional<string>& _date_format = none)
: item_handler<xact_t>(handler), amount_expr(_amount_expr), : item_handler<xact_t>(handler), amount_expr(_amount_expr),
@ -572,7 +570,6 @@ class interval_xacts : public subtotal_xacts
{ {
interval_t interval; interval_t interval;
xact_t * last_xact; xact_t * last_xact;
bool started;
std::list<entry_t> entry_temps; std::list<entry_t> entry_temps;
std::list<xact_t> xact_temps; std::list<xact_t> xact_temps;
@ -586,7 +583,7 @@ public:
const interval_t& _interval, account_t * master = NULL, const interval_t& _interval, account_t * master = NULL,
bool _generate_empty_xacts = false) bool _generate_empty_xacts = false)
: subtotal_xacts(_handler, amount_expr), interval(_interval), : subtotal_xacts(_handler, amount_expr), interval(_interval),
last_xact(NULL), started(false), empty_account(master, "<None>"), last_xact(NULL), empty_account(master, "<None>"),
generate_empty_xacts(_generate_empty_xacts) { generate_empty_xacts(_generate_empty_xacts) {
TRACE_CTOR(interval_xacts, TRACE_CTOR(interval_xacts,
"xact_handler_ptr, expr_t&, const interval_t&, account_t *, bool"); "xact_handler_ptr, expr_t&, const interval_t&, account_t *, bool");
@ -595,11 +592,15 @@ public:
TRACE_DTOR(interval_xacts); TRACE_DTOR(interval_xacts);
} }
void report_subtotal(const date_t& moment); void report_subtotal() {
assert(last_xact);
subtotal_xacts::report_subtotal();
last_xact = NULL;
}
virtual void flush() { virtual void flush() {
if (last_xact) if (last_xact)
report_subtotal(last_xact->date()); report_subtotal();
subtotal_xacts::flush(); subtotal_xacts::flush();
} }
virtual void operator()(xact_t& xact); virtual void operator()(xact_t& xact);