summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/chain.cc4
-rw-r--r--src/filters.cc45
-rw-r--r--src/filters.h10
3 files changed, 48 insertions, 11 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);
};