mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
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:
parent
88bdc41cd8
commit
335e018b60
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 *
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user