From d98a13da0654d1dfce31d638678efd8504320ba8 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 22 Aug 2005 08:45:25 +0000 Subject: [PATCH] (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. --- journal.cc | 39 +++++++++++++++++++++------------------ 1 file 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.