diff options
-rw-r--r-- | src/chain.cc | 1 | ||||
-rw-r--r-- | src/filters.cc | 60 | ||||
-rw-r--r-- | src/filters.h | 29 | ||||
-rw-r--r-- | src/report.cc | 1 | ||||
-rw-r--r-- | src/report.h | 1 | ||||
-rw-r--r-- | test/baseline/opt-exact.test | 225 |
6 files changed, 282 insertions, 35 deletions
diff --git a/src/chain.cc b/src/chain.cc index 2fc6123e..14c07b8c 100644 --- a/src/chain.cc +++ b/src/chain.cc @@ -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")); } diff --git a/src/filters.cc b/src/filters.cc index 06bc4487..f3b74aa3 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -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 { diff --git a/src/filters.h b/src/filters.h index 6089ef75..ea6874f6 100644 --- a/src/filters.h +++ b/src/filters.h @@ -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); diff --git a/src/report.cc b/src/report.cc index ce63101b..074af2f3 100644 --- a/src/report.cc +++ b/src/report.cc @@ -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); diff --git a/src/report.h b/src/report.h index 3d246cc8..00e0d588 100644 --- a/src/report.h +++ b/src/report.h @@ -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 diff --git a/test/baseline/opt-exact.test b/test/baseline/opt-exact.test new file mode 100644 index 00000000..358f1dc4 --- /dev/null +++ b/test/baseline/opt-exact.test @@ -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 |