diff options
author | John Wiegley <johnw@newartisans.com> | 2010-03-05 22:12:32 -0500 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2010-03-05 22:14:14 -0500 |
commit | 33187220891dd8826ff4d5a53b724b0058f6fef9 (patch) | |
tree | 79328965f8c183d92267ca46585d4640f72eb982 | |
parent | dc1b3907207cc5ccf3d27a01aa877e841bf7ac6f (diff) | |
download | fork-ledger-33187220891dd8826ff4d5a53b724b0058f6fef9.tar.gz fork-ledger-33187220891dd8826ff4d5a53b724b0058f6fef9.tar.bz2 fork-ledger-33187220891dd8826ff4d5a53b724b0058f6fef9.zip |
Added new "payee" and "capture" directives
The payee directive allows for transformation of payee names during the
parsing of a Ledger file. This means you can record the payee name in
one form, but always have it reported in another form. The syntax is
(and will be):
payee PAYEE_NAME REGEXP
or
payee PAYEE_NAME
REGEXP1
REGEXP2
...
The account directive sets the account automatically based on the payee
iff the base account name is Unknown. For example, if you have a bunch
of transaction in Expenses:Unknown, you can assign accounts for several
automatically using:
account ACCOUNT_NAME PAYEE_REGEXP
or
account ACCOUNT_NAME
PAYEE_REGEXP1
PAYEE_REGEXP2
...
-rw-r--r-- | src/journal.h | 8 | ||||
-rw-r--r-- | src/mask.h | 3 | ||||
-rw-r--r-- | src/textual.cc | 52 |
3 files changed, 62 insertions, 1 deletions
diff --git a/src/journal.h b/src/journal.h index 2711c3b5..e54814aa 100644 --- a/src/journal.h +++ b/src/journal.h @@ -44,6 +44,7 @@ #include "utils.h" #include "times.h" +#include "mask.h" namespace ledger { @@ -58,6 +59,11 @@ typedef std::list<xact_t *> xacts_list; typedef std::list<auto_xact_t *> auto_xacts_list; typedef std::list<period_xact_t *> period_xacts_list; +typedef std::pair<mask_t, string> payee_mapping_t; +typedef std::list<payee_mapping_t> payee_mappings_t; +typedef std::pair<mask_t, account_t *> account_mapping_t; +typedef std::list<account_mapping_t> account_mappings_t; + class journal_t : public noncopyable { public: @@ -110,6 +116,8 @@ public: period_xacts_list period_xacts; std::list<fileinfo_t> sources; bool was_loaded; + payee_mappings_t payee_mappings; + account_mappings_t account_mappings; journal_t(); journal_t(const path& pathname); @@ -74,6 +74,9 @@ public: mask_t& operator=(const string& other); + bool operator<(const mask_t& other) const { + return expr < other.expr; + } bool operator==(const mask_t& other) const { return expr == other.expr; } diff --git a/src/textual.cc b/src/textual.cc index 9ad70c60..764d15e8 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -144,6 +144,8 @@ namespace { void end_directive(char * line); void alias_directive(char * line); void fixed_directive(char * line); + void payee_mapping_directive(char * line); + void account_mapping_directive(char * line); void tag_directive(char * line); void define_directive(char * line); bool general_directive(char * line); @@ -735,6 +737,24 @@ void instance_t::fixed_directive(char * line) } } +void instance_t::payee_mapping_directive(char * line) +{ + char * payee = skip_ws(line); + char * regex = next_element(payee, true); + + context.journal.payee_mappings.push_back(payee_mapping_t(mask_t(regex), payee)); +} + +void instance_t::account_mapping_directive(char * line) +{ + char * account_name = skip_ws(line); + char * payee_regex = next_element(account_name, true); + + context.journal.account_mappings.push_back + (account_mapping_t(mask_t(payee_regex), + context.top_account()->find_account(account_name))); +} + void instance_t::tag_directive(char * line) { string tag(trim_ws(line)); @@ -782,6 +802,13 @@ bool instance_t::general_directive(char * line) } break; + case 'c': + if (std::strcmp(p, "capture") == 0) { + account_mapping_directive(arg); + return true; + } + break; + case 'd': if (std::strcmp(p, "def") == 0 || std::strcmp(p, "define") == 0) { define_directive(arg); @@ -810,6 +837,13 @@ bool instance_t::general_directive(char * line) } break; + case 'p': + if (std::strcmp(p, "payee") == 0) { + payee_mapping_directive(arg); + return true; + } + break; + case 't': if (std::strcmp(p, "tag") == 0) { tag_directive(arg); @@ -929,6 +963,15 @@ post_t * instance_t::parse_post(char * line, post->account->add_flags(ACCOUNT_KNOWN); } + if (post->account->name == _("Unknown")) { + foreach (account_mapping_t& value, context.journal.account_mappings) { + if (value.first.match(xact->payee)) { + post->account = value.second; + break; + } + } + } + // Parse the optional amount bool saw_amount = false; @@ -1242,7 +1285,14 @@ xact_t * instance_t::parse_xact(char * line, if (next && *next) { char * p = next_element(next, true); - xact->payee = next; + foreach (payee_mapping_t& value, context.journal.payee_mappings) { + if (value.first.match(next)) { + xact->payee = value.second; + break; + } + } + if (xact->payee.empty()) + xact->payee = next; next = p; } else { xact->payee = _("<Unspecified payee>"); |