summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2005-08-22 08:45:25 +0000
committerJohn Wiegley <johnw@newartisans.com>2008-04-13 02:41:17 -0400
commitd98a13da0654d1dfce31d638678efd8504320ba8 (patch)
tree8e71b2ebaa3e8fd5031a8b8a00e9350a48d48446
parent98895eb1cfb231846537c1d2cf7f8b5e804fdecf (diff)
downloadledger-d98a13da0654d1dfce31d638678efd8504320ba8.tar.gz
ledger-d98a13da0654d1dfce31d638678efd8504320ba8.tar.bz2
ledger-d98a13da0654d1dfce31d638678efd8504320ba8.zip
(finalize): Improved the logic which auto-computes per unit cost for
self-balancing transactions of two different commodity types. Now it doesn't matter how many transactions of each commodity there are, only that only two commodities are involved. Whichever commodity type is used first is the one divided into.
-rw-r--r--journal.cc39
1 files changed, 21 insertions, 18 deletions
diff --git a/journal.cc b/journal.cc
index e43a1115..298755d2 100644
--- a/journal.cc
+++ b/journal.cc
@@ -99,28 +99,31 @@ bool entry_base_t::finalize()
// the balance. This is done for the last eligible commodity.
if (balance && balance.type == value_t::BALANCE &&
- ((balance_t *) balance.data)->amounts.size() == 2)
- for (transactions_list::const_iterator x = transactions.begin();
- x != transactions.end();
- x++) {
- if ((*x)->cost || ((*x)->flags & TRANSACTION_VIRTUAL))
+ ((balance_t *) balance.data)->amounts.size() == 2) {
+ transactions_list::const_iterator x = transactions.begin();
+ commodity_t& this_comm = (*x)->amount.commodity();
+
+ amounts_map::const_iterator this_bal =
+ ((balance_t *) balance.data)->amounts.find(&this_comm);
+ amounts_map::const_iterator other_bal =
+ ((balance_t *) balance.data)->amounts.begin();
+ if (this_bal == other_bal)
+ other_bal++;
+
+ amount_t per_unit_cost = (*other_bal).second / (*this_bal).second;
+
+ for (; x != transactions.end(); x++) {
+ if ((*x)->cost || ((*x)->flags & TRANSACTION_VIRTUAL) ||
+ (*x)->amount.commodity() != this_comm)
continue;
- for (amounts_map::const_iterator i
- = ((balance_t *) balance.data)->amounts.begin();
- i != ((balance_t *) balance.data)->amounts.end();
- i++)
- if ((*i).second.commodity() != (*x)->amount.commodity()) {
- assert((*x)->amount);
- balance -= (*x)->amount;
- assert(! (*x)->cost);
- (*x)->cost = new amount_t(- (*i).second);
- balance += *(*x)->cost;
- break;
- }
+ assert((*x)->amount);
- break;
+ balance -= (*x)->amount;
+ (*x)->cost = new amount_t(- (per_unit_cost * (*x)->amount));
+ balance += *(*x)->cost;
}
+ }
// Walk through each of the transactions, fixing up any that we
// can, and performing any on-the-fly calculations.