More work on fixing split problems and rebalancing.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3219 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Dave Peticolas 2000-12-01 07:59:57 +00:00
parent 88bdc41cd8
commit 335e018b60
5 changed files with 113 additions and 69 deletions

View File

@ -3018,8 +3018,8 @@ xaccSRSaveChangedCells (SplitRegister *reg, Transaction *trans, Split *split)
if (MOD_SHRS & changed) if (MOD_SHRS & changed)
{ {
gnc_numeric amount = xaccGetPriceCellValue(reg->sharesCell); gnc_numeric amount = xaccGetPriceCellValue (reg->sharesCell);
gnc_numeric price = xaccGetPriceCellValue(reg->priceCell); gnc_numeric price = xaccGetPriceCellValue (reg->priceCell);
DEBUG ("MOD_SHRS"); DEBUG ("MOD_SHRS");
@ -3031,7 +3031,7 @@ xaccSRSaveChangedCells (SplitRegister *reg, Transaction *trans, Split *split)
{ {
gnc_numeric price; gnc_numeric price;
price = xaccGetPriceCellValue(reg->priceCell); price = xaccGetPriceCellValue (reg->priceCell);
DEBUG ("MOD_PRIC"); DEBUG ("MOD_PRIC");
@ -3055,7 +3055,7 @@ xaccSRSaveChangedCells (SplitRegister *reg, Transaction *trans, Split *split)
if ((MOD_AMNT | MOD_PRIC | MOD_SHRS) & changed) if ((MOD_AMNT | MOD_PRIC | MOD_SHRS) & changed)
{ {
xaccSplitScrubImbalance (split); xaccSplitScrub (split);
if (other_split) if (other_split)
{ {
@ -3065,7 +3065,7 @@ xaccSRSaveChangedCells (SplitRegister *reg, Transaction *trans, Split *split)
amount = gnc_numeric_neg (amount); amount = gnc_numeric_neg (amount);
xaccSplitSetSharePriceAndAmount (other_split, price, amount); xaccSplitSetSharePriceAndAmount (other_split, price, amount);
xaccSplitScrubImbalance (other_split); xaccSplitScrub (other_split);
} }
} }

View File

@ -105,6 +105,94 @@ xaccAccountScrubOrphans (Account *acc)
/* ================================================================ */ /* ================================================================ */
void
xaccGroupScrubSplits (AccountGroup *group)
{
int i;
if (!group) return;
assert ((0 == group->numAcc) || (group->account));
for (i = 0; i < group->numAcc; i++)
xaccAccountTreeScrubSplits (group->account[i]);
}
void
xaccAccountTreeScrubSplits (Account *account)
{
xaccGroupScrubSplits (xaccAccountGetChildren(account));
xaccAccountScrubSplits (account);
}
void
xaccAccountScrubSplits (Account *account)
{
GList *node;
for (node = xaccAccountGetSplitList (account); node; node = node->next)
xaccSplitScrub (node->data);
}
void
xaccTransScrubSplits (Transaction *trans)
{
GList *node;
if (!trans)
return;
for (node = trans->splits; node; node = node->next)
xaccSplitScrub (node->data);
}
void
xaccSplitScrub (Split *split)
{
Account *account;
Transaction *trans;
gboolean trans_was_open;
int scu;
if (!split)
return;
trans = xaccSplitGetParent (split);
if (!trans)
return;
account = xaccSplitGetAccount (split);
if (!account)
return;
if (!gnc_commodity_equiv (xaccAccountGetCurrency (account),
xaccAccountGetEffectiveSecurity (account)))
return;
scu = MIN (xaccAccountGetCurrencySCU (account),
xaccAccountGetSecuritySCU (account));
if (gnc_numeric_same (xaccSplitGetShareAmount (split),
xaccSplitGetValue (split),
scu, GNC_RND_ROUND))
return;
PINFO ("split with mismatched values: %s",
guid_to_string (xaccSplitGetGUID (split)));
trans_was_open = xaccTransIsOpen (trans);
if (!trans_was_open)
xaccTransBeginEdit (trans, TRUE);
xaccSplitSetShareAmount (split, xaccSplitGetValue (split));
if (!trans_was_open)
xaccTransCommitEdit (trans);
}
/* ================================================================ */
void void
xaccGroupScrubImbalance (AccountGroup *grp) xaccGroupScrubImbalance (AccountGroup *grp)
{ {
@ -150,7 +238,7 @@ xaccTransScrubImbalance (Transaction *trans)
if (!trans) if (!trans)
return; return;
xaccTransScrubSplitImbalance (trans); xaccTransScrubSplits (trans);
{ {
GList *node; GList *node;
@ -230,63 +318,6 @@ xaccTransScrubImbalance (Transaction *trans)
} }
} }
void
xaccTransScrubSplitImbalance (Transaction *trans)
{
GList *node;
if (!trans)
return;
for (node = trans->splits; node; node = node->next)
xaccSplitScrubImbalance (node->data);
}
void
xaccSplitScrubImbalance (Split *split)
{
Account *account;
Transaction *trans;
gboolean trans_was_open;
int scu;
if (!split)
return;
trans = xaccSplitGetParent (split);
if (!trans)
return;
account = xaccSplitGetAccount (split);
if (!account)
return;
if (!gnc_commodity_equiv (xaccAccountGetCurrency (account),
xaccAccountGetEffectiveSecurity (account)))
return;
scu = MIN (xaccAccountGetCurrencySCU (account),
xaccAccountGetSecuritySCU (account));
if (gnc_numeric_same (xaccSplitGetShareAmount (split),
xaccSplitGetValue (split),
scu, GNC_RND_ROUND))
return;
PINFO ("split with mismatched values: %s",
guid_to_string (xaccSplitGetGUID (split)));
trans_was_open = xaccTransIsOpen (trans);
if (!trans_was_open)
xaccTransBeginEdit (trans, TRUE);
xaccSplitSetShareAmount (split, xaccSplitGetValue (split));
if (!trans_was_open)
xaccTransCommitEdit (trans);
}
/* ================================================================ */ /* ================================================================ */
static Account * static Account *

View File

@ -57,13 +57,20 @@ void xaccAccountScrubOrphans (Account *acc);
void xaccAccountTreeScrubOrphans (Account *acc); void xaccAccountTreeScrubOrphans (Account *acc);
void xaccGroupScrubOrphans (AccountGroup *grp); void xaccGroupScrubOrphans (AccountGroup *grp);
/* The ScrubSplit methods ensure that splits with the same currency
* and security have the same share quantity and value.
*/
void xaccSplitScrub (Split *split);
void xaccTransScrubSplits (Transaction *trans);
void xaccAccountScrubSplits (Account *account);
void xaccAccountTreeScrubSplits (Account *account);
void xaccGroupScrubSplits (AccountGroup *group);
/* The xaccScrubImbalance() method searches for transactions that do /* The xaccScrubImbalance() method searches for transactions that do
* not balance to zero. If any such transactions are found, a split * not balance to zero. If any such transactions are found, a split
* is created to offset this amount and is added to an "imbalance" * is created to offset this amount and is added to an "imbalance"
* account. * account.
*/ */
void xaccSplitScrubImbalance (Split *split);
void xaccTransScrubSplitImbalance (Transaction *trans);
void xaccTransScrubImbalance (Transaction *trans); void xaccTransScrubImbalance (Transaction *trans);
void xaccAccountScrubImbalance (Account *acc); void xaccAccountScrubImbalance (Account *acc);
void xaccAccountTreeScrubImbalance (Account *acc); void xaccAccountTreeScrubImbalance (Account *acc);

View File

@ -63,9 +63,12 @@
int force_double_entry = 0; int force_double_entry = 0;
/* bit-field flags for controlling transaction commits */ /* bit-field flags for controlling transaction commits */
#define BEGIN_EDIT 0x1 typedef enum
#define DEFER_REBALANCE 0x2 {
#define BEING_DESTROYED 0x4 BEGIN_EDIT = 1 << 0,
DEFER_REBALANCE = 1 << 1,
BEING_DESTROYED = 1 << 2,
} TransFlags;
/* arbitrary price per share increment FIXME */ /* arbitrary price per share increment FIXME */
#define PRICE_DENOM 1000000 #define PRICE_DENOM 1000000
@ -1332,7 +1335,7 @@ xaccTransCommitEdit (Transaction *trans)
xaccSplitSetValue(s, gnc_numeric_neg(split->value)); xaccSplitSetValue(s, gnc_numeric_neg(split->value));
} }
xaccTransScrubSplitImbalance (trans); /* xaccTransScrubSplits (trans); */
trans->open &= ~DEFER_REBALANCE; trans->open &= ~DEFER_REBALANCE;
xaccTransRebalance (trans); xaccTransRebalance (trans);

View File

@ -43,6 +43,7 @@
#include "BackendP.h" #include "BackendP.h"
#include "FileIO.h" #include "FileIO.h"
#include "Group.h" #include "Group.h"
#include "Scrub.h"
#include "gnc-book.h" #include "gnc-book.h"
#include "gnc-engine-util.h" #include "gnc-engine-util.h"
@ -411,6 +412,8 @@ gnc_book_load (GNCBook *book)
return FALSE; return FALSE;
} }
xaccGroupScrubSplits (book->topgroup);
return TRUE; return TRUE;
} }
else else