From 335e018b60fb75dac21a0a66d785b30691f2d892 Mon Sep 17 00:00:00 2001 From: Dave Peticolas Date: Fri, 1 Dec 2000 07:59:57 +0000 Subject: [PATCH] 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 --- src/SplitLedger.c | 10 +-- src/engine/Scrub.c | 147 ++++++++++++++++++++++++--------------- src/engine/Scrub.h | 11 ++- src/engine/Transaction.c | 11 +-- src/engine/gnc-book.c | 3 + 5 files changed, 113 insertions(+), 69 deletions(-) diff --git a/src/SplitLedger.c b/src/SplitLedger.c index 9ed1dac673..73619302b0 100644 --- a/src/SplitLedger.c +++ b/src/SplitLedger.c @@ -3018,8 +3018,8 @@ xaccSRSaveChangedCells (SplitRegister *reg, Transaction *trans, Split *split) if (MOD_SHRS & changed) { - gnc_numeric amount = xaccGetPriceCellValue(reg->sharesCell); - gnc_numeric price = xaccGetPriceCellValue(reg->priceCell); + gnc_numeric amount = xaccGetPriceCellValue (reg->sharesCell); + gnc_numeric price = xaccGetPriceCellValue (reg->priceCell); DEBUG ("MOD_SHRS"); @@ -3031,7 +3031,7 @@ xaccSRSaveChangedCells (SplitRegister *reg, Transaction *trans, Split *split) { gnc_numeric price; - price = xaccGetPriceCellValue(reg->priceCell); + price = xaccGetPriceCellValue (reg->priceCell); DEBUG ("MOD_PRIC"); @@ -3055,7 +3055,7 @@ xaccSRSaveChangedCells (SplitRegister *reg, Transaction *trans, Split *split) if ((MOD_AMNT | MOD_PRIC | MOD_SHRS) & changed) { - xaccSplitScrubImbalance (split); + xaccSplitScrub (split); if (other_split) { @@ -3065,7 +3065,7 @@ xaccSRSaveChangedCells (SplitRegister *reg, Transaction *trans, Split *split) amount = gnc_numeric_neg (amount); xaccSplitSetSharePriceAndAmount (other_split, price, amount); - xaccSplitScrubImbalance (other_split); + xaccSplitScrub (other_split); } } diff --git a/src/engine/Scrub.c b/src/engine/Scrub.c index 9f30320041..ad0724eae6 100644 --- a/src/engine/Scrub.c +++ b/src/engine/Scrub.c @@ -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 xaccGroupScrubImbalance (AccountGroup *grp) { @@ -150,7 +238,7 @@ xaccTransScrubImbalance (Transaction *trans) if (!trans) return; - xaccTransScrubSplitImbalance (trans); + xaccTransScrubSplits (trans); { 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 * diff --git a/src/engine/Scrub.h b/src/engine/Scrub.h index 7ebd49968d..63d0bb37db 100644 --- a/src/engine/Scrub.h +++ b/src/engine/Scrub.h @@ -57,13 +57,20 @@ void xaccAccountScrubOrphans (Account *acc); void xaccAccountTreeScrubOrphans (Account *acc); 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 * not balance to zero. If any such transactions are found, a split * is created to offset this amount and is added to an "imbalance" * account. */ -void xaccSplitScrubImbalance (Split *split); -void xaccTransScrubSplitImbalance (Transaction *trans); void xaccTransScrubImbalance (Transaction *trans); void xaccAccountScrubImbalance (Account *acc); void xaccAccountTreeScrubImbalance (Account *acc); diff --git a/src/engine/Transaction.c b/src/engine/Transaction.c index 5a641a59ed..6cbc55bc10 100644 --- a/src/engine/Transaction.c +++ b/src/engine/Transaction.c @@ -63,9 +63,12 @@ int force_double_entry = 0; /* bit-field flags for controlling transaction commits */ -#define BEGIN_EDIT 0x1 -#define DEFER_REBALANCE 0x2 -#define BEING_DESTROYED 0x4 +typedef enum +{ + BEGIN_EDIT = 1 << 0, + DEFER_REBALANCE = 1 << 1, + BEING_DESTROYED = 1 << 2, +} TransFlags; /* arbitrary price per share increment FIXME */ #define PRICE_DENOM 1000000 @@ -1332,7 +1335,7 @@ xaccTransCommitEdit (Transaction *trans) xaccSplitSetValue(s, gnc_numeric_neg(split->value)); } - xaccTransScrubSplitImbalance (trans); + /* xaccTransScrubSplits (trans); */ trans->open &= ~DEFER_REBALANCE; xaccTransRebalance (trans); diff --git a/src/engine/gnc-book.c b/src/engine/gnc-book.c index b9321766f0..b94e34a16f 100644 --- a/src/engine/gnc-book.c +++ b/src/engine/gnc-book.c @@ -43,6 +43,7 @@ #include "BackendP.h" #include "FileIO.h" #include "Group.h" +#include "Scrub.h" #include "gnc-book.h" #include "gnc-engine-util.h" @@ -411,6 +412,8 @@ gnc_book_load (GNCBook *book) return FALSE; } + xaccGroupScrubSplits (book->topgroup); + return TRUE; } else