diff options
author | John Wiegley <johnw@newartisans.com> | 2010-06-18 02:26:50 -0400 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2010-06-18 02:28:12 -0400 |
commit | 5da1e7756d2a4eb04753b8a97bc00063b4d3f687 (patch) | |
tree | 66798448f6a0cde13b434a28465c734d39a7a6cd /src/filters.cc | |
parent | 7e2547b1e4c5b6e940506ddff80e8871ada029ea (diff) | |
download | fork-ledger-5da1e7756d2a4eb04753b8a97bc00063b4d3f687.tar.gz fork-ledger-5da1e7756d2a4eb04753b8a97bc00063b4d3f687.tar.bz2 fork-ledger-5da1e7756d2a4eb04753b8a97bc00063b4d3f687.zip |
Added new option --inject=KEY[,KEY...]
If you have a typed metadata key which contains an amount, you can use
--inject=KEY to inject a posting with that amount wherever a match
occurs. There are two main forms of usage:
2010-06-18 Sample
; Key:: $100
Expenses:Food $100.00
Assets:Checking
The command would be:
ledger reg --inject=Key
In the above, transactional form, a posting under the account "Key" will
be injected before the first posting reported for this transaction.
It's amount will be $100. This only happens once for the whole
transaction.
It is also possible to associate the key with a posting:
2010-06-18 Sample
Expenses:Food $100.00
; Key:: $100
Assets:Checking
Now the injected posting is generated whenever that particular post is
reported.
Diffstat (limited to 'src/filters.cc')
-rw-r--r-- | src/filters.cc | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/src/filters.cc b/src/filters.cc index 6e832149..33905856 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -1338,6 +1338,66 @@ 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) { + if (tag_value->is_amount()) { + 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->as_amount(); + temp.add_flags(ITEM_GENERATED); + + item_handler<post_t>::operator()(temp); + } else { + throw_(std::logic_error, + _("Attempt to inject a posting with non-amount %1 for tag %2") + << *tag_value << pair.first); + } + } + } + + item_handler<post_t>::operator()(post); +} + pass_down_accounts::pass_down_accounts(acct_handler_ptr handler, accounts_iterator& iter, const optional<predicate_t>& _pred, |