Added a new --exact option

The purpose of this option is that usually when you do a --monthly
periodic report, you see dates ranges from the first day of each month,
to the last day.  With --exact, the first day of each range will be the
date of the first transaction found in that range, and likewise with the
end of the range.  Essentially it "contracts" the reported period dates
to reflect the exact begin and end dates.
This commit is contained in:
John Wiegley 2009-02-21 02:14:53 -04:00
parent a93111470d
commit d0ac3a2e4e
6 changed files with 282 additions and 35 deletions

View file

@ -138,6 +138,7 @@ xact_handler_ptr chain_xact_handlers(report_t& report,
handler.reset(new interval_xacts(handler, expr,
report.HANDLER(period_).str(),
report.session.master.get(),
report.HANDLED(exact),
report.HANDLED(empty)));
handler.reset(new sort_xacts(handler, "date"));
}

View file

@ -414,43 +414,45 @@ void changed_value_xacts::operator()(xact_t& xact)
last_xact = &xact;
}
void subtotal_xacts::report_subtotal(const char * spec_fmt)
void subtotal_xacts::report_subtotal(const char * spec_fmt,
const date_t& start,
const date_t& finish)
{
if (component_xacts.empty())
return;
date_t start;
date_t finish;
date_t range_start = start;
date_t range_finish = 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;
if (! is_valid(range_start) || date < range_start)
range_start = date;
if (! is_valid(range_finish) || date > range_finish)
range_finish = date;
}
component_xacts.clear();
std::ostringstream out_date;
if (spec_fmt) {
out_date << format_date(finish, string(spec_fmt));
out_date << format_date(range_finish, string(spec_fmt));
}
else if (date_format) {
string fmt = "- ";
fmt += *date_format;
out_date << format_date(finish, string(fmt));
out_date << format_date(range_finish, string(fmt));
}
else {
out_date << format_date(finish, std::string("- ") + output_date_format);
out_date << format_date(range_finish, std::string("- ") + output_date_format);
}
entry_temps.push_back(entry_t());
entry_t& entry = entry_temps.back();
entry.payee = out_date.str();
entry._date = start;
entry._date = range_start;
foreach (values_map::value_type& pair, values)
handle_value(pair.second.value, pair.second.account, &entry, 0,
xact_temps, *handler, finish);
xact_temps, *handler, range_finish);
values.clear();
}
@ -483,23 +485,35 @@ void subtotal_xacts::operator()(xact_t& xact)
xact.reported_account()->xdata().add_flags(ACCOUNT_EXT_HAS_UNB_VIRTUALS);
}
void interval_xacts::report_subtotal(const date_t& finish)
{
if (last_xact && interval) {
if (exact_periods)
subtotal_xacts::report_subtotal();
else
subtotal_xacts::report_subtotal(NULL, interval.begin, finish);
}
last_xact = NULL;
}
void interval_xacts::operator()(xact_t& xact)
{
date_t date = xact.date();
date_t date = xact.reported_date();
if (! is_valid(interval.begin)) {
interval.set_start(date);
}
else if ((is_valid(interval.begin) && date < interval.begin) ||
(is_valid(interval.end) && date >= interval.end)) {
if ((is_valid(interval.begin) && date < interval.begin) ||
(is_valid(interval.end) && date >= interval.end))
return;
}
if (interval) {
if (! is_valid(interval.begin))
interval.set_start(date);
start = interval.begin;
date_t quant = interval.increment(interval.begin);
if (date >= quant) {
if (last_xact)
report_subtotal();
report_subtotal(quant - gregorian::days(1));
date_t temp;
while (date >= (temp = interval.increment(quant))) {
@ -515,7 +529,7 @@ void interval_xacts::operator()(xact_t& xact)
entry_temps.push_back(entry_t());
entry_t& null_entry = entry_temps.back();
null_entry.add_flags(ITEM_TEMP);
null_entry._date = quant;
null_entry._date = quant - gregorian::days(1);
xact_temps.push_back(xact_t(&empty_account));
xact_t& null_xact = xact_temps.back();
@ -526,10 +540,10 @@ void interval_xacts::operator()(xact_t& xact)
last_xact = &null_xact;
subtotal_xacts::operator()(null_xact);
report_subtotal();
report_subtotal(quant - gregorian::days(1));
}
}
interval.begin = quant;
start = interval.begin = quant;
}
subtotal_xacts::operator()(xact);
} else {

View file

@ -559,7 +559,9 @@ public:
clear_entries_xacts(entry_temps);
}
void report_subtotal(const char * spec_fmt = NULL);
void report_subtotal(const char * spec_fmt = NULL,
const date_t& start = date_t(),
const date_t& finish = date_t());
virtual void flush() {
if (values.size() > 0)
@ -579,33 +581,36 @@ class interval_xacts : public subtotal_xacts
interval_t interval;
xact_t * last_xact;
account_t empty_account;
bool exact_periods;
bool generate_empty_xacts;
date_t start;
interval_xacts();
public:
interval_xacts(xact_handler_ptr _handler, expr_t& amount_expr,
const interval_t& _interval, account_t * master = NULL,
bool _generate_empty_xacts = false)
interval_xacts(xact_handler_ptr _handler,
expr_t& amount_expr,
const interval_t& _interval,
account_t * master = NULL,
bool _exact_periods = false,
bool _generate_empty_xacts = false)
: subtotal_xacts(_handler, amount_expr), interval(_interval),
last_xact(NULL), empty_account(master, "<None>"),
exact_periods(_exact_periods),
generate_empty_xacts(_generate_empty_xacts) {
TRACE_CTOR(interval_xacts,
"xact_handler_ptr, expr_t&, const interval_t&, account_t *, bool");
"xact_handler_ptr, expr_t&, interval_t, account_t *, bool, bool");
}
virtual ~interval_xacts() throw() {
TRACE_DTOR(interval_xacts);
}
void report_subtotal() {
if (last_xact && interval)
subtotal_xacts::report_subtotal();
last_xact = NULL;
}
void report_subtotal(const date_t& finish);
virtual void flush() {
if (last_xact)
report_subtotal();
if (last_xact && interval)
report_subtotal(interval.increment(interval.begin) - gregorian::days(1));
subtotal_xacts::flush();
}
virtual void operator()(xact_t& xact);

