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:
parent
a93111470d
commit
d0ac3a2e4e
6 changed files with 282 additions and 35 deletions
|
|
@ -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"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
225
test/baseline/opt-exact.test
Normal file
225
test/baseline/opt-exact.test
Normal 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
|
||||
Loading…
Add table
Reference in a new issue