summaryrefslogtreecommitdiff
path: root/src/filters.cc
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2010-06-23 19:31:06 -0400
committerJohn Wiegley <johnw@newartisans.com>2010-06-23 19:31:06 -0400
commiteda6cbd0146d371653feec70e0eb3ee4e4c56379 (patch)
treeaeb4e1ace0f9b284789f66f3ceb30bed66946b93 /src/filters.cc
parent014fde3418783d1ee1ec7fe4ea6c8b04ae7f6cd8 (diff)
parent93807fade69dd4f0ec575eda78fe1a77a85c24e3 (diff)
downloadfork-ledger-eda6cbd0146d371653feec70e0eb3ee4e4c56379.tar.gz
fork-ledger-eda6cbd0146d371653feec70e0eb3ee4e4c56379.tar.bz2
fork-ledger-eda6cbd0146d371653feec70e0eb3ee4e4c56379.zip
Merge branch 'next'
Diffstat (limited to 'src/filters.cc')
-rw-r--r--src/filters.cc120
1 files changed, 102 insertions, 18 deletions
diff --git a/src/filters.cc b/src/filters.cc
index 03baadc6..1dd410d3 100644
--- a/src/filters.cc
+++ b/src/filters.cc
@@ -266,6 +266,7 @@ void anonymize_posts::operator()(post_t& post)
copy_xact_details = true;
}
xact_t& xact = temps.last_xact();
+ xact.code = none;
if (copy_xact_details) {
xact.copy_details(*post.xact);
@@ -523,7 +524,7 @@ display_filter_posts::display_filter_posts(post_handler_ptr handler,
bool _show_rounding)
: item_handler<post_t>(handler), report(_report),
show_rounding(_show_rounding),
- rounding_account(temps.create_account(_("<Rounding>"))),
+ rounding_account(temps.create_account(_("<Adjustment>"))),
revalued_account(temps.create_account(_("<Revalued>")))
{
TRACE_CTOR(display_filter_posts,
@@ -1042,10 +1043,10 @@ void by_payee_posts::flush()
void by_payee_posts::operator()(post_t& post)
{
- payee_subtotals_map::iterator i = payee_subtotals.find(post.xact->payee);
+ payee_subtotals_map::iterator i = payee_subtotals.find(post.payee());
if (i == payee_subtotals.end()) {
payee_subtotals_pair
- temp(post.xact->payee,
+ temp(post.payee(),
shared_ptr<subtotal_posts>(new subtotal_posts(handler, amount_expr)));
std::pair<payee_subtotals_map::iterator, bool> result
= payee_subtotals.insert(temp);
@@ -1073,7 +1074,7 @@ void transfer_details::operator()(post_t& post)
if (! substitute.is_null()) {
switch (which_element) {
case SET_DATE:
- temp.xdata().date = substitute.to_date();
+ temp._date = substitute.to_date();
break;
case SET_ACCOUNT: {
@@ -1112,7 +1113,7 @@ void transfer_details::operator()(post_t& post)
item_handler<post_t>::operator()(temp);
}
-void dow_posts::flush()
+void day_of_week_posts::flush()
{
for (int i = 0; i < 7; i++) {
foreach (post_t * post, days_of_the_week[i])
@@ -1143,20 +1144,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 +1201,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);
}
@@ -1215,6 +1240,14 @@ void budget_posts::operator()(post_t& post)
}
}
+void budget_posts::flush()
+{
+ if (flags & BUDGET_BUDGETED)
+ 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);
@@ -1274,17 +1307,16 @@ void forecast_posts::flush()
least = i;
}
- date_t& begin = *(*least).first.start;
#if !defined(NO_ASSERTS)
if ((*least).first.finish)
- assert(begin < *(*least).first.finish);
+ assert(*(*least).first.start < *(*least).first.finish);
#endif
// If the next date in the series for this periodic posting is more than 5
// years beyond the last valid post we generated, drop it from further
// consideration.
- date_t next = *(*least).first.next;
- assert(next > begin);
+ date_t& next(*(*least).first.next);
+ assert(next > *(*least).first.start);
if (static_cast<std::size_t>((next - last).days()) >
static_cast<std::size_t>(365U) * forecast_years) {
@@ -1295,15 +1327,13 @@ void forecast_posts::flush()
continue;
}
- begin = next;
-
// `post' refers to the posting defined in the period transaction. We
// make a copy of it within a temporary transaction with the payee
// "Forecast transaction".
post_t& post = *(*least).second;
xact_t& xact = temps.create_xact();
xact.payee = _("Forecast transaction");
- xact._date = begin;
+ xact._date = next;
post_t& temp = temps.copy_post(post, xact);
// Submit the generated posting
@@ -1338,6 +1368,60 @@ void forecast_posts::flush()
item_handler<post_t>::flush();
}
+inject_posts::inject_posts(post_handler_ptr handler,
+ const string& tag_list,
+ account_t * master)
+ : item_handler<post_t>(handler)
+{
+ TRACE_CTOR(inject_posts, "post_handler_ptr, string");
+
+ scoped_array<char> buf(new char[tag_list.length() + 1]);
+ std::strcpy(buf.get(), tag_list.c_str());
+
+ for (char * q = std::strtok(buf.get(), ",");
+ q;
+ q = std::strtok(NULL, ",")) {
+
+ std::list<string> account_names;
+ split_string(q, ':', account_names);
+ account_t * account =
+ create_temp_account_from_path(account_names, temps, master);
+ account->add_flags(ACCOUNT_GENERATED);
+
+ tags_list.push_back
+ (tags_list_pair(q, tag_mapping_pair(account, tag_injected_set())));
+ }
+}
+
+void inject_posts::operator()(post_t& post)
+{
+ foreach (tags_list_pair& pair, tags_list) {
+ optional<value_t> tag_value = post.get_tag(pair.first, false);
+ if (! tag_value &&
+ pair.second.second.find(post.xact) == pair.second.second.end()) {
+ // When checking if the transaction has the tag, only inject once
+ // per transaction.
+ pair.second.second.insert(post.xact);
+ tag_value = post.xact->get_tag(pair.first);
+ }
+
+ if (tag_value) {
+ xact_t& xact = temps.copy_xact(*post.xact);
+ xact._date = post.date();
+ xact.add_flags(ITEM_GENERATED);
+ post_t& temp = temps.copy_post(post, xact);
+
+ temp.account = pair.second.first;
+ temp.amount = tag_value->to_amount();
+ temp.add_flags(ITEM_GENERATED);
+
+ item_handler<post_t>::operator()(temp);
+ }
+ }
+
+ item_handler<post_t>::operator()(post);
+}
+
pass_down_accounts::pass_down_accounts(acct_handler_ptr handler,
accounts_iterator& iter,
const optional<predicate_t>& _pred,