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
557
src/Account.c
557
src/Account.c
@ -66,11 +66,6 @@ mallocAccount( void )
|
||||
acc->description = 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->splits = (Split **) _malloc (sizeof (Split *));
|
||||
acc->splits[0] = NULL;
|
||||
@ -95,8 +90,10 @@ mallocAccount( void )
|
||||
void
|
||||
freeAccount( Account *acc )
|
||||
{
|
||||
int i;
|
||||
Split *s;
|
||||
int i=0, j=0;
|
||||
Split *s, *debit_s;
|
||||
int dont_free_transaction = 0;
|
||||
struct _account * _acc = (struct _account *) acc;
|
||||
|
||||
if (NULL == acc) return;
|
||||
|
||||
@ -109,40 +106,40 @@ freeAccount( Account *acc )
|
||||
|
||||
freeQuickFill(acc->qfRoot);
|
||||
|
||||
/* free up splits */
|
||||
/* 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. */
|
||||
/* any split pointing at this account needs to be unmarked */
|
||||
i=0;
|
||||
s = acc->splits[0];
|
||||
while (s) {
|
||||
struct _account * _acc = (struct _account *) acc;
|
||||
if (_acc == s->acc) s->acc = NULL;
|
||||
s->acc = NULL;
|
||||
i++;
|
||||
s = acc->splits[i];
|
||||
}
|
||||
_free (acc->splits);
|
||||
acc->numSplits = 0;
|
||||
|
||||
/* free transactions */
|
||||
for( i=0; i<acc->numTrans; i++ ) {
|
||||
Transaction *trans = acc->transaction[i];
|
||||
struct _account * _acc = (struct _account *) acc;
|
||||
|
||||
if (!trans) continue;
|
||||
/* free the transaction only if its not
|
||||
* a part of a double entry */
|
||||
if (_acc == trans->credit_split.acc) trans->credit_split.acc = NULL;
|
||||
if (_acc == trans->debit) trans->debit = NULL;
|
||||
if ( (NULL == trans->debit) && (NULL == trans->credit_split.acc) ) {
|
||||
/* search for orphaned transactions, and delete them */
|
||||
i=0;
|
||||
s = acc->splits[0];
|
||||
while (s) {
|
||||
Transaction *trans = (Transaction *) s->parent;
|
||||
|
||||
j=0;
|
||||
debit_s = trans->debit_splits[0];
|
||||
while (debit_s) {
|
||||
if (debit_s->acc) { dont_free_transaction = 1; break; }
|
||||
j++;
|
||||
debit_s = trans->debit_splits[j];
|
||||
}
|
||||
|
||||
if ( (!dont_free_transaction) && (NULL == trans->credit_split.acc) ) {
|
||||
freeTransaction( trans );
|
||||
}
|
||||
|
||||
i++;
|
||||
s = acc->splits[i];
|
||||
}
|
||||
|
||||
|
||||
/* free the array of pointers */
|
||||
_free( acc->transaction );
|
||||
/* free up array of split pointers */
|
||||
_free (acc->splits);
|
||||
acc->splits = NULL;
|
||||
|
||||
/* zero out values, just in case stray
|
||||
* pointers are pointing here. */
|
||||
@ -160,9 +157,6 @@ freeAccount( Account *acc )
|
||||
acc->description = NULL;
|
||||
acc->notes = NULL;
|
||||
|
||||
acc->numTrans = 0;
|
||||
acc->transaction = NULL;
|
||||
|
||||
/* hack alert -- shouldn't we destroy this widget ??? */
|
||||
acc->arrowb = NULL;
|
||||
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
|
||||
xaccInsertSplit ( Account *acc, Split *split )
|
||||
{
|
||||
@ -440,184 +242,7 @@ xaccInsertSplit ( Account *acc, Split *split )
|
||||
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 *
|
||||
* recomputes the partial balances and the current balance for *
|
||||
@ -649,7 +274,7 @@ double xaccGetShareBalance (Account *acc, Transaction *trans)
|
||||
void
|
||||
xaccRecomputeBalance( Account * acc )
|
||||
{
|
||||
int i;
|
||||
int i = 0;
|
||||
double dbalance = 0.0;
|
||||
double dcleared_balance = 0.0;
|
||||
double dreconciled_balance = 0.0;
|
||||
@ -657,75 +282,56 @@ xaccRecomputeBalance( Account * acc )
|
||||
double share_cleared_balance = 0.0;
|
||||
double share_reconciled_balance = 0.0;
|
||||
double amt = 0.0;
|
||||
Transaction *trans, *last_trans=NULL;
|
||||
Account *tracc;
|
||||
Split *split, *last_split;
|
||||
|
||||
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 */
|
||||
amt = xaccGetShareAmount (acc, trans);
|
||||
amt = split->damount;
|
||||
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;
|
||||
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;
|
||||
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
|
||||
* amount. For stock accoounts, the invarient is the share amount */
|
||||
if ( (STOCK == tracc->type) || ( MUTUAL == tracc->type) ) {
|
||||
trans -> credit_share_balance = share_balance;
|
||||
trans -> credit_share_cleared_balance = share_cleared_balance;
|
||||
trans -> credit_share_reconciled_balance = share_reconciled_balance;
|
||||
trans -> credit_balance = trans->share_price * share_balance;
|
||||
trans -> credit_cleared_balance = trans->share_price * share_cleared_balance;
|
||||
trans -> credit_reconciled_balance = trans->share_price * share_reconciled_balance;
|
||||
} else {
|
||||
trans -> credit_share_balance = dbalance;
|
||||
trans -> credit_share_cleared_balance = dcleared_balance;
|
||||
trans -> credit_share_reconciled_balance = dreconciled_balance;
|
||||
trans -> credit_balance = dbalance;
|
||||
trans -> credit_cleared_balance = dcleared_balance;
|
||||
trans -> credit_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;
|
||||
}
|
||||
/* For bank accounts, the invarient subtotal is the dollar
|
||||
* amount. For stock accoounts, the invarient is the share amount */
|
||||
if ( (STOCK == acc->type) || ( MUTUAL == acc->type) ) {
|
||||
split -> share_balance = share_balance;
|
||||
split -> share_cleared_balance = share_cleared_balance;
|
||||
split -> share_reconciled_balance = share_reconciled_balance;
|
||||
split -> balance = split->share_price * share_balance;
|
||||
split -> cleared_balance = split->share_price * share_cleared_balance;
|
||||
split -> reconciled_balance = split->share_price * share_reconciled_balance;
|
||||
} else {
|
||||
split -> share_balance = dbalance;
|
||||
split -> share_cleared_balance = dcleared_balance;
|
||||
split -> share_reconciled_balance = dreconciled_balance;
|
||||
split -> balance = dbalance;
|
||||
split -> cleared_balance = dcleared_balance;
|
||||
split -> reconciled_balance = dreconciled_balance;
|
||||
}
|
||||
|
||||
last_trans = trans;
|
||||
last_split = split;
|
||||
i++;
|
||||
split = acc->splits[i];
|
||||
}
|
||||
|
||||
if ( (STOCK == acc->type) || ( MUTUAL == acc->type) ) {
|
||||
if (last_trans) {
|
||||
acc -> balance = share_balance * (last_trans->share_price);
|
||||
acc -> cleared_balance = share_cleared_balance * (last_trans->share_price);
|
||||
acc -> reconciled_balance = share_reconciled_balance * (last_trans->share_price);
|
||||
if (last_split) {
|
||||
acc -> balance = share_balance * (last_split->share_price);
|
||||
acc -> cleared_balance = share_cleared_balance * (last_split->share_price);
|
||||
acc -> reconciled_balance = share_reconciled_balance * (last_split->share_price);
|
||||
} else {
|
||||
acc -> balance = 0.0;
|
||||
acc -> cleared_balance = 0.0;
|
||||
@ -752,37 +358,46 @@ xaccRecomputeBalance( Account * acc )
|
||||
\********************************************************************/
|
||||
|
||||
int
|
||||
xaccCheckDateOrder (Account * acc, Transaction *trans )
|
||||
xaccCheckDateOrder (Account * acc, Split *split )
|
||||
{
|
||||
int outOfOrder = 0;
|
||||
Transaction *prevTrans;
|
||||
Transaction *nextTrans;
|
||||
Split *s;
|
||||
Split *prevSplit;
|
||||
Split *nextSplit;
|
||||
int position;
|
||||
|
||||
if (NULL == acc) return 0;
|
||||
|
||||
position = getNumOfTransaction (acc, trans);
|
||||
if (-1 == position) {
|
||||
printf ("Internal Error: xaccCheckDateOrder(): \n");
|
||||
printf ("transaction not present in the account !\n");
|
||||
return 0;
|
||||
/* find the split's location in the array */
|
||||
position = 0;
|
||||
s = acc->splits[0];
|
||||
while (s) {
|
||||
if (s == split) break;
|
||||
position ++;
|
||||
s = acc->splits[position];
|
||||
}
|
||||
|
||||
prevTrans = getTransaction( acc, position-1 );
|
||||
nextTrans = getTransaction( acc, position+1 );
|
||||
if (!s) {
|
||||
printf ("Internal Error: xaccCheckDateOrder(): ");
|
||||
printf (" split not present in account \n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
prevSplit = acc->splits [position-1];
|
||||
nextSplit = acc->splits [position+1];
|
||||
|
||||
/* figure out if the transactions are out of order */
|
||||
if (NULL != prevTrans) {
|
||||
if( xaccTransOrder (&prevTrans, &trans) >0 ) outOfOrder = True;
|
||||
if (NULL != prevSplit) {
|
||||
if( xaccTransOrder (&(prevSplit->parent), &(split->parent)) >0 ) outOfOrder = True;
|
||||
}
|
||||
if (NULL != nextTrans) {
|
||||
if( xaccTransOrder (&trans, &nextTrans) >0 ) outOfOrder = True;
|
||||
if (NULL != nextSplit) {
|
||||
if( xaccTransOrder (&(split->parent), &(nextSplit->parent)) >0 ) outOfOrder = True;
|
||||
}
|
||||
|
||||
/* take care of re-ordering, if necessary */
|
||||
if( outOfOrder ) {
|
||||
removeTransaction( acc, position );
|
||||
insertTransaction( acc, trans );
|
||||
insertTransaction( acc, split );
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@ -902,8 +517,8 @@ xaccConsolidateTransactions (Account * acc)
|
||||
if (strcmp (ta->description, tb->description)) continue;
|
||||
if (strcmp (ta->credit_split.memo, tb->credit_split.memo)) continue;
|
||||
if (strcmp (ta->action, tb->action)) continue;
|
||||
if (0 == DEQ(ta->damount, tb->damount)) continue;
|
||||
if (0 == DEQ(ta->share_price, tb->share_price)) continue;
|
||||
if (0 == DEQ(ta->credit_split.damount, tb->credit_split.damount)) 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. */
|
||||
/* before deleting it, remove it from the other
|
||||
|
@ -307,18 +307,15 @@ adjBOkCB( Widget mw, XtPointer cd, XtPointer cb )
|
||||
/* fill out the rest of the fields */
|
||||
xaccTransSetDescription (trans, ADJ_BALN_STR);
|
||||
xaccTransSetReconcile (trans, NREC);
|
||||
|
||||
pos = insertTransaction( acc, trans );
|
||||
|
||||
/* figure out what the amount for this transaction... figure out
|
||||
* the current balance, and take the diff from amount */
|
||||
dcurrAmount = 0.0;
|
||||
for( i=0; i<pos; i++ )
|
||||
{
|
||||
tempTrans = getTransaction(acc,i);
|
||||
dcurrAmount += xaccGetAmount (acc, tempTrans);
|
||||
}
|
||||
xaccSetAmount (acc, trans, themount - dcurrAmount);
|
||||
|
||||
xaccInsertSplit (acc, &(trans->credit_split));
|
||||
|
||||
/* compute the dollar amount this transaction should have.
|
||||
* it will be the difference between the current balance, and
|
||||
* the desired balance. */
|
||||
dcurrAmount = xaccGetBalance (&(trans->credit_split));
|
||||
|
||||
xaccSetAmount (split, dcurrAmount - themount);
|
||||
|
||||
/* Refresh the account register window */
|
||||
regRefresh(acc->regData);
|
||||
|
@ -37,7 +37,7 @@
|
||||
\********************************************************************/
|
||||
|
||||
/********************************************************************\
|
||||
* initSplit
|
||||
* xaccInitSplit
|
||||
* Initialize a splitaction structure
|
||||
\********************************************************************/
|
||||
|
||||
@ -113,6 +113,47 @@ xaccCountSplits (Split **tarray)
|
||||
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
|
||||
* Initialize a transaction structure
|
||||
@ -199,6 +240,38 @@ implemented and tested.
|
||||
_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
|
||||
@ -210,6 +283,7 @@ xaccAppendSplit (Transaction *trans, Split *split)
|
||||
if (!trans) return;
|
||||
if (!split) return;
|
||||
|
||||
/* first, insert the split into the array */
|
||||
split->parent = (struct _transaction *) trans;
|
||||
num = xaccCountSplits (trans->debit_splits);
|
||||
|
||||
@ -222,6 +296,9 @@ xaccAppendSplit (Transaction *trans, Split *split)
|
||||
trans->debit_splits[num+1] = NULL;
|
||||
|
||||
if (oldarray) _free (oldarray);
|
||||
|
||||
/* bring dollar amounts into synchrony */
|
||||
xaccTransRecomputeAmount (trans);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
@ -250,6 +327,9 @@ xaccRemoveSplit (Split *split)
|
||||
}
|
||||
trans->debit_splits[i] = NULL;
|
||||
|
||||
/* bring dollar amounts into synchrony */
|
||||
xaccTransRecomputeAmount (trans);
|
||||
|
||||
/* hack alert -- we should also remove it from the account */
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user