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)
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 *
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user