diff options
author | John Wiegley <johnw@newartisans.com> | 2009-10-31 04:17:40 -0400 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2009-10-31 04:17:40 -0400 |
commit | 97a9b42b2c5ef908e0c47ecfd39771a79f8fa8a2 (patch) | |
tree | 8eadb82cc54e66353e05309fe42c2900b93628bf /src/derive.cc | |
parent | a2cb549b1dff9024e3f700203e424e496b25fd91 (diff) | |
parent | a0a980b9f4ebf1493682ecf1eb745bf52649aac5 (diff) | |
download | fork-ledger-97a9b42b2c5ef908e0c47ecfd39771a79f8fa8a2.tar.gz fork-ledger-97a9b42b2c5ef908e0c47ecfd39771a79f8fa8a2.tar.bz2 fork-ledger-97a9b42b2c5ef908e0c47ecfd39771a79f8fa8a2.zip |
Merge branch 'next'
Diffstat (limited to 'src/derive.cc')
-rw-r--r-- | src/derive.cc | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/derive.cc b/src/derive.cc index ef2d1e51..df27d4b6 100644 --- a/src/derive.cc +++ b/src/derive.cc @@ -54,6 +54,8 @@ namespace { bool from; optional<mask_t> account_mask; optional<amount_t> amount; + optional<string> cost_operator; + optional<amount_t> cost; post_template_t() : from(false) {} }; @@ -111,6 +113,10 @@ namespace { if (post.amount) out << _(" Amount: ") << *post.amount << std::endl; + + if (post.cost) + out << _(" Cost: ") << *post.cost_operator + << " " << *post.cost << std::endl; } } } @@ -148,6 +154,8 @@ namespace { string arg = (*begin).to_string(); if (arg == "at") { + if (begin == end) + throw std::runtime_error(_("Invalid xact command arguments")); tmpl.payee_mask = (*++begin).to_string(); } else if (arg == "to" || arg == "from") { @@ -155,22 +163,41 @@ namespace { tmpl.posts.push_back(xact_template_t::post_template_t()); post = &tmpl.posts.back(); } + if (begin == end) + throw std::runtime_error(_("Invalid xact command arguments")); post->account_mask = mask_t((*++begin).to_string()); post->from = arg == "from"; } else if (arg == "on") { + if (begin == end) + throw std::runtime_error(_("Invalid xact command arguments")); tmpl.date = parse_date((*++begin).to_string()); check_for_date = false; } else if (arg == "code") { + if (begin == end) + throw std::runtime_error(_("Invalid xact command arguments")); tmpl.code = (*++begin).to_string(); } else if (arg == "note") { + if (begin == end) + throw std::runtime_error(_("Invalid xact command arguments")); tmpl.note = (*++begin).to_string(); } else if (arg == "rest") { ; // just ignore this argument } + else if (arg == "@" || arg == "@@") { + amount_t cost; + post->cost_operator = arg; + if (begin == end) + throw std::runtime_error(_("Invalid xact command arguments")); + arg = (*++begin).to_string(); + if (! cost.parse(arg, amount_t::PARSE_SOFT_FAIL | + amount_t::PARSE_NO_MIGRATE)) + throw std::runtime_error(_("Invalid xact command arguments")); + post->cost = cost; + } else { // Without a preposition, it is either: // @@ -443,6 +470,25 @@ namespace { } } + if (post.cost) { + if (post.cost->sign() < 0) + throw parse_error(_("A posting's cost may not be negative")); + + post.cost->in_place_unround(); + + if (*post.cost_operator == "@") { + // For the sole case where the cost might be uncommoditized, + // guarantee that the commodity of the cost after multiplication + // is the same as it was before. + commodity_t& cost_commodity(post.cost->commodity()); + *post.cost *= new_post->amount; + post.cost->set_commodity(cost_commodity); + } + + new_post->cost = *post.cost; + DEBUG("derive.xact", "Copied over posting cost"); + } + if (found_commodity && ! new_post->amount.is_null() && ! new_post->amount.has_commodity()) { |