mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
first step of radical surgery to implement splits
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@380 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
dc30ef2388
commit
129367be70
547
src/Account.c
547
src/Account.c
@ -66,11 +66,6 @@ mallocAccount( void )
|
|||||||
acc->description = NULL;
|
acc->description = NULL;
|
||||||
acc->notes = NULL;
|
acc->notes = NULL;
|
||||||
|
|
||||||
/* transction array should be null-terminated */
|
|
||||||
acc->numTrans = 0;
|
|
||||||
acc->transaction = (Transaction **) _malloc (sizeof (Transaction *));
|
|
||||||
acc->transaction[0] = NULL;
|
|
||||||
|
|
||||||
acc->numSplits = 0;
|
acc->numSplits = 0;
|
||||||
acc->splits = (Split **) _malloc (sizeof (Split *));
|
acc->splits = (Split **) _malloc (sizeof (Split *));
|
||||||
acc->splits[0] = NULL;
|
acc->splits[0] = NULL;
|
||||||
@ -95,8 +90,10 @@ mallocAccount( void )
|
|||||||
void
|
void
|
||||||
freeAccount( Account *acc )
|
freeAccount( Account *acc )
|
||||||
{
|
{
|
||||||
int i;
|
int i=0, j=0;
|
||||||
Split *s;
|
Split *s, *debit_s;
|
||||||
|
int dont_free_transaction = 0;
|
||||||
|
struct _account * _acc = (struct _account *) acc;
|
||||||
|
|
||||||
if (NULL == acc) return;
|
if (NULL == acc) return;
|
||||||
|
|
||||||
@ -109,40 +106,40 @@ freeAccount( Account *acc )
|
|||||||
|
|
||||||
freeQuickFill(acc->qfRoot);
|
freeQuickFill(acc->qfRoot);
|
||||||
|
|
||||||
/* free up splits */
|
/* any split pointing at this account needs to be unmarked */
|
||||||
/* hack alert -- this is incomplete and broken,
|
|
||||||
* and interacts badly with the free-transaction code
|
|
||||||
* immediately below. Should be corrected when final
|
|
||||||
* split work is completed. */
|
|
||||||
i=0;
|
i=0;
|
||||||
s = acc->splits[0];
|
s = acc->splits[0];
|
||||||
while (s) {
|
while (s) {
|
||||||
struct _account * _acc = (struct _account *) acc;
|
s->acc = NULL;
|
||||||
if (_acc == s->acc) s->acc = NULL;
|
|
||||||
i++;
|
i++;
|
||||||
s = acc->splits[i];
|
s = acc->splits[i];
|
||||||
}
|
}
|
||||||
_free (acc->splits);
|
|
||||||
acc->numSplits = 0;
|
|
||||||
|
|
||||||
/* free transactions */
|
/* search for orphaned transactions, and delete them */
|
||||||
for( i=0; i<acc->numTrans; i++ ) {
|
i=0;
|
||||||
Transaction *trans = acc->transaction[i];
|
s = acc->splits[0];
|
||||||
struct _account * _acc = (struct _account *) acc;
|
while (s) {
|
||||||
|
Transaction *trans = (Transaction *) s->parent;
|
||||||
|
|
||||||
if (!trans) continue;
|
j=0;
|
||||||
/* free the transaction only if its not
|
debit_s = trans->debit_splits[0];
|
||||||
* a part of a double entry */
|
while (debit_s) {
|
||||||
if (_acc == trans->credit_split.acc) trans->credit_split.acc = NULL;
|
if (debit_s->acc) { dont_free_transaction = 1; break; }
|
||||||
if (_acc == trans->debit) trans->debit = NULL;
|
j++;
|
||||||
if ( (NULL == trans->debit) && (NULL == trans->credit_split.acc) ) {
|
debit_s = trans->debit_splits[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (!dont_free_transaction) && (NULL == trans->credit_split.acc) ) {
|
||||||
freeTransaction( trans );
|
freeTransaction( trans );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
s = acc->splits[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* free up array of split pointers */
|
||||||
/* free the array of pointers */
|
_free (acc->splits);
|
||||||
_free( acc->transaction );
|
acc->splits = NULL;
|
||||||
|
|
||||||
/* zero out values, just in case stray
|
/* zero out values, just in case stray
|
||||||
* pointers are pointing here. */
|
* pointers are pointing here. */
|
||||||
@ -160,9 +157,6 @@ freeAccount( Account *acc )
|
|||||||
acc->description = NULL;
|
acc->description = NULL;
|
||||||
acc->notes = NULL;
|
acc->notes = NULL;
|
||||||
|
|
||||||
acc->numTrans = 0;
|
|
||||||
acc->transaction = NULL;
|
|
||||||
|
|
||||||
/* hack alert -- shouldn't we destroy this widget ??? */
|
/* hack alert -- shouldn't we destroy this widget ??? */
|
||||||
acc->arrowb = NULL;
|
acc->arrowb = NULL;
|
||||||
acc->expand = 0;
|
acc->expand = 0;
|
||||||
@ -190,198 +184,6 @@ xaccGetAccountID (Account *acc)
|
|||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
\********************************************************************/
|
\********************************************************************/
|
||||||
|
|
||||||
Transaction *
|
|
||||||
getTransaction( Account *acc, int num )
|
|
||||||
{
|
|
||||||
if( NULL == acc ) return NULL;
|
|
||||||
|
|
||||||
if( (num >= 0) && (num < acc->numTrans) )
|
|
||||||
return acc->transaction[num];
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************\
|
|
||||||
\********************************************************************/
|
|
||||||
|
|
||||||
int
|
|
||||||
getNumOfTransaction( Account *acc, Transaction *trans )
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i=0; i<acc->numTrans; i++) {
|
|
||||||
if (trans == acc->transaction[i]) return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************\
|
|
||||||
\********************************************************************/
|
|
||||||
|
|
||||||
Transaction *
|
|
||||||
removeTransaction( Account *acc, int num )
|
|
||||||
{
|
|
||||||
Transaction *trans = NULL;
|
|
||||||
Transaction **oldTrans;
|
|
||||||
int i,j;
|
|
||||||
|
|
||||||
if (NULL == acc) return NULL;
|
|
||||||
|
|
||||||
oldTrans = acc->transaction;
|
|
||||||
|
|
||||||
/* check for valid number */
|
|
||||||
if( (0 > num) || (num >= acc->numTrans) ) return NULL;
|
|
||||||
|
|
||||||
/* Set this flag, so we know we need to save the data file: */
|
|
||||||
if( NULL != acc->parent ) acc->parent->saved = False;
|
|
||||||
|
|
||||||
acc->numTrans--;
|
|
||||||
|
|
||||||
acc->transaction = (Transaction **)_malloc(((acc->numTrans)+1)*
|
|
||||||
sizeof(Transaction *));
|
|
||||||
|
|
||||||
trans = oldTrans[acc->numTrans];/* In case we are deleting last in
|
|
||||||
* old array */
|
|
||||||
for( i=0,j=0; i<acc->numTrans; i++,j++ ) {
|
|
||||||
if( j != num ) {
|
|
||||||
acc->transaction[i] = oldTrans[j];
|
|
||||||
} else {
|
|
||||||
trans = oldTrans[j];
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* make sure the array is NULL terminated */
|
|
||||||
acc->transaction[acc->numTrans] = NULL;
|
|
||||||
|
|
||||||
_free (oldTrans);
|
|
||||||
|
|
||||||
/* if this is a double-entry transaction, be sure to
|
|
||||||
* unmark it. */
|
|
||||||
if (((Account *)trans->credit_split.acc) == acc)
|
|
||||||
trans->credit_split.acc = NULL;
|
|
||||||
if (((Account *)trans->debit) == acc) trans->debit = NULL;
|
|
||||||
|
|
||||||
return trans;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************\
|
|
||||||
\********************************************************************/
|
|
||||||
|
|
||||||
void
|
|
||||||
xaccRemoveTransaction( Account *acc, Transaction *trans)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!acc) return;
|
|
||||||
if (!trans) return;
|
|
||||||
|
|
||||||
i = getNumOfTransaction (acc, trans);
|
|
||||||
if (0 <= i) {
|
|
||||||
removeTransaction (acc, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************\
|
|
||||||
\********************************************************************/
|
|
||||||
|
|
||||||
int
|
|
||||||
insertTransaction( Account *acc, Transaction *trans )
|
|
||||||
{
|
|
||||||
int position=-1;
|
|
||||||
int i,j;
|
|
||||||
int inserted = False;
|
|
||||||
Transaction **oldTrans;
|
|
||||||
|
|
||||||
if (NULL == acc) {
|
|
||||||
printf ("Internal Error: insertTransaction(): \n");
|
|
||||||
printf (" no account specified ! \n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the transaction hasn't already been marked as a debit
|
|
||||||
* or a credit to this account, then provide a default
|
|
||||||
* behavior for double-entry insertion.
|
|
||||||
*
|
|
||||||
* If this appears to be a new transaction, then default
|
|
||||||
* it to being a credit. If this transaction is already
|
|
||||||
* in another account, assume this is the other half.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( (acc != (Account *) trans->credit_split.acc) &&
|
|
||||||
(acc != (Account *) trans->debit) ) {
|
|
||||||
|
|
||||||
if (NULL == trans->credit_split.acc) {
|
|
||||||
trans->credit_split.acc = (struct _account *) acc;
|
|
||||||
} else
|
|
||||||
if (NULL == trans->debit) {
|
|
||||||
trans->debit = (struct _account *) acc;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
printf ("Internal Error: insertTransaction(): \n");
|
|
||||||
printf ("can't insert a transaction more than twice! \n");
|
|
||||||
printf ("This error should not occur, please report it \n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trans->debit == trans->credit_split.acc) {
|
|
||||||
printf ("Internal Error: insertTransaction(): \n");
|
|
||||||
printf ("debited and credit accounts cannot be the same\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* mark the data file as needing to be saved: */
|
|
||||||
if( acc->parent != NULL ) acc->parent->saved = False;
|
|
||||||
|
|
||||||
acc->numTrans++;
|
|
||||||
oldTrans = acc->transaction;
|
|
||||||
acc->transaction = (Transaction **)_malloc(((acc->numTrans) + 1) *
|
|
||||||
sizeof(Transaction *));
|
|
||||||
|
|
||||||
/* dt is the date of the transaction we are inserting, and dj
|
|
||||||
* is the date of the "cursor" transaction... we want to insert
|
|
||||||
* the new transaction before the first transaction of the same
|
|
||||||
* or later date. The !inserted bit is a bit of a kludge to
|
|
||||||
* make sure we only insert the new transaction once! */
|
|
||||||
for( i=0,j=0; i<acc->numTrans; i++,j++ )
|
|
||||||
{
|
|
||||||
/* if we didn't do this, and we needed to insert into the
|
|
||||||
* last spot in the array, we would walk off the end of the
|
|
||||||
* old array, which is no good! */
|
|
||||||
if( j>=(acc->numTrans-1) )
|
|
||||||
{
|
|
||||||
position = i;
|
|
||||||
acc->transaction[i] = trans;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( (xaccTransOrder (&(oldTrans[j]),&trans) > 0) && !inserted )
|
|
||||||
{
|
|
||||||
position = i;
|
|
||||||
acc->transaction[i] = trans;
|
|
||||||
j--;
|
|
||||||
inserted = True;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
acc->transaction[i] = oldTrans[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* make sure the array is NULL terminated */
|
|
||||||
acc->transaction[acc->numTrans] = NULL;
|
|
||||||
|
|
||||||
_free(oldTrans);
|
|
||||||
|
|
||||||
if( position != -1 )
|
|
||||||
qfInsertTransaction( acc->qfRoot, trans );
|
|
||||||
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************\
|
|
||||||
\********************************************************************/
|
|
||||||
|
|
||||||
void
|
void
|
||||||
xaccInsertSplit ( Account *acc, Split *split )
|
xaccInsertSplit ( Account *acc, Split *split )
|
||||||
{
|
{
|
||||||
@ -440,183 +242,6 @@ xaccInsertSplit ( Account *acc, Split *split )
|
|||||||
qfInsertTransaction( acc->qfRoot, trans );
|
qfInsertTransaction( acc->qfRoot, trans );
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************\
|
|
||||||
\********************************************************************/
|
|
||||||
|
|
||||||
Account *
|
|
||||||
xaccGetOtherAccount( Account *acc, Transaction *trans )
|
|
||||||
{
|
|
||||||
if (NULL == acc) return NULL;
|
|
||||||
|
|
||||||
if (acc == ((Account *) trans->debit)) {
|
|
||||||
return ((Account *) trans->credit_split.acc);
|
|
||||||
} else
|
|
||||||
if (acc == ((Account *) trans->credit_split.acc)) {
|
|
||||||
return ((Account *) trans->debit);
|
|
||||||
} else {
|
|
||||||
printf ("Internal Error: xaccGetOtherAccount(): inconsistent entry \n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************\
|
|
||||||
\********************************************************************/
|
|
||||||
|
|
||||||
double xaccGetAmount (Account *acc, Transaction *trans)
|
|
||||||
{
|
|
||||||
double themount; /* amount */
|
|
||||||
|
|
||||||
themount = xaccGetShareAmount (acc, trans);
|
|
||||||
themount *= trans->share_price;
|
|
||||||
return themount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************\
|
|
||||||
\********************************************************************/
|
|
||||||
|
|
||||||
double xaccGetShareAmount (Account *acc, Transaction *trans)
|
|
||||||
{
|
|
||||||
double themount; /* amount */
|
|
||||||
struct _account *_acc = (struct _account *) acc;
|
|
||||||
|
|
||||||
if (NULL == trans) return 0.0;
|
|
||||||
if (NULL == acc) return 0.0;
|
|
||||||
|
|
||||||
/* for a double-entry, determine if this is a credit or a debit */
|
|
||||||
if ( trans->credit_split.acc == _acc ) {
|
|
||||||
themount = trans->damount;
|
|
||||||
} else
|
|
||||||
if ( trans->debit == _acc ) {
|
|
||||||
themount = - (trans->damount);
|
|
||||||
} else {
|
|
||||||
printf ("Internal Error: xaccGetShareAmount: missing double entry \n");
|
|
||||||
printf ("this error should not occur. Please report the problem. \n");
|
|
||||||
printf ("acc=%p deb=%p cred=%p\n",
|
|
||||||
acc, trans->debit, trans->credit_split.acc);
|
|
||||||
themount = 0.0; /* punt */
|
|
||||||
}
|
|
||||||
return themount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************\
|
|
||||||
\********************************************************************/
|
|
||||||
|
|
||||||
void xaccSetShareAmount (Account *acc, Transaction *trans, double themount)
|
|
||||||
{
|
|
||||||
struct _account *_acc = (struct _account *) acc;
|
|
||||||
|
|
||||||
/* for a double-entry, determine if this is a credit or a debit */
|
|
||||||
if ( trans->credit_split.acc == _acc ) {
|
|
||||||
trans->damount = themount;
|
|
||||||
} else
|
|
||||||
if ( trans->debit == _acc ) {
|
|
||||||
trans->damount = - themount;
|
|
||||||
} else {
|
|
||||||
printf ("Internal Error: xaccSetShareAmount: missing double entry \n");
|
|
||||||
printf ("this error should not occur. Please report the problem. \n");
|
|
||||||
trans->damount = 0.0; /* punt */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************\
|
|
||||||
\********************************************************************/
|
|
||||||
|
|
||||||
void xaccSetAmount (Account *acc, Transaction *trans, double themount)
|
|
||||||
{
|
|
||||||
if (0.0 < trans->share_price) {
|
|
||||||
themount /= trans->share_price;
|
|
||||||
xaccSetShareAmount (acc, trans, themount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************\
|
|
||||||
\********************************************************************/
|
|
||||||
|
|
||||||
double xaccGetBalance (Account *acc, Transaction *trans)
|
|
||||||
{
|
|
||||||
double themount; /* amount */
|
|
||||||
struct _account *_acc = (struct _account *) acc;
|
|
||||||
|
|
||||||
/* for a double-entry, determine if this is a credit or a debit */
|
|
||||||
if ( trans->credit_split.acc == _acc ) {
|
|
||||||
themount = trans->credit_balance;
|
|
||||||
} else
|
|
||||||
if ( trans->debit == _acc ) {
|
|
||||||
themount = trans->debit_balance;
|
|
||||||
} else {
|
|
||||||
printf ("Internal Error: xaccGetBalance: missing double entry \n");
|
|
||||||
printf ("this error should not occur. Please report the problem. \n");
|
|
||||||
themount = 0.0; /* punt */
|
|
||||||
}
|
|
||||||
return themount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************\
|
|
||||||
\********************************************************************/
|
|
||||||
|
|
||||||
double xaccGetClearedBalance (Account *acc, Transaction *trans)
|
|
||||||
{
|
|
||||||
double themount; /* amount */
|
|
||||||
struct _account *_acc = (struct _account *) acc;
|
|
||||||
|
|
||||||
/* for a double-entry, determine if this is a credit or a debit */
|
|
||||||
if ( trans->credit_split.acc == _acc ) {
|
|
||||||
themount = trans->credit_cleared_balance;
|
|
||||||
} else
|
|
||||||
if ( trans->debit == _acc ) {
|
|
||||||
themount = trans->debit_cleared_balance;
|
|
||||||
} else {
|
|
||||||
printf ("Internal Error: xaccGetClearedBalance: missing double entry \n");
|
|
||||||
printf ("this error should not occur. Please report the problem. \n");
|
|
||||||
themount = 0.0; /* punt */
|
|
||||||
}
|
|
||||||
return themount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************\
|
|
||||||
\********************************************************************/
|
|
||||||
|
|
||||||
double xaccGetReconciledBalance (Account *acc, Transaction *trans)
|
|
||||||
{
|
|
||||||
double themount; /* amount */
|
|
||||||
struct _account *_acc = (struct _account *) acc;
|
|
||||||
|
|
||||||
/* for a double-entry, determine if this is a credit or a debit */
|
|
||||||
if ( trans->credit_split.acc == _acc ) {
|
|
||||||
themount = trans->credit_reconciled_balance;
|
|
||||||
} else
|
|
||||||
if ( trans->debit == _acc ) {
|
|
||||||
themount = trans->debit_reconciled_balance;
|
|
||||||
} else {
|
|
||||||
printf ("Internal Error: xaccGetReconciledBalance: missing double entry \n");
|
|
||||||
printf ("this error should not occur. Please report the problem. \n");
|
|
||||||
themount = 0.0; /* punt */
|
|
||||||
}
|
|
||||||
return themount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************\
|
|
||||||
\********************************************************************/
|
|
||||||
|
|
||||||
double xaccGetShareBalance (Account *acc, Transaction *trans)
|
|
||||||
{
|
|
||||||
double themount; /* amount */
|
|
||||||
struct _account *_acc = (struct _account *) acc;
|
|
||||||
|
|
||||||
/* for a double-entry, determine if this is a credit or a debit */
|
|
||||||
if ( trans->credit_split.acc == _acc ) {
|
|
||||||
themount = trans->credit_share_balance;
|
|
||||||
} else
|
|
||||||
if ( trans->debit == _acc ) {
|
|
||||||
themount = trans->debit_share_balance;
|
|
||||||
} else {
|
|
||||||
printf ("Internal Error: xaccGetShareBalance: missing double entry \n");
|
|
||||||
printf ("this error should not occur. Please report the problem. \n");
|
|
||||||
themount = 0.0; /* punt */
|
|
||||||
}
|
|
||||||
return themount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
* xaccRecomputeBalance *
|
* xaccRecomputeBalance *
|
||||||
@ -649,7 +274,7 @@ double xaccGetShareBalance (Account *acc, Transaction *trans)
|
|||||||
void
|
void
|
||||||
xaccRecomputeBalance( Account * acc )
|
xaccRecomputeBalance( Account * acc )
|
||||||
{
|
{
|
||||||
int i;
|
int i = 0;
|
||||||
double dbalance = 0.0;
|
double dbalance = 0.0;
|
||||||
double dcleared_balance = 0.0;
|
double dcleared_balance = 0.0;
|
||||||
double dreconciled_balance = 0.0;
|
double dreconciled_balance = 0.0;
|
||||||
@ -657,75 +282,56 @@ xaccRecomputeBalance( Account * acc )
|
|||||||
double share_cleared_balance = 0.0;
|
double share_cleared_balance = 0.0;
|
||||||
double share_reconciled_balance = 0.0;
|
double share_reconciled_balance = 0.0;
|
||||||
double amt = 0.0;
|
double amt = 0.0;
|
||||||
Transaction *trans, *last_trans=NULL;
|
Split *split, *last_split;
|
||||||
Account *tracc;
|
|
||||||
|
|
||||||
if( NULL == acc ) return;
|
if( NULL == acc ) return;
|
||||||
|
|
||||||
for( i=0; (trans=getTransaction(acc,i)) != NULL; i++ ) {
|
split = acc->splits[0];
|
||||||
|
while (split) {
|
||||||
|
|
||||||
/* compute both dollar and share balances */
|
/* compute both dollar and share balances */
|
||||||
amt = xaccGetShareAmount (acc, trans);
|
amt = split->damount;
|
||||||
share_balance += amt;
|
share_balance += amt;
|
||||||
dbalance += amt * (trans->share_price);
|
dbalance += amt * (split->share_price);
|
||||||
|
|
||||||
if( NREC != trans->credit_split.reconciled ) {
|
if( NREC != split -> reconciled ) {
|
||||||
share_cleared_balance += amt;
|
share_cleared_balance += amt;
|
||||||
dcleared_balance += amt * (trans->share_price);
|
dcleared_balance += amt * (split->share_price);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( YREC == trans->credit_split.reconciled ) {
|
if( YREC == split -> reconciled ) {
|
||||||
share_reconciled_balance += amt;
|
share_reconciled_balance += amt;
|
||||||
dreconciled_balance += amt * (trans->share_price);
|
dreconciled_balance += amt * (split->share_price);
|
||||||
}
|
}
|
||||||
|
|
||||||
tracc = (Account *) trans->credit_split.acc;
|
|
||||||
if (tracc == acc) {
|
|
||||||
/* For bank accounts, the invarient subtotal is the dollar
|
/* For bank accounts, the invarient subtotal is the dollar
|
||||||
* amount. For stock accoounts, the invarient is the share amount */
|
* amount. For stock accoounts, the invarient is the share amount */
|
||||||
if ( (STOCK == tracc->type) || ( MUTUAL == tracc->type) ) {
|
if ( (STOCK == acc->type) || ( MUTUAL == acc->type) ) {
|
||||||
trans -> credit_share_balance = share_balance;
|
split -> share_balance = share_balance;
|
||||||
trans -> credit_share_cleared_balance = share_cleared_balance;
|
split -> share_cleared_balance = share_cleared_balance;
|
||||||
trans -> credit_share_reconciled_balance = share_reconciled_balance;
|
split -> share_reconciled_balance = share_reconciled_balance;
|
||||||
trans -> credit_balance = trans->share_price * share_balance;
|
split -> balance = split->share_price * share_balance;
|
||||||
trans -> credit_cleared_balance = trans->share_price * share_cleared_balance;
|
split -> cleared_balance = split->share_price * share_cleared_balance;
|
||||||
trans -> credit_reconciled_balance = trans->share_price * share_reconciled_balance;
|
split -> reconciled_balance = split->share_price * share_reconciled_balance;
|
||||||
} else {
|
} else {
|
||||||
trans -> credit_share_balance = dbalance;
|
split -> share_balance = dbalance;
|
||||||
trans -> credit_share_cleared_balance = dcleared_balance;
|
split -> share_cleared_balance = dcleared_balance;
|
||||||
trans -> credit_share_reconciled_balance = dreconciled_balance;
|
split -> share_reconciled_balance = dreconciled_balance;
|
||||||
trans -> credit_balance = dbalance;
|
split -> balance = dbalance;
|
||||||
trans -> credit_cleared_balance = dcleared_balance;
|
split -> cleared_balance = dcleared_balance;
|
||||||
trans -> credit_reconciled_balance = dreconciled_balance;
|
split -> reconciled_balance = dreconciled_balance;
|
||||||
}
|
|
||||||
}
|
|
||||||
tracc = (Account *) trans->debit;
|
|
||||||
if (tracc == acc) {
|
|
||||||
if ( (STOCK == tracc->type) || ( MUTUAL == tracc->type) ) {
|
|
||||||
trans -> debit_share_balance = share_balance;
|
|
||||||
trans -> debit_share_cleared_balance = share_cleared_balance;
|
|
||||||
trans -> debit_share_reconciled_balance = share_reconciled_balance;
|
|
||||||
trans -> debit_balance = trans->share_price * share_balance;
|
|
||||||
trans -> debit_cleared_balance = trans->share_price * share_cleared_balance;
|
|
||||||
trans -> debit_reconciled_balance = trans->share_price * share_reconciled_balance;
|
|
||||||
} else {
|
|
||||||
trans -> debit_share_balance = dbalance;
|
|
||||||
trans -> debit_share_cleared_balance = dcleared_balance;
|
|
||||||
trans -> debit_share_reconciled_balance = dreconciled_balance;
|
|
||||||
trans -> debit_balance = dbalance;
|
|
||||||
trans -> debit_cleared_balance = dcleared_balance;
|
|
||||||
trans -> debit_reconciled_balance = dreconciled_balance;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
last_trans = trans;
|
last_split = split;
|
||||||
|
i++;
|
||||||
|
split = acc->splits[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (STOCK == acc->type) || ( MUTUAL == acc->type) ) {
|
if ( (STOCK == acc->type) || ( MUTUAL == acc->type) ) {
|
||||||
if (last_trans) {
|
if (last_split) {
|
||||||
acc -> balance = share_balance * (last_trans->share_price);
|
acc -> balance = share_balance * (last_split->share_price);
|
||||||
acc -> cleared_balance = share_cleared_balance * (last_trans->share_price);
|
acc -> cleared_balance = share_cleared_balance * (last_split->share_price);
|
||||||
acc -> reconciled_balance = share_reconciled_balance * (last_trans->share_price);
|
acc -> reconciled_balance = share_reconciled_balance * (last_split->share_price);
|
||||||
} else {
|
} else {
|
||||||
acc -> balance = 0.0;
|
acc -> balance = 0.0;
|
||||||
acc -> cleared_balance = 0.0;
|
acc -> cleared_balance = 0.0;
|
||||||
@ -752,37 +358,46 @@ xaccRecomputeBalance( Account * acc )
|
|||||||
\********************************************************************/
|
\********************************************************************/
|
||||||
|
|
||||||
int
|
int
|
||||||
xaccCheckDateOrder (Account * acc, Transaction *trans )
|
xaccCheckDateOrder (Account * acc, Split *split )
|
||||||
{
|
{
|
||||||
int outOfOrder = 0;
|
int outOfOrder = 0;
|
||||||
Transaction *prevTrans;
|
Split *s;
|
||||||
Transaction *nextTrans;
|
Split *prevSplit;
|
||||||
|
Split *nextSplit;
|
||||||
int position;
|
int position;
|
||||||
|
|
||||||
if (NULL == acc) return 0;
|
if (NULL == acc) return 0;
|
||||||
|
|
||||||
position = getNumOfTransaction (acc, trans);
|
/* find the split's location in the array */
|
||||||
if (-1 == position) {
|
position = 0;
|
||||||
printf ("Internal Error: xaccCheckDateOrder(): \n");
|
s = acc->splits[0];
|
||||||
printf ("transaction not present in the account !\n");
|
while (s) {
|
||||||
|
if (s == split) break;
|
||||||
|
position ++;
|
||||||
|
s = acc->splits[position];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!s) {
|
||||||
|
printf ("Internal Error: xaccCheckDateOrder(): ");
|
||||||
|
printf (" split not present in account \n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
prevTrans = getTransaction( acc, position-1 );
|
prevSplit = acc->splits [position-1];
|
||||||
nextTrans = getTransaction( acc, position+1 );
|
nextSplit = acc->splits [position+1];
|
||||||
|
|
||||||
/* figure out if the transactions are out of order */
|
/* figure out if the transactions are out of order */
|
||||||
if (NULL != prevTrans) {
|
if (NULL != prevSplit) {
|
||||||
if( xaccTransOrder (&prevTrans, &trans) >0 ) outOfOrder = True;
|
if( xaccTransOrder (&(prevSplit->parent), &(split->parent)) >0 ) outOfOrder = True;
|
||||||
}
|
}
|
||||||
if (NULL != nextTrans) {
|
if (NULL != nextSplit) {
|
||||||
if( xaccTransOrder (&trans, &nextTrans) >0 ) outOfOrder = True;
|
if( xaccTransOrder (&(split->parent), &(nextSplit->parent)) >0 ) outOfOrder = True;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* take care of re-ordering, if necessary */
|
/* take care of re-ordering, if necessary */
|
||||||
if( outOfOrder ) {
|
if( outOfOrder ) {
|
||||||
removeTransaction( acc, position );
|
removeTransaction( acc, position );
|
||||||
insertTransaction( acc, trans );
|
insertTransaction( acc, split );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -902,8 +517,8 @@ xaccConsolidateTransactions (Account * acc)
|
|||||||
if (strcmp (ta->description, tb->description)) continue;
|
if (strcmp (ta->description, tb->description)) continue;
|
||||||
if (strcmp (ta->credit_split.memo, tb->credit_split.memo)) continue;
|
if (strcmp (ta->credit_split.memo, tb->credit_split.memo)) continue;
|
||||||
if (strcmp (ta->action, tb->action)) continue;
|
if (strcmp (ta->action, tb->action)) continue;
|
||||||
if (0 == DEQ(ta->damount, tb->damount)) continue;
|
if (0 == DEQ(ta->credit_split.damount, tb->credit_split.damount)) continue;
|
||||||
if (0 == DEQ(ta->share_price, tb->share_price)) continue;
|
if (0 == DEQ(ta->credit_split.share_price, tb->credit_split.share_price)) continue;
|
||||||
|
|
||||||
/* if we got to here, then there must be a duplicate. */
|
/* if we got to here, then there must be a duplicate. */
|
||||||
/* before deleting it, remove it from the other
|
/* before deleting it, remove it from the other
|
||||||
|
@ -308,17 +308,14 @@ adjBOkCB( Widget mw, XtPointer cd, XtPointer cb )
|
|||||||
xaccTransSetDescription (trans, ADJ_BALN_STR);
|
xaccTransSetDescription (trans, ADJ_BALN_STR);
|
||||||
xaccTransSetReconcile (trans, NREC);
|
xaccTransSetReconcile (trans, NREC);
|
||||||
|
|
||||||
pos = insertTransaction( acc, trans );
|
xaccInsertSplit (acc, &(trans->credit_split));
|
||||||
|
|
||||||
/* figure out what the amount for this transaction... figure out
|
/* compute the dollar amount this transaction should have.
|
||||||
* the current balance, and take the diff from amount */
|
* it will be the difference between the current balance, and
|
||||||
dcurrAmount = 0.0;
|
* the desired balance. */
|
||||||
for( i=0; i<pos; i++ )
|
dcurrAmount = xaccGetBalance (&(trans->credit_split));
|
||||||
{
|
|
||||||
tempTrans = getTransaction(acc,i);
|
xaccSetAmount (split, dcurrAmount - themount);
|
||||||
dcurrAmount += xaccGetAmount (acc, tempTrans);
|
|
||||||
}
|
|
||||||
xaccSetAmount (acc, trans, themount - dcurrAmount);
|
|
||||||
|
|
||||||
/* Refresh the account register window */
|
/* Refresh the account register window */
|
||||||
regRefresh(acc->regData);
|
regRefresh(acc->regData);
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
\********************************************************************/
|
\********************************************************************/
|
||||||
|
|
||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
* initSplit
|
* xaccInitSplit
|
||||||
* Initialize a splitaction structure
|
* Initialize a splitaction structure
|
||||||
\********************************************************************/
|
\********************************************************************/
|
||||||
|
|
||||||
@ -113,6 +113,47 @@ xaccCountSplits (Split **tarray)
|
|||||||
return nsplit;
|
return nsplit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************\
|
||||||
|
\********************************************************************/
|
||||||
|
|
||||||
|
void xaccSetShareAmount (Split *s, double amt)
|
||||||
|
{
|
||||||
|
s -> damount = amt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void xaccSetAmount (Split *s, double amt)
|
||||||
|
{
|
||||||
|
/* remember, damount is actually share price */
|
||||||
|
s -> damount = amt / (s->share_price);
|
||||||
|
}
|
||||||
|
|
||||||
|
/********************************************************************\
|
||||||
|
\********************************************************************/
|
||||||
|
|
||||||
|
double xaccGetBalance (Split *s)
|
||||||
|
{
|
||||||
|
if (!s) return 0.0;
|
||||||
|
return s->balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
double xaccGetClearedBalance (Split *s)
|
||||||
|
{
|
||||||
|
if (!s) return 0.0;
|
||||||
|
return s->cleared_balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
double xaccGetReconciledBalance (Split *s)
|
||||||
|
{
|
||||||
|
if (!s) return 0.0;
|
||||||
|
return s->reconciled_balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
double xaccGetShareBalance (Split *s)
|
||||||
|
{
|
||||||
|
if (!s) return 0.0;
|
||||||
|
return s->share_balance;
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
* initTransaction
|
* initTransaction
|
||||||
* Initialize a transaction structure
|
* Initialize a transaction structure
|
||||||
@ -199,6 +240,38 @@ implemented and tested.
|
|||||||
_free(trans);
|
_free(trans);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************\
|
||||||
|
* Walk the debit-splits array, and compute the new
|
||||||
|
* credit amounts based on that.
|
||||||
|
\********************************************************************/
|
||||||
|
|
||||||
|
void
|
||||||
|
xaccTransRecomputeAmount (Transaction *trans)
|
||||||
|
{
|
||||||
|
Split *s;
|
||||||
|
int i = 0;
|
||||||
|
double amount = 0.0;
|
||||||
|
|
||||||
|
s = trans->debit_splits[i];
|
||||||
|
while (s) {
|
||||||
|
amount += s->share_price * s->damount;
|
||||||
|
i++;
|
||||||
|
s = trans->debit_splits[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if there is just one split, then the credited
|
||||||
|
* and the debited splits should match up. */
|
||||||
|
if (1 == i) {
|
||||||
|
s = trans->debit_splits[0];
|
||||||
|
trans -> credit_split.damount = - (s->damount);
|
||||||
|
trans -> credit_split.share_price = s->share_price;
|
||||||
|
} else {
|
||||||
|
trans -> credit_split.damount = -amount;
|
||||||
|
trans -> credit_split.share_price = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
\********************************************************************/
|
\********************************************************************/
|
||||||
void
|
void
|
||||||
@ -210,6 +283,7 @@ xaccAppendSplit (Transaction *trans, Split *split)
|
|||||||
if (!trans) return;
|
if (!trans) return;
|
||||||
if (!split) return;
|
if (!split) return;
|
||||||
|
|
||||||
|
/* first, insert the split into the array */
|
||||||
split->parent = (struct _transaction *) trans;
|
split->parent = (struct _transaction *) trans;
|
||||||
num = xaccCountSplits (trans->debit_splits);
|
num = xaccCountSplits (trans->debit_splits);
|
||||||
|
|
||||||
@ -222,6 +296,9 @@ xaccAppendSplit (Transaction *trans, Split *split)
|
|||||||
trans->debit_splits[num+1] = NULL;
|
trans->debit_splits[num+1] = NULL;
|
||||||
|
|
||||||
if (oldarray) _free (oldarray);
|
if (oldarray) _free (oldarray);
|
||||||
|
|
||||||
|
/* bring dollar amounts into synchrony */
|
||||||
|
xaccTransRecomputeAmount (trans);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
@ -250,6 +327,9 @@ xaccRemoveSplit (Split *split)
|
|||||||
}
|
}
|
||||||
trans->debit_splits[i] = NULL;
|
trans->debit_splits[i] = NULL;
|
||||||
|
|
||||||
|
/* bring dollar amounts into synchrony */
|
||||||
|
xaccTransRecomputeAmount (trans);
|
||||||
|
|
||||||
/* hack alert -- we should also remove it from the account */
|
/* hack alert -- we should also remove it from the account */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user