diff options
Diffstat (limited to 'src')
-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 |
5 files changed, 57 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 |