View file

@ -368,6 +368,7 @@ option_t<report_t> * report_t::lookup_option(const char * p)
else OPT(empty);
else OPT_(end_);
else OPT(equity);
else OPT(exact);
break;
case 'f':
OPT(flat);

View file

@ -373,6 +373,7 @@ public:
});
OPTION(report_t, equity);
OPTION(report_t, exact);
OPTION(report_t, flat);
OPTION(report_t, forecast_while_);
OPTION(report_t, format_); // -F

View file

@ -0,0 +1,225 @@
reg --weekly --exact books
<<<
2008/01/01 January
Expenses:Books $10.00
Assets:Cash
2008/01/31 End of January
Expenses:Books $10.00
Assets:Cash
2008/02/01 February
Expenses:Books $20.00
Assets:Cash
2008/02/28 End of February
Expenses:Books $20.00
Assets:Cash
2008/03/01 March
Expenses:Books $30.00
Assets:Cash
2008/03/31 End of March
Expenses:Books $30.00
Assets:Cash
2008/04/01 April
Expenses:Books $40.00
Assets:Cash
2008/04/30 End of April
Expenses:Books $40.00
Assets:Cash
2008/05/01 May
Expenses:Books $50.00
Assets:Cash
2008/05/31 End of May
Expenses:Books $50.00
Assets:Cash
2008/06/01 June
Expenses:Books $60.00
Assets:Cash
2008/06/30 End of June
Expenses:Books $60.00
Assets:Cash
2008/07/01 July
Expenses:Books $70.00
Assets:Cash
2008/07/31 End of July
Expenses:Books $70.00
Assets:Cash
2008/08/01 August
Expenses:Books $80.00
Assets:Cash
2008/08/31 End of August
Expenses:Books $80.00
Assets:Cash
2008/09/01 September
Expenses:Books $90.00
Assets:Cash
2008/09/30 End of September
Expenses:Books $90.00
Assets:Cash
2008/10/01 October
Expenses:Books $100.00
Assets:Cash
2008/10/31 End of October
Expenses:Books $100.00
Assets:Cash
2008/11/01 November
Expenses:Books $110.00
Assets:Cash
2008/11/30 End of November
Expenses:Books $110.00
Assets:Cash
2008/12/01 December
Expenses:Books $120.00
Assets:Cash
2008/12/31 End of December
Expenses:Books $120.00
Assets:Cash
2009/01/01 January
Expenses:Books $10.00
Assets:Cash
2009/01/31 End of January
Expenses:Books $10.00
Assets:Cash
2009/02/01 February
Expenses:Books $20.00
Assets:Cash
2009/02/28 End of February
Expenses:Books $20.00
Assets:Cash
2009/03/01 March
Expenses:Books $30.00
Assets:Cash
2009/03/31 End of March
Expenses:Books $30.00
Assets:Cash
2009/04/01 April
Expenses:Books $40.00
Assets:Cash
2009/04/30 End of April
Expenses:Books $40.00
Assets:Cash
2009/05/01 May
Expenses:Books $50.00
Assets:Cash
2009/05/31 End of May
Expenses:Books $50.00
Assets:Cash
2009/06/01 June
Expenses:Books $60.00
Assets:Cash
2009/06/30 End of June
Expenses:Books $60.00
Assets:Cash
2009/07/01 July
Expenses:Books $70.00
Assets:Cash
2009/07/31 End of July
Expenses:Books $70.00
Assets:Cash
2009/08/01 August
Expenses:Books $80.00
Assets:Cash
2009/08/31 End of August
Expenses:Books $80.00
Assets:Cash
2009/09/01 September
Expenses:Books $90.00
Assets:Cash
2009/09/30 End of September
Expenses:Books $90.00
Assets:Cash
2009/10/01 October
Expenses:Books $100.00
Assets:Cash
2009/10/31 End of October
Expenses:Books $100.00
Assets:Cash
2009/11/01 November
Expenses:Books $110.00
Assets:Cash
2009/11/30 End of November
Expenses:Books $110.00
Assets:Cash
2009/12/01 December
Expenses:Books $120.00
Assets:Cash
2009/12/31 End of December
Expenses:Books $120.00
Assets:Cash
>>>1
08-Jan-01 - 08-Jan-01 Expenses:Books $10.00 $10.00
08-Jan-31 - 08-Feb-01 Expenses:Books $30.00 $40.00
08-Feb-28 - 08-Mar-01 Expenses:Books $50.00 $90.00
08-Mar-31 - 08-Apr-01 Expenses:Books $70.00 $160.00
08-Apr-30 - 08-May-01 Expenses:Books $90.00 $250.00
08-May-31 - 08-May-31 Expenses:Books $50.00 $300.00
08-Jun-01 - 08-Jun-01 Expenses:Books $60.00 $360.00
08-Jun-30 - 08-Jul-01 Expenses:Books $130.00 $490.00
08-Jul-31 - 08-Aug-01 Expenses:Books $150.00 $640.00
08-Aug-31 - 08-Sep-01 Expenses:Books $170.00 $810.00
08-Sep-30 - 08-Oct-01 Expenses:Books $190.00 $1000.00
08-Oct-31 - 08-Nov-01 Expenses:Books $210.00 $1210.00
08-Nov-30 - 08-Dec-01 Expenses:Books $230.00 $1440.00
08-Dec-31 - 09-Jan-01 Expenses:Books $130.00 $1570.00
09-Jan-31 - 09-Jan-31 Expenses:Books $10.00 $1580.00
09-Feb-01 - 09-Feb-01 Expenses:Books $20.00 $1600.00
09-Feb-28 - 09-Feb-28 Expenses:Books $20.00 $1620.00
09-Mar-01 - 09-Mar-01 Expenses:Books $30.00 $1650.00
09-Mar-31 - 09-Apr-01 Expenses:Books $70.00 $1720.00
09-Apr-30 - 09-May-01 Expenses:Books $90.00 $1810.00
09-May-31 - 09-Jun-01 Expenses:Books $110.00 $1920.00
09-Jun-30 - 09-Jul-01 Expenses:Books $130.00 $2050.00
09-Jul-31 - 09-Aug-01 Expenses:Books $150.00 $2200.00
09-Aug-31 - 09-Sep-01 Expenses:Books $170.00 $2370.00
09-Sep-30 - 09-Oct-01 Expenses:Books $190.00 $2560.00
09-Oct-31 - 09-Oct-31 Expenses:Books $100.00 $2660.00
09-Nov-01 - 09-Nov-01 Expenses:Books $110.00 $2770.00
09-Nov-30 - 09-Dec-01 Expenses:Books $230.00 $3000.00
09-Dec-31 - 09-Dec-31 Expenses:Books $120.00 $3120.00
>>>2
=== 0