Balance assertions now really assert

There are two kinds of balance related options for a posting: a balance
assignment, where the amount of the posting is blank and so it fills it
in to make the assertion true; and plain assertions, where the amount is
not blank and an error is reported if the balance does not match the
given amount after the posting is taken into account.
This commit is contained in:
John Wiegley 2009-10-26 19:08:15 -04:00
parent 4f11ded5bc
commit 3fdd75fb5b

View file

@ -970,8 +970,12 @@ post_t * instance_t::parse_post(char * line,
static_cast<uint_least8_t>(expr_t::PARSE_SINGLE) |
static_cast<uint_least8_t>(expr_t::PARSE_NO_MIGRATE));
if (post->assigned_amount->is_null())
throw parse_error(_("An assigned balance must evaluate to a constant value"));
if (post->assigned_amount->is_null()) {
if (post->amount.is_null())
throw parse_error(_("Balance assignment must evaluate to a constant"));
else
throw parse_error(_("Balance assertion must evaluate to a constant"));
}
DEBUG("textual.parse", "line " << linenum << ": "
<< "POST assign: parsed amt = " << *post->assigned_amount);
@ -980,46 +984,50 @@ post_t * instance_t::parse_post(char * line,
value_t account_total(post->account->self_total(false)
.strip_annotations(keep_details_t()));
DEBUG("post.assign", "line " << linenum << ": "
"account balance = " << account_total);
DEBUG("post.assign", "line " << linenum << ": "
"post amount = " << amt);
DEBUG("post.assign",
"line " << linenum << ": " "account balance = " << account_total);
DEBUG("post.assign",
"line " << linenum << ": " "post amount = " << amt);
amount_t diff;
amount_t diff = amt;
switch (account_total.type()) {
case value_t::AMOUNT:
diff = amt - account_total.as_amount();
diff -= account_total.as_amount();
break;
case value_t::BALANCE:
if (optional<amount_t> comm_bal =
account_total.as_balance().commodity_amount(amt.commodity()))
diff = amt - *comm_bal;
else
diff = amt;
diff -= *comm_bal;
break;
default:
diff = amt;
break;
}
DEBUG("post.assign", "line " << linenum << ": "
<< "diff = " << diff);
DEBUG("textual.parse", "line " << linenum << ": "
<< "POST assign: diff = " << diff);
DEBUG("post.assign",
"line " << linenum << ": " << "diff = " << diff);
DEBUG("textual.parse",
"line " << linenum << ": " << "POST assign: diff = " << diff);
if (! diff.is_zero()) {
if (! post->amount.is_null()) {
diff -= post->amount;
if (! diff.is_zero()) {
#if 1
throw_(parse_error, _("Balance assertion off by %1") << diff);
#else
// This code, rather than issuing an error if a balance assignment
// fails, creates a balancing transaction that causes the
// assertion to be true.
post_t * temp = new post_t(post->account, diff,
ITEM_GENERATED | POST_CALCULATED);
xact->add_post(temp);
DEBUG("textual.parse", "line " << linenum << ": "
<< "Created balancing posting");
#endif
}
} else {
post->amount = diff;
@ -1033,7 +1041,7 @@ post_t * instance_t::parse_post(char * line,
else
next = skip_ws(p + static_cast<std::ptrdiff_t>(stream.tellg()));
} else {
throw parse_error(_("Expected an assigned balance amount"));
throw parse_error(_("Expected an balance assignment/assertion amount"));
}
}