summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/chain.cc1
-rw-r--r--src/filters.cc60
-rw-r--r--src/filters.h29
-rw-r--r--src/report.cc1
-rw-r--r--src/report.h1
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