summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2009-02-21 02:14:53 -0400
committerJohn Wiegley <johnw@newartisans.com>2009-02-21 02:14:53 -0400
commitd0ac3a2e4e4b6a28c71755fe54089e28e3a7d4db (patch)
tree4ac1059c1170ddabe68e43b890612595d1d3e5be
parenta93111470d54e6345617b51fcc939f306854a524 (diff)
downloadfork-ledger-d0ac3a2e4e4b6a28c71755fe54089e28e3a7d4db.tar.gz
fork-ledger-d0ac3a2e4e4b6a28c71755fe54089e28e3a7d4db.tar.bz2
fork-ledger-d0ac3a2e4e4b6a28c71755fe54089e28e3a7d4db.zip
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.
-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
-rw-r--r--test/baseline/opt-exact.test225
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