Fixed an issue involving costs and reduced values
This commit is contained in:
parent
d525db35d8
commit
38dd1b8655
3 changed files with 91 additions and 64 deletions
|
|
@ -828,9 +828,10 @@ post_t * instance_t::parse_post(char * line,
|
||||||
ptristream stream(next, len - beg);
|
ptristream stream(next, len - beg);
|
||||||
|
|
||||||
if (*next != '(') // indicates a value expression
|
if (*next != '(') // indicates a value expression
|
||||||
post->amount.parse(stream);
|
post->amount.parse(stream, amount_t::PARSE_NO_REDUCE);
|
||||||
else
|
else
|
||||||
parse_amount_expr(session_scope, stream, post->amount, post.get(),
|
parse_amount_expr(session_scope, stream, post->amount, post.get(),
|
||||||
|
static_cast<uint_least8_t>(expr_t::PARSE_NO_REDUCE) |
|
||||||
static_cast<uint_least8_t>(expr_t::PARSE_NO_ASSIGN));
|
static_cast<uint_least8_t>(expr_t::PARSE_NO_ASSIGN));
|
||||||
|
|
||||||
if (! post->amount.is_null() && honor_strict && strict &&
|
if (! post->amount.is_null() && honor_strict && strict &&
|
||||||
|
|
|
||||||
38
src/xact.cc
38
src/xact.cc
|
|
@ -89,9 +89,11 @@ bool xact_base_t::finalize()
|
||||||
post_t * null_post = NULL;
|
post_t * null_post = NULL;
|
||||||
|
|
||||||
foreach (post_t * post, posts) {
|
foreach (post_t * post, posts) {
|
||||||
if (post->must_balance()) {
|
if (! post->must_balance())
|
||||||
|
continue;
|
||||||
|
|
||||||
amount_t& p(post->cost ? *post->cost : post->amount);
|
amount_t& p(post->cost ? *post->cost : post->amount);
|
||||||
DEBUG("xact.finalize", "post must balance = " << p);
|
DEBUG("xact.finalize", "post must balance = " << p.reduced());
|
||||||
if (! p.is_null()) {
|
if (! p.is_null()) {
|
||||||
if (! post->cost && post->amount.is_annotated() &&
|
if (! post->cost && post->amount.is_annotated() &&
|
||||||
post->amount.annotation().price) {
|
post->amount.annotation().price) {
|
||||||
|
|
@ -103,22 +105,23 @@ bool xact_base_t::finalize()
|
||||||
DEBUG("xact.finalize", "amount = " << post->amount);
|
DEBUG("xact.finalize", "amount = " << post->amount);
|
||||||
DEBUG("xact.finalize", "priced cost = " << *post->cost);
|
DEBUG("xact.finalize", "priced cost = " << *post->cost);
|
||||||
post->add_flags(POST_PRICED);
|
post->add_flags(POST_PRICED);
|
||||||
add_or_set_value(balance, post->cost->rounded());
|
add_or_set_value(balance, post->cost->rounded().reduced());
|
||||||
} else {
|
} else {
|
||||||
// If the amount was a cost, it very likely has the "keep_precision"
|
// If the amount was a cost, it very likely has the "keep_precision"
|
||||||
// flag set, meaning commodity display precision is ignored when
|
// flag set, meaning commodity display precision is ignored when
|
||||||
// displaying the amount. We never want this set for the balance,
|
// displaying the amount. We never want this set for the balance,
|
||||||
// so we must clear the flag in a temporary to avoid it propagating
|
// so we must clear the flag in a temporary to avoid it propagating
|
||||||
// into the balance.
|
// into the balance.
|
||||||
add_or_set_value(balance, p.keep_precision() ? p.rounded() : p);
|
add_or_set_value(balance, p.keep_precision() ?
|
||||||
|
p.rounded().reduced() : p.reduced());
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
if (null_post)
|
else if (null_post) {
|
||||||
throw_(std::logic_error,
|
throw_(std::logic_error,
|
||||||
"Only one posting with null amount allowed per transaction");
|
_("Only one posting with null amount allowed per transaction"));
|
||||||
else
|
|
||||||
null_post = post;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
null_post = post;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(balance.valid());
|
assert(balance.valid());
|
||||||
|
|
@ -213,6 +216,7 @@ bool xact_base_t::finalize()
|
||||||
y = t;
|
y = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*x && *y) {
|
||||||
DEBUG("xact.finalize", "primary amount = " << *x);
|
DEBUG("xact.finalize", "primary amount = " << *x);
|
||||||
DEBUG("xact.finalize", "secondary amount = " << *y);
|
DEBUG("xact.finalize", "secondary amount = " << *y);
|
||||||
|
|
||||||
|
|
@ -253,6 +257,7 @@ bool xact_base_t::finalize()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Now that the post list has its final form, calculate the balance once
|
// Now that the post list has its final form, calculate the balance once
|
||||||
// more in terms of total cost, accounting for any possible gain/loss
|
// more in terms of total cost, accounting for any possible gain/loss
|
||||||
|
|
@ -279,7 +284,7 @@ bool xact_base_t::finalize()
|
||||||
breakdown.final_cost).rounded()) {
|
breakdown.final_cost).rounded()) {
|
||||||
DEBUG("xact.finalize", "gain_loss = " << gain_loss);
|
DEBUG("xact.finalize", "gain_loss = " << gain_loss);
|
||||||
|
|
||||||
add_or_set_value(balance, gain_loss);
|
add_or_set_value(balance, gain_loss.reduced());
|
||||||
|
|
||||||
account_t * account;
|
account_t * account;
|
||||||
if (gain_loss.sign() > 0)
|
if (gain_loss.sign() > 0)
|
||||||
|
|
@ -309,21 +314,27 @@ bool xact_base_t::finalize()
|
||||||
|
|
||||||
if (dynamic_cast<xact_t *>(this)) {
|
if (dynamic_cast<xact_t *>(this)) {
|
||||||
bool all_null = true;
|
bool all_null = true;
|
||||||
|
bool some_null = false;
|
||||||
foreach (post_t * post, posts) {
|
foreach (post_t * post, posts) {
|
||||||
if (! post->amount.is_null()) {
|
if (! post->amount.is_null()) {
|
||||||
all_null = false;
|
all_null = false;
|
||||||
|
|
||||||
// jww (2008-08-09): For now, this feature only works for non-specific
|
post->amount.in_place_reduce();
|
||||||
// commodities.
|
|
||||||
add_or_set_value(post->account->xdata().value, post->amount);
|
add_or_set_value(post->account->xdata().value, post->amount);
|
||||||
|
|
||||||
DEBUG("xact.finalize.totals",
|
DEBUG("xact.finalize.totals",
|
||||||
"Total for " << post->account->fullname() << " + "
|
"Total for " << post->account->fullname() << " + "
|
||||||
<< post->amount << ": " << post->account->xdata().value);
|
<< post->amount << ": " << post->account->xdata().value);
|
||||||
|
} else {
|
||||||
|
some_null = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (all_null)
|
if (all_null)
|
||||||
return false; // ignore this xact completely
|
return false; // ignore this xact completely
|
||||||
|
else if (some_null)
|
||||||
|
throw_(balance_error,
|
||||||
|
"There cannot be null amounts after balancing a transaction");
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -403,9 +414,8 @@ void auto_xact_t::extend_xact(xact_base_t& xact, bool post_handler)
|
||||||
amount_t amt;
|
amount_t amt;
|
||||||
assert(post->amount);
|
assert(post->amount);
|
||||||
if (! post->amount.commodity()) {
|
if (! post->amount.commodity()) {
|
||||||
if (post_handler)
|
if (post_handler || initial_post->amount.is_null())
|
||||||
continue;
|
continue;
|
||||||
assert(initial_post->amount);
|
|
||||||
amt = initial_post->amount * post->amount;
|
amt = initial_post->amount * post->amount;
|
||||||
} else {
|
} else {
|
||||||
if (post_handler)
|
if (post_handler)
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,26 @@ i 2007/03/01 23:00:00 A
|
||||||
o 2007/03/02 01:00:00
|
o 2007/03/02 01:00:00
|
||||||
i 2007/03/11 23:00:00 B
|
i 2007/03/11 23:00:00 B
|
||||||
o 2007/03/12 01:00:00
|
o 2007/03/12 01:00:00
|
||||||
|
|
||||||
|
2006/05/22 * Company
|
||||||
|
Assets:Receivable $4,000.00
|
||||||
|
Income:Contracts -40h @ $100.00
|
||||||
|
|
||||||
|
2006/05/22 * Company
|
||||||
|
Assets:Receivable $4,000.00
|
||||||
|
Income:Contracts -40h {$20} @ $100.00
|
||||||
|
Income:Gains $-3,200.00
|
||||||
>>>1
|
>>>1
|
||||||
7200s A
|
7200s A
|
||||||
|
$8,000.00 Assets:Receivable
|
||||||
7200s B
|
7200s B
|
||||||
|
$3,200.00 Equity:Capital Gains
|
||||||
|
$-3,200.00
|
||||||
|
-288000s Income
|
||||||
|
-288000s Contracts
|
||||||
|
$-3,200.00 Gains
|
||||||
--------------------
|
--------------------
|
||||||
14400s
|
$8,000.00
|
||||||
|
-273600s
|
||||||
>>>2
|
>>>2
|
||||||
=== 0
|
=== 0
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue