diff options
Diffstat (limited to 'src/derive.cc')
-rw-r--r-- | src/derive.cc | 212 |
1 files changed, 107 insertions, 105 deletions
diff --git a/src/derive.cc b/src/derive.cc index 8ea07c87..f6b594e0 100644 --- a/src/derive.cc +++ b/src/derive.cc @@ -35,7 +35,7 @@ namespace ledger { namespace { - struct entry_template_t + struct xact_template_t { optional<date_t> date; optional<date_t> eff_date; @@ -43,17 +43,17 @@ namespace { optional<string> note; mask_t payee_mask; - struct xact_template_t { + struct post_template_t { bool from; optional<mask_t> account_mask; optional<amount_t> amount; - xact_template_t() : from(false) {} + post_template_t() : from(false) {} }; - std::list<xact_template_t> xacts; + std::list<post_template_t> posts; - entry_template_t() {} + xact_template_t() {} void dump(std::ostream& out) const { @@ -76,52 +76,52 @@ namespace { else out << "Payee mask: " << payee_mask << std::endl; - if (xacts.empty()) { + if (posts.empty()) { out << std::endl - << "<Transaction copied from last related entry>" + << "<Posting copied from last related transaction>" << std::endl; } else { bool has_only_from = true; bool has_only_to = true; - foreach (const xact_template_t& xact, xacts) { - if (xact.from) + foreach (const post_template_t& post, posts) { + if (post.from) has_only_to = false; else has_only_from = false; } - foreach (const xact_template_t& xact, xacts) { + foreach (const post_template_t& post, posts) { out << std::endl - << "[Transaction \"" << (xact.from ? "from" : "to") + << "[Posting \"" << (post.from ? "from" : "to") << "\"]" << std::endl; - if (xact.account_mask) - out << " Account mask: " << *xact.account_mask << std::endl; - else if (xact.from) + if (post.account_mask) + out << " Account mask: " << *post.account_mask << std::endl; + else if (post.from) out << " Account mask: <use last of last related accounts>" << std::endl; else out << " Account mask: <use first of last related accounts>" << std::endl; - if (xact.amount) - out << " Amount: " << *xact.amount << std::endl; + if (post.amount) + out << " Amount: " << *post.amount << std::endl; } } } }; - entry_template_t - args_to_entry_template(value_t::sequence_t::const_iterator begin, + xact_template_t + args_to_xact_template(value_t::sequence_t::const_iterator begin, value_t::sequence_t::const_iterator end) { regex date_mask("([0-9]+(?:[-/.][0-9]+)?(?:[-/.][0-9]+))?(?:=.*)?"); regex dow_mask("(sun|mon|tue|wed|thu|fri|sat)"); smatch what; - entry_template_t tmpl; + xact_template_t tmpl; bool check_for_date = true; - entry_template_t::xact_template_t * xact = NULL; + xact_template_t::post_template_t * post = NULL; for (; begin != end; begin++) { if (check_for_date && @@ -147,12 +147,12 @@ namespace { tmpl.payee_mask = (*++begin).to_string(); } else if (arg == "to" || arg == "from") { - if (! xact || xact->account_mask) { - tmpl.xacts.push_back(entry_template_t::xact_template_t()); - xact = &tmpl.xacts.back(); + if (! post || post->account_mask) { + tmpl.posts.push_back(xact_template_t::post_template_t()); + post = &tmpl.posts.back(); } - xact->account_mask = mask_t((*++begin).to_string()); - xact->from = arg == "from"; + post->account_mask = mask_t((*++begin).to_string()); + post->from = arg == "from"; } else if (arg == "on") { tmpl.date = parse_date((*++begin).to_string()); @@ -186,62 +186,62 @@ namespace { amount_t::PARSE_NO_MIGRATE)) account = mask_t(arg); - if (! xact || - (account && xact->account_mask) || - (! account && xact->amount)) { - tmpl.xacts.push_back(entry_template_t::xact_template_t()); - xact = &tmpl.xacts.back(); + if (! post || + (account && post->account_mask) || + (! account && post->amount)) { + tmpl.posts.push_back(xact_template_t::post_template_t()); + post = &tmpl.posts.back(); } if (account) { - xact->from = false; - xact->account_mask = account; + post->from = false; + post->account_mask = account; } else { - xact->amount = amt; + post->amount = amt; } } } } } - if (! tmpl.xacts.empty()) { + if (! tmpl.posts.empty()) { bool has_only_from = true; bool has_only_to = true; - foreach (entry_template_t::xact_template_t& xact, tmpl.xacts) { - if (xact.from) + foreach (xact_template_t::post_template_t& post, tmpl.posts) { + if (post.from) has_only_to = false; else has_only_from = false; } if (has_only_from) { - tmpl.xacts.push_front(entry_template_t::xact_template_t()); + tmpl.posts.push_front(xact_template_t::post_template_t()); } else if (has_only_to) { - tmpl.xacts.push_back(entry_template_t::xact_template_t()); - tmpl.xacts.back().from = true; + tmpl.posts.push_back(xact_template_t::post_template_t()); + tmpl.posts.back().from = true; } } return tmpl; } - entry_t * derive_entry_from_template(entry_template_t& tmpl, + xact_t * derive_xact_from_template(xact_template_t& tmpl, report_t& report) { if (tmpl.payee_mask.empty()) - throw std::runtime_error("'entry' command requires at least a payee"); + throw std::runtime_error("'xact' command requires at least a payee"); - entry_t * matching = NULL; + xact_t * matching = NULL; journal_t& journal(*report.session.journal.get()); - std::auto_ptr<entry_t> added(new entry_t); + std::auto_ptr<xact_t> added(new xact_t); - entries_list::reverse_iterator j; + xacts_list::reverse_iterator j; - for (j = journal.entries.rbegin(); - j != journal.entries.rend(); + for (j = journal.xacts.rbegin(); + j != journal.xacts.rend(); j++) { if (tmpl.payee_mask.match((*j)->payee)) { matching = *j; @@ -270,112 +270,114 @@ namespace { if (tmpl.note) added->note = tmpl.note; - if (tmpl.xacts.empty()) { + if (tmpl.posts.empty()) { if (matching) { - foreach (xact_t * xact, matching->xacts) - added->add_xact(new xact_t(*xact)); + foreach (post_t * post, matching->posts) + added->add_post(new post_t(*post)); } else { throw_(std::runtime_error, - "No accounts, and no past entry matching '" << tmpl.payee_mask <<"'"); + "No accounts, and no past transaction matching '" + << tmpl.payee_mask <<"'"); } } else { - bool any_xact_has_amount = false; - foreach (entry_template_t::xact_template_t& xact, tmpl.xacts) { - if (xact.amount) { - any_xact_has_amount = true; + bool any_post_has_amount = false; + foreach (xact_template_t::post_template_t& post, tmpl.posts) { + if (post.amount) { + any_post_has_amount = true; break; } } - foreach (entry_template_t::xact_template_t& xact, tmpl.xacts) { - std::auto_ptr<xact_t> new_xact; + foreach (xact_template_t::post_template_t& post, tmpl.posts) { + std::auto_ptr<post_t> new_post; commodity_t * found_commodity = NULL; if (matching) { - if (xact.account_mask) { - foreach (xact_t * x, matching->xacts) { - if (xact.account_mask->match(x->account->fullname())) { - new_xact.reset(new xact_t(*x)); + if (post.account_mask) { + foreach (post_t * x, matching->posts) { + if (post.account_mask->match(x->account->fullname())) { + new_post.reset(new post_t(*x)); break; } } } else { - if (xact.from) - new_xact.reset(new xact_t(*matching->xacts.back())); + if (post.from) + new_post.reset(new post_t(*matching->posts.back())); else - new_xact.reset(new xact_t(*matching->xacts.front())); + new_post.reset(new post_t(*matching->posts.front())); } } - if (! new_xact.get()) - new_xact.reset(new xact_t); + if (! new_post.get()) + new_post.reset(new post_t); - if (! new_xact->account) { - if (xact.account_mask) { + if (! new_post->account) { + if (post.account_mask) { account_t * acct = NULL; if (! acct) - acct = journal.find_account_re(xact.account_mask->expr.str()); + acct = journal.find_account_re(post.account_mask->expr.str()); if (! acct) - acct = journal.find_account(xact.account_mask->expr.str()); + acct = journal.find_account(post.account_mask->expr.str()); // Find out the default commodity to use by looking at the last // commodity used in that account - entries_list::reverse_iterator j; + xacts_list::reverse_iterator j; - for (j = journal.entries.rbegin(); - j != journal.entries.rend(); + for (j = journal.xacts.rbegin(); + j != journal.xacts.rend(); j++) { - foreach (xact_t * x, (*j)->xacts) { + foreach (post_t * x, (*j)->posts) { if (x->account == acct && ! x->amount.is_null()) { - new_xact.reset(new xact_t(*x)); + new_post.reset(new post_t(*x)); break; } } } - if (! new_xact.get()) - new_xact.reset(new xact_t); + if (! new_post.get()) + new_post.reset(new post_t); - new_xact->account = acct; + new_post->account = acct; } else { - if (xact.from) - new_xact->account = journal.find_account("Liabilities:Unknown"); + if (post.from) + new_post->account = journal.find_account("Liabilities:Unknown"); else - new_xact->account = journal.find_account("Expenses:Unknown"); + new_post->account = journal.find_account("Expenses:Unknown"); } } - if (new_xact.get() && ! new_xact->amount.is_null()) { - found_commodity = &new_xact->amount.commodity(); + if (new_post.get() && ! new_post->amount.is_null()) { + found_commodity = &new_post->amount.commodity(); - if (any_xact_has_amount) - new_xact->amount = amount_t(); + if (any_post_has_amount) + new_post->amount = amount_t(); else - any_xact_has_amount = true; + any_post_has_amount = true; } - if (xact.amount) { - new_xact->amount = *xact.amount; - if (xact.from) - new_xact->amount.in_place_negate(); + if (post.amount) { + new_post->amount = *post.amount; + if (post.from) + new_post->amount.in_place_negate(); } if (found_commodity && - ! new_xact->amount.is_null() && - ! new_xact->amount.has_commodity()) { - new_xact->amount.set_commodity(*found_commodity); - new_xact->amount = new_xact->amount.rounded(); + ! new_post->amount.is_null() && + ! new_post->amount.has_commodity()) { + new_post->amount.set_commodity(*found_commodity); + new_post->amount = new_post->amount.rounded(); } - added->add_xact(new_xact.release()); + added->add_post(new_post.release()); } } - if (! journal.entry_finalize_hooks.run_hooks(*added.get(), false) || + if (! journal.xact_finalize_hooks.run_hooks(*added.get(), false) || ! added->finalize() || - ! journal.entry_finalize_hooks.run_hooks(*added.get(), true)) - throw std::runtime_error("Failed to finalize derived entry (check commodities)"); + ! journal.xact_finalize_hooks.run_hooks(*added.get(), true)) + throw_(std::runtime_error, + "Failed to finalize derived transaction (check commodities)"); return added.release(); } @@ -393,27 +395,27 @@ value_t template_command(call_scope_t& args) args.value().dump(out); out << std::endl << std::endl; - entry_template_t tmpl = args_to_entry_template(begin, end); + xact_template_t tmpl = args_to_xact_template(begin, end); - out << "--- Entry template ---" << std::endl; + out << "--- Transaction template ---" << std::endl; tmpl.dump(out); return true; } -value_t entry_command(call_scope_t& args) +value_t xact_command(call_scope_t& args) { value_t::sequence_t::const_iterator begin = args.value().begin(); value_t::sequence_t::const_iterator end = args.value().end(); report_t& report(find_scope<report_t>(args)); - entry_template_t tmpl = args_to_entry_template(begin, end); - std::auto_ptr<entry_t> new_entry(derive_entry_from_template(tmpl, report)); + xact_template_t tmpl = args_to_xact_template(begin, end); + std::auto_ptr<xact_t> new_xact(derive_xact_from_template(tmpl, report)); - report.entry_report(xact_handler_ptr - (new format_xacts(report, + report.xact_report(post_handler_ptr + (new format_posts(report, report.HANDLER(print_format_).str())), - *new_entry.get()); + *new_xact.get()); return true; } |