make sure that balances are automatically recomputed whenever needed

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@782 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Linas Vepstas 1998-04-05 09:26:01 +00:00
parent 5003b58622
commit 0fc2f2048a
4 changed files with 69 additions and 35 deletions

View File

@ -103,9 +103,8 @@ xaccMallocAccount( void )
void
xaccFreeAccount( Account *acc )
{
int i=0, j=0;
Split *s, *debit_s;
int dont_free_transaction = 0;
int i=0;
Split *s;
if (NULL == acc) return;
@ -129,20 +128,7 @@ xaccFreeAccount( Account *acc )
i=0;
s = acc->splits[0];
while (s) {
Transaction *trans = (Transaction *) s->parent;
j=0;
debit_s = trans->splits[0];
while (debit_s) {
if (debit_s->acc) { dont_free_transaction = 1; break; }
j++;
debit_s = trans->splits[j];
}
if (!dont_free_transaction) {
xaccFreeTransaction( trans );
}
xaccSplitDestroy (s);
i++;
s = acc->splits[i];
}
@ -233,6 +219,11 @@ xaccAccountInsertSplit ( Account *acc, Split *split )
acc -> changed = TRUE;
if( acc->parent != NULL ) acc->parent->saved = FALSE;
/* if this split belongs to another acount, remove it from
* there first. We don't want to ever leave the system
* in an inconsistent state.
*/
if (split->acc) xaccAccountRemoveSplit (split->acc, split);
split->acc = acc;
oldsplits = acc->splits;
@ -273,6 +264,8 @@ xaccAccountInsertSplit ( Account *acc, Split *split )
acc->splits[acc->numSplits] = NULL;
_free(oldsplits);
xaccAccountRecomputeBalance (acc);
}
@ -309,7 +302,7 @@ xaccAccountRemoveSplit ( Account *acc, Split *split )
/********************************************************************\
* xaccRecomputeBalance *
* xaccAccountRecomputeBalance *
* recomputes the partial balances and the current balance for *
* this account. *
*
@ -337,7 +330,7 @@ xaccAccountRemoveSplit ( Account *acc, Split *split )
\********************************************************************/
void
xaccRecomputeBalance( Account * acc )
xaccAccountRecomputeBalance( Account * acc )
{
int i = 0;
double dbalance = 0.0;
@ -528,7 +521,7 @@ xaccIsAccountInList (Account * acc, Account **list)
\********************************************************************/
void
xaccRecomputeBalances( Account **list )
xaccAccountRecomputeBalances( Account **list )
{
Account * acc;
int nacc = 0;
@ -536,7 +529,7 @@ xaccRecomputeBalances( Account **list )
acc = list[0];
while (acc) {
xaccRecomputeBalance (acc);
xaccAccountRecomputeBalance (acc);
nacc++;
acc = list[nacc];
}

View File

@ -49,13 +49,13 @@ void xaccAccountCommitEdit (Account *);
int xaccGetAccountID (Account *);
/*
* The xaccAccountInsertSplit() method will insert the indicated
* split into the indicated account. If the split already
* belongs to anothe account, it will be removed from that
* account first.
*/
void xaccAccountInsertSplit (Account *, Split *);
void xaccAccountRemoveSplit (Account *, Split *);
/* the following recompute the partial balances (stored with the transaction)
* and the total balance, for this account */
void xaccRecomputeBalance (Account *);
void xaccRecomputeBalances (Account **);
/* The xaccCheckDateOrder() surboutine checks to see if
* a split is in proper sorted date order with respect

View File

@ -6,6 +6,13 @@
* This is the *private* header for the account structure.
* No one outside of the engine should ever include this file.
*
* This header includes prototypes for "dangerous" functions.
* Invoking any of these functions potentially leave the account
* in an inconsistent state. If they are not used in the proper
* setting, they can leave the account structures in an inconsistent
* state. Thus, these methods should never be used outside of
* the engine, which is why they are "hidden" here.
*
*/
/********************************************************************\
@ -74,4 +81,20 @@ struct _account {
};
/* The xaccAccountRemoveSplit() routine will remove the indicated split
* from the indicated account. Note that this will leave the split
* "dangling", i.e. unassigned to any account, and therefore will put
* the engine into an inconsistent state. After removing a split,
* it should be immediately destroyed, or it should be inserted into
* an account.
*/
void xaccAccountRemoveSplit (Account *, Split *);
/* the following recompute the partial balances (stored with the
* transaction)
* and the total balance, for this account */
void xaccAccountRecomputeBalance (Account *);
void xaccAccountRecomputeBalances (Account **);
#endif /* __XACC_ACCOUNT_P_H__ */

View File

@ -136,6 +136,7 @@ MarkChanged (Transaction *trans)
void
xaccSplitDestroy (Split *split)
{
Account *acc;
Transaction *trans;
int numsplits = 0;
int ismember = 0;
@ -148,6 +149,7 @@ xaccSplitDestroy (Split *split)
numsplits = 0;
s = trans->splits[0];
while (s) {
MARK_SPLIT(s);
if (s == split) ismember = 1;
numsplits ++;
s = trans->splits[numsplits];
@ -158,20 +160,30 @@ xaccSplitDestroy (Split *split)
* merely unlink & free the split.
*/
if (2 < numsplits) {
MARK_SPLIT (split);
xaccTransRemoveSplit (trans, split);
xaccAccountRemoveSplit (split->acc, split);
acc = split->acc;
xaccAccountRemoveSplit (acc, split);
xaccAccountRecomputeBalance (acc);
xaccFreeSplit (split);
xaccSplitRebalance (trans->splits[1]);
xaccSplitRebalance (trans->splits[0]);
} else {
/* if the transaction has only two splits,
* remove both of them, and them destroy the
* transaction.
*/
s = trans->splits[0];
xaccAccountRemoveSplit (split->acc, s);
acc = s->acc;
MARK_SPLIT (s);
xaccAccountRemoveSplit (acc, s);
xaccAccountRecomputeBalance (acc);
xaccFreeSplit (s);
s = trans->splits[1];
xaccAccountRemoveSplit (split->acc, s);
acc = s->acc;
MARK_SPLIT (s);
xaccAccountRemoveSplit (acc, s);
xaccAccountRecomputeBalance (acc);
xaccFreeSplit (s);
xaccFreeTransaction (trans);
}
@ -355,13 +367,17 @@ xaccTransDestroy (Transaction *trans)
{
int i;
Split *split;
Account *acc;
if (!trans) return;
i=0;
split = trans->splits[i];
while (split) {
xaccAccountRemoveSplit (split->acc, split);
MARK_SPLIT (split);
acc = split ->acc;
xaccAccountRemoveSplit (acc, split);
xaccAccountRecomputeBalance (acc);
i++;
split = trans->splits[i];
}
@ -437,6 +453,7 @@ xaccSplitRebalance (Split *split)
*/
s -> damount = - (value / (s->share_price));
MARK_SPLIT (s);
xaccAccountRecomputeBalance (s->acc);
} else{
/* There are no destination splits !!
@ -461,9 +478,9 @@ xaccSplitRebalance (Split *split)
/* insert the new split into the transaction and
* the same account as the source split */
MARK_SPLIT (s);
xaccTransAppendSplit (trans, s);
xaccAccountInsertSplit (split->acc, s);
MARK_SPLIT (s);
}
#endif
@ -486,6 +503,7 @@ xaccSplitRebalance (Split *split)
s = trans->splits[0];
s -> damount = - (value / (s->share_price));
MARK_SPLIT (s);
xaccAccountRecomputeBalance (s->acc);
}
/* hack alert -- if the "force-double-entry" flag is set,
@ -713,10 +731,9 @@ xaccTransSetDate (Transaction *trans, int day, int mon, int year)
i=0;
split = trans->splits[i];
while (split) {
acc = (Account *) split->acc;
acc = split->acc;
xaccAccountRemoveSplit (acc, split);
xaccAccountInsertSplit (acc, split);
xaccRecomputeBalance (acc);
i++;
split = trans->splits[i];
@ -874,6 +891,7 @@ xaccSplitSetReconcile (Split *split, char recn)
{
split->reconciled = recn;
MARK_SPLIT (split);
xaccAccountRecomputeBalance (split->acc);
}
/********************************************************************\