summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2010-06-19 16:07:54 -0400
committerJohn Wiegley <johnw@newartisans.com>2010-06-19 16:07:59 -0400
commit6770380b6da5061857e0a15539f1b85669d24e62 (patch)
treed04d198e1fa4abf0c4642a5112dbf99c4558e832
parentb819475a9346bedf31fd25e67dc2640ff6431141 (diff)
downloadfork-ledger-6770380b6da5061857e0a15539f1b85669d24e62.tar.gz
fork-ledger-6770380b6da5061857e0a15539f1b85669d24e62.tar.bz2
fork-ledger-6770380b6da5061857e0a15539f1b85669d24e62.zip
Subsantial fixes and improvements to budgeting
1. A bounded budget "from DATE to DATE" will now generate entries throughout that entire range, if it is triggered. 2. An unbounded budget begins, as before, in the timeframe of the reported posting which triggered it, but now continues until the present date.
-rw-r--r--src/chain.cc4
-rw-r--r--src/filters.cc45
-rw-r--r--src/filters.h10
-rw-r--r--test/baseline/opt-add-budget.test2
-rw-r--r--test/baseline/opt-budget.test2
-rw-r--r--test/baseline/opt-budget_range.test111
-rw-r--r--test/regress/8254755E.test6
7 files changed, 164 insertions, 16 deletions
diff --git a/src/chain.cc b/src/chain.cc
index 8010ba74..228c3fec 100644
--- a/src/chain.cc
+++ b/src/chain.cc
@@ -67,8 +67,8 @@ post_handler_ptr chain_pre_post_handlers(post_handler_ptr base_handler,
// future balance.
if (report.budget_flags != BUDGET_NO_BUDGET) {
- budget_posts * budget_handler = new budget_posts(handler,
- report.budget_flags);
+ budget_posts * budget_handler =
+ new budget_posts(handler, report.terminus.date(), report.budget_flags);
budget_handler->add_period_xacts(report.session.journal->period_xacts);
handler.reset(budget_handler);
diff --git a/src/filters.cc b/src/filters.cc
index 1a45ee8a..1a0ecd50 100644
--- a/src/filters.cc
+++ b/src/filters.cc
@@ -1143,20 +1143,44 @@ void budget_posts::report_budget_items(const date_t& date)
bool reported;
do {
+ std::list<pending_posts_list::iterator> posts_to_erase;
+
reported = false;
- foreach (pending_posts_list::value_type& pair, pending_posts) {
+ for (pending_posts_list::iterator i = pending_posts.begin();
+ i != pending_posts.end();
+ i++) {
+ pending_posts_list::value_type& pair(*i);
+
optional<date_t> begin = pair.first.start;
if (! begin) {
- if (! pair.first.find_period(date))
+ optional<date_t> range_begin;
+ if (pair.first.range)
+ range_begin = pair.first.range->begin();
+
+ DEBUG("budget.generate", "Finding period for pending post");
+ if (! pair.first.find_period(range_begin ? *range_begin : date))
continue;
+ if (! pair.first.start)
+ throw_(std::logic_error,
+ _("Failed to find period for periodic transaction"));
begin = pair.first.start;
}
- assert(begin);
+
+#if defined(DEBUG_ON)
+ DEBUG("budget.generate", "begin = " << *begin);
+ DEBUG("budget.generate", "date = " << date);
+ if (pair.first.finish)
+ DEBUG("budget.generate", "pair.first.finish = " << *pair.first.finish);
+#endif
if (*begin <= date &&
(! pair.first.finish || *begin < *pair.first.finish)) {
post_t& post = *pair.second;
+ ++pair.first;
+ if (! pair.first.start)
+ posts_to_erase.push_back(i);
+
DEBUG("budget.generate", "Reporting budget for "
<< post.reported_account()->fullname());
@@ -1176,14 +1200,14 @@ void budget_posts::report_budget_items(const date_t& date)
temp.xdata().add_flags(POST_EXT_COMPOUND);
}
- ++pair.first;
- begin = *pair.first.start;
-
item_handler<post_t>::operator()(temp);
reported = true;
}
}
+
+ foreach (pending_posts_list::iterator& i, posts_to_erase)
+ pending_posts.erase(i);
} while (reported);
}
@@ -1208,6 +1232,7 @@ void budget_posts::operator()(post_t& post)
handle:
if (post_in_budget && flags & BUDGET_BUDGETED) {
report_budget_items(post.date());
+ count++;
item_handler<post_t>::operator()(post);
}
else if (! post_in_budget && flags & BUDGET_UNBUDGETED) {
@@ -1215,6 +1240,14 @@ void budget_posts::operator()(post_t& post)
}
}
+void budget_posts::flush()
+{
+ if (count > 0)
+ report_budget_items(terminus);
+
+ item_handler<post_t>::flush();
+}
+
void forecast_posts::add_post(const date_interval_t& period, post_t& post)
{
date_interval_t i(period);
diff --git a/src/filters.h b/src/filters.h
index 180253d2..72e8f19f 100644
--- a/src/filters.h
+++ b/src/filters.h
@@ -882,14 +882,17 @@ class budget_posts : public generate_posts
#define BUDGET_WRAP_VALUES 0x04
uint_least8_t flags;
+ date_t terminus;
+ std::size_t count;
budget_posts();
public:
budget_posts(post_handler_ptr handler,
- uint_least8_t _flags = BUDGET_BUDGETED)
- : generate_posts(handler), flags(_flags) {
- TRACE_CTOR(budget_posts, "post_handler_ptr, uint_least8_t");
+ date_t _terminus,
+ uint_least8_t _flags = BUDGET_BUDGETED)
+ : generate_posts(handler), flags(_flags), terminus(_terminus), count(0) {
+ TRACE_CTOR(budget_posts, "post_handler_ptr, date_t, uint_least8_t");
}
virtual ~budget_posts() throw() {
TRACE_DTOR(budget_posts);
@@ -897,6 +900,7 @@ public:
void report_budget_items(const date_t& date);
+ virtual void flush();
virtual void operator()(post_t& post);
};
diff --git a/test/baseline/opt-add-budget.test b/test/baseline/opt-add-budget.test
index 535335d3..d2cd6945 100644
--- a/test/baseline/opt-add-budget.test
+++ b/test/baseline/opt-add-budget.test
@@ -1,4 +1,4 @@
-reg --add-budget books cards
+reg --add-budget books cards --now=2009/12/31
<<<
~ monthly
Expenses:Books $10.00
diff --git a/test/baseline/opt-budget.test b/test/baseline/opt-budget.test
index eb2ade9d..67b4e85e 100644
--- a/test/baseline/opt-budget.test
+++ b/test/baseline/opt-budget.test
@@ -1,4 +1,4 @@
-reg --budget books
+reg --budget books --now=2009/12/31
<<<
~ monthly
Expenses:Books $10.00
diff --git a/test/baseline/opt-budget_range.test b/test/baseline/opt-budget_range.test
new file mode 100644
index 00000000..7c8ee2d2
--- /dev/null
+++ b/test/baseline/opt-budget_range.test
@@ -0,0 +1,111 @@
+reg --now=2010/02 --sort=date exp --budget
+<<<
+~ monthly
+ Expenses:Food $100
+ Expenses:Movies $20
+ Assets:Cash
+
+~ monthly from 2009
+ Expenses:Food $101
+ Expenses:Movies $21
+ Assets:Cash
+
+~ monthly to 2010
+ Expenses:Food $102
+ Expenses:Movies $22
+ Assets:Cash
+
+~ monthly from 2009 to 2010
+ Expenses:Food $103
+ Expenses:Movies $23
+ Assets:Cash
+
+2009/06/05 Grocery
+ Expenses:Food $5
+ Assets:Cash
+>>>
+09-Jan-01 Budget transaction Expenses:Food $-101 $-101
+09-Jan-01 Budget transaction Expenses:Movies $-21 $-122
+09-Jan-01 Budget transaction Expenses:Food $-103 $-225
+09-Jan-01 Budget transaction Expenses:Movies $-23 $-248
+09-Feb-01 Budget transaction Expenses:Food $-101 $-349
+09-Feb-01 Budget transaction Expenses:Movies $-21 $-370
+09-Feb-01 Budget transaction Expenses:Food $-103 $-473
+09-Feb-01 Budget transaction Expenses:Movies $-23 $-496
+09-Mar-01 Budget transaction Expenses:Food $-101 $-597
+09-Mar-01 Budget transaction Expenses:Movies $-21 $-618
+09-Mar-01 Budget transaction Expenses:Food $-103 $-721
+09-Mar-01 Budget transaction Expenses:Movies $-23 $-744
+09-Apr-01 Budget transaction Expenses:Food $-101 $-845
+09-Apr-01 Budget transaction Expenses:Movies $-21 $-866
+09-Apr-01 Budget transaction Expenses:Food $-103 $-969
+09-Apr-01 Budget transaction Expenses:Movies $-23 $-992
+09-May-01 Budget transaction Expenses:Food $-101 $-1093
+09-May-01 Budget transaction Expenses:Movies $-21 $-1114
+09-May-01 Budget transaction Expenses:Food $-103 $-1217
+09-May-01 Budget transaction Expenses:Movies $-23 $-1240
+09-Jun-01 Budget transaction Expenses:Food $-100 $-1340
+09-Jun-01 Budget transaction Expenses:Movies $-20 $-1360
+09-Jun-01 Budget transaction Expenses:Food $-102 $-1462
+09-Jun-01 Budget transaction Expenses:Movies $-22 $-1484
+09-Jun-01 Budget transaction Expenses:Food $-101 $-1585
+09-Jun-01 Budget transaction Expenses:Movies $-21 $-1606
+09-Jun-01 Budget transaction Expenses:Food $-103 $-1709
+09-Jun-01 Budget transaction Expenses:Movies $-23 $-1732
+09-Jun-05 Grocery Expenses:Food $5 $-1727
+09-Jul-01 Budget transaction Expenses:Food $-100 $-1827
+09-Jul-01 Budget transaction Expenses:Movies $-20 $-1847
+09-Jul-01 Budget transaction Expenses:Food $-101 $-1948
+09-Jul-01 Budget transaction Expenses:Movies $-21 $-1969
+09-Jul-01 Budget transaction Expenses:Food $-102 $-2071
+09-Jul-01 Budget transaction Expenses:Movies $-22 $-2093
+09-Jul-01 Budget transaction Expenses:Food $-103 $-2196
+09-Jul-01 Budget transaction Expenses:Movies $-23 $-2219
+09-Aug-01 Budget transaction Expenses:Food $-100 $-2319
+09-Aug-01 Budget transaction Expenses:Movies $-20 $-2339
+09-Aug-01 Budget transaction Expenses:Food $-101 $-2440
+09-Aug-01 Budget transaction Expenses:Movies $-21 $-2461
+09-Aug-01 Budget transaction Expenses:Food $-102 $-2563
+09-Aug-01 Budget transaction Expenses:Movies $-22 $-2585
+09-Aug-01 Budget transaction Expenses:Food $-103 $-2688
+09-Aug-01 Budget transaction Expenses:Movies $-23 $-2711
+09-Sep-01 Budget transaction Expenses:Food $-100 $-2811
+09-Sep-01 Budget transaction Expenses:Movies $-20 $-2831
+09-Sep-01 Budget transaction Expenses:Food $-101 $-2932
+09-Sep-01 Budget transaction Expenses:Movies $-21 $-2953
+09-Sep-01 Budget transaction Expenses:Food $-102 $-3055
+09-Sep-01 Budget transaction Expenses:Movies $-22 $-3077
+09-Sep-01 Budget transaction Expenses:Food $-103 $-3180
+09-Sep-01 Budget transaction Expenses:Movies $-23 $-3203
+09-Oct-01 Budget transaction Expenses:Food $-100 $-3303
+09-Oct-01 Budget transaction Expenses:Movies $-20 $-3323
+09-Oct-01 Budget transaction Expenses:Food $-101 $-3424
+09-Oct-01 Budget transaction Expenses:Movies $-21 $-3445
+09-Oct-01 Budget transaction Expenses:Food $-102 $-3547
+09-Oct-01 Budget transaction Expenses:Movies $-22 $-3569
+09-Oct-01 Budget transaction Expenses:Food $-103 $-3672
+09-Oct-01 Budget transaction Expenses:Movies $-23 $-3695
+09-Nov-01 Budget transaction Expenses:Food $-100 $-3795
+09-Nov-01 Budget transaction Expenses:Movies $-20 $-3815
+09-Nov-01 Budget transaction Expenses:Food $-101 $-3916
+09-Nov-01 Budget transaction Expenses:Movies $-21 $-3937
+09-Nov-01 Budget transaction Expenses:Food $-102 $-4039
+09-Nov-01 Budget transaction Expenses:Movies $-22 $-4061
+09-Nov-01 Budget transaction Expenses:Food $-103 $-4164
+09-Nov-01 Budget transaction Expenses:Movies $-23 $-4187
+09-Dec-01 Budget transaction Expenses:Food $-100 $-4287
+09-Dec-01 Budget transaction Expenses:Movies $-20 $-4307
+09-Dec-01 Budget transaction Expenses:Food $-101 $-4408
+09-Dec-01 Budget transaction Expenses:Movies $-21 $-4429
+09-Dec-01 Budget transaction Expenses:Food $-102 $-4531
+09-Dec-01 Budget transaction Expenses:Movies $-22 $-4553
+09-Dec-01 Budget transaction Expenses:Food $-103 $-4656
+09-Dec-01 Budget transaction Expenses:Movies $-23 $-4679
+10-Jan-01 Budget transaction Expenses:Food $-100 $-4779
+10-Jan-01 Budget transaction Expenses:Movies $-20 $-4799
+10-Jan-01 Budget transaction Expenses:Food $-101 $-4900
+10-Jan-01 Budget transaction Expenses:Movies $-21 $-4921
+10-Feb-01 Budget transaction Expenses:Food $-100 $-5021
+10-Feb-01 Budget transaction Expenses:Movies $-20 $-5041
+10-Feb-01 Budget transaction Expenses:Food $-101 $-5142
+10-Feb-01 Budget transaction Expenses:Movies $-21 $-5163
diff --git a/test/regress/8254755E.test b/test/regress/8254755E.test
index 26baf52d..98904d6e 100644
--- a/test/regress/8254755E.test
+++ b/test/regress/8254755E.test
@@ -1,4 +1,4 @@
-bal --flat food:out
+bal --flat food:out --now=2009/12/31
<<<
~ Monthly
Expenses:Auto:Fuel $120.00
@@ -13,8 +13,8 @@ bal --flat food:out
$50.00 Expenses:Food:Out
>>>2
=== 0
-bal --flat --budget food:out
+bal --flat --budget food:out --now=2009/12/31
>>>1
- $-50.00 Expenses:Food:Out
+ $-150.00 Expenses:Food:Out
>>>2
=== 0