rename debit & credit splits to be source & dest splits

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@596 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Linas Vepstas 1998-03-07 21:55:07 +00:00
parent 069acf2e0b
commit 3e1327e7a0
7 changed files with 174 additions and 131 deletions

View File

@ -47,14 +47,14 @@ GetOtherAccName (Split *split)
Transaction *trans; Transaction *trans;
trans = (Transaction *) (split->parent); trans = (Transaction *) (split->parent);
if (split != &(trans->credit_split)) { if (split != &(trans->source_split)) {
acc = (Account *) trans->credit_split.acc; acc = (Account *) trans->source_split.acc;
} else { } else {
if (trans->debit_splits) { if (trans->dest_splits) {
if (NULL != trans->debit_splits[0]) { if (NULL != trans->dest_splits[0]) {
/* if only one split, then use that */ /* if only one split, then use that */
if (NULL == trans->debit_splits[1]) { if (NULL == trans->dest_splits[1]) {
acc = (Account *) trans->debit_splits[0]->acc; acc = (Account *) trans->dest_splits[0]->acc;
} else { } else {
return SPLIT_STR; return SPLIT_STR;
} }
@ -227,7 +227,7 @@ printf ("load reg of %d entries --------------------------- \n",i);
todaysDate (&(trans->date)); todaysDate (&(trans->date));
table->current_cursor_row = i; table->current_cursor_row = i;
table->current_cursor_col = 0; table->current_cursor_col = 0;
xaccLoadRegEntry (reg, &(trans->credit_split)); xaccLoadRegEntry (reg, &(trans->source_split));
i++; i++;
/* restore the cursor to it original location */ /* restore the cursor to it original location */

View File

@ -1,7 +1,7 @@
/********************************************************************\ /********************************************************************\
* Account.c -- the Account data structure * * Account.c -- the Account data structure *
* Copyright (C) 1997 Robin D. Clark * * Copyright (C) 1997 Robin D. Clark *
* Copyright (C) 1997 Linas Vepstas * * Copyright (C) 1997, 1998 Linas Vepstas *
* * * *
* This program is free software; you can redistribute it and/or * * This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as * * modify it under the terms of the GNU General Public License as *
@ -126,14 +126,14 @@ xaccFreeAccount( Account *acc )
Transaction *trans = (Transaction *) s->parent; Transaction *trans = (Transaction *) s->parent;
j=0; j=0;
debit_s = trans->debit_splits[0]; debit_s = trans->dest_splits[0];
while (debit_s) { while (debit_s) {
if (debit_s->acc) { dont_free_transaction = 1; break; } if (debit_s->acc) { dont_free_transaction = 1; break; }
j++; j++;
debit_s = trans->debit_splits[j]; debit_s = trans->dest_splits[j];
} }
if ( (!dont_free_transaction) && (NULL == trans->credit_split.acc) ) { if ( (!dont_free_transaction) && (NULL == trans->source_split.acc) ) {
xaccFreeTransaction( trans ); xaccFreeTransaction( trans );
} }
@ -449,16 +449,16 @@ xaccCheckTransDateOrder (Transaction *trans )
if (NULL == trans) return 0; if (NULL == trans) return 0;
acc = (Account *) (trans->credit_split.acc); acc = (Account *) (trans->source_split.acc);
outOfOrder += xaccCheckDateOrder (acc, &(trans->credit_split)); outOfOrder += xaccCheckDateOrder (acc, &(trans->source_split));
i=0; i=0;
s = trans->debit_splits[0]; s = trans->dest_splits[0];
while (s) { while (s) {
acc = (Account *) (s->acc); acc = (Account *) (s->acc);
outOfOrder += xaccCheckDateOrder (acc, s); outOfOrder += xaccCheckDateOrder (acc, s);
i++; i++;
s = trans->debit_splits[i]; s = trans->dest_splits[i];
} }
if (outOfOrder) return 1; if (outOfOrder) return 1;
@ -539,14 +539,14 @@ xaccMoveFarEnd (Split *split, Account *new_acc)
* then move the far end of the split to the new location. * then move the far end of the split to the new location.
*/ */
trans = (Transaction *) (split->parent); trans = (Transaction *) (split->parent);
if (split != &(trans->credit_split)) { if (split != &(trans->source_split)) {
partner_split = &(trans->credit_split); partner_split = &(trans->source_split);
} else { } else {
/* perform that transfer *only* if there is one split */ /* perform that transfer *only* if there is one split */
if (trans->debit_splits) { if (trans->dest_splits) {
if (0x0 != trans->debit_splits[0]) { if (0x0 != trans->dest_splits[0]) {
if (0x0 == trans->debit_splits[1]) { if (0x0 == trans->dest_splits[1]) {
partner_split = trans->debit_splits[0]; partner_split = trans->dest_splits[0];
} }
} }
} }

View File

@ -46,7 +46,7 @@
* Account ::== accID flags type accountName description * * Account ::== accID flags type accountName description *
* notes numTran (Transaction)^numTrans * * notes numTran (Transaction)^numTrans *
* numGroups (Group)^numGroups * * numGroups (Group)^numGroups *
* Transaction ::== num date description credit_split * * Transaction ::== num date description source_split *
* numSplits (Split)^numSplits * * numSplits (Split)^numSplits *
* Split ::== memo action reconciled * * Split ::== memo action reconciled *
* amount share_price account * * amount share_price account *
@ -577,7 +577,7 @@ readTransaction( int fd, Account *acc, int token )
* aren't reconciled until you get your bank statement, and * aren't reconciled until you get your bank statement, and
* use the reconcile window to mark the transaction reconciled * use the reconcile window to mark the transaction reconciled
*/ */
if( YREC == trans->credit_split.reconciled ) { if( YREC == trans->source_split.reconciled ) {
xaccTransSetReconcile (trans, CREC); xaccTransSetReconcile (trans, CREC);
} }
} }
@ -586,9 +586,9 @@ readTransaction( int fd, Account *acc, int token )
* I have to do this mainly for if I change what NREC and * I have to do this mainly for if I change what NREC and
* YREC are defined to be... this way it might loose all * YREC are defined to be... this way it might loose all
* the reconciled data, but at least the field is valid */ * the reconciled data, but at least the field is valid */
if( (YREC != trans->credit_split.reconciled) && if( (YREC != trans->source_split.reconciled) &&
(FREC != trans->credit_split.reconciled) && (FREC != trans->source_split.reconciled) &&
(CREC != trans->credit_split.reconciled) ) { (CREC != trans->source_split.reconciled) ) {
xaccTransSetReconcile (trans, NREC); xaccTransSetReconcile (trans, NREC);
} }
@ -607,7 +607,7 @@ readTransaction( int fd, Account *acc, int token )
} }
XACC_FLIP_INT (amount); XACC_FLIP_INT (amount);
num_shares = 0.01 * ((double) amount); /* file stores pennies */ num_shares = 0.01 * ((double) amount); /* file stores pennies */
trans->credit_split.damount = num_shares; trans->source_split.damount = num_shares;
} else { } else {
double damount; double damount;
@ -621,7 +621,7 @@ readTransaction( int fd, Account *acc, int token )
} }
XACC_FLIP_DOUBLE (damount); XACC_FLIP_DOUBLE (damount);
num_shares = damount; num_shares = damount;
trans->credit_split.damount = num_shares; trans->source_split.damount = num_shares;
/* ... next read the share price ... */ /* ... next read the share price ... */
err = read( fd, &damount, sizeof(double) ); err = read( fd, &damount, sizeof(double) );
@ -633,7 +633,7 @@ readTransaction( int fd, Account *acc, int token )
} }
XACC_FLIP_DOUBLE (damount); XACC_FLIP_DOUBLE (damount);
share_price = damount; share_price = damount;
trans->credit_split.share_price = share_price; trans->source_split.share_price = share_price;
} }
INFO_2 ("readTransaction(): num_shares %f \n", num_shares); INFO_2 ("readTransaction(): num_shares %f \n", num_shares);
@ -653,11 +653,11 @@ readTransaction( int fd, Account *acc, int token )
XACC_FLIP_INT (acc_id); XACC_FLIP_INT (acc_id);
INFO_2 ("readTransaction(): credit %d\n", acc_id); INFO_2 ("readTransaction(): credit %d\n", acc_id);
peer_acc = locateAccount (acc_id); peer_acc = locateAccount (acc_id);
trans -> credit_split.acc = (struct _account *) peer_acc; trans -> source_split.acc = (struct _account *) peer_acc;
/* insert the split part of the transaction into /* insert the split part of the transaction into
* the credited account */ * the credited account */
if (peer_acc) xaccInsertSplit( peer_acc, &(trans->credit_split) ); if (peer_acc) xaccInsertSplit( peer_acc, &(trans->source_split) );
/* next read the debit account number */ /* next read the debit account number */
err = read( fd, &acc_id, sizeof(int) ); err = read( fd, &acc_id, sizeof(int) );
@ -680,33 +680,33 @@ readTransaction( int fd, Account *acc, int token )
/* duplicate many of the attributes in the credit split */ /* duplicate many of the attributes in the credit split */
split->damount = -num_shares; split->damount = -num_shares;
split->share_price = share_price; split->share_price = share_price;
split->reconciled = trans->credit_split.reconciled; split->reconciled = trans->source_split.reconciled;
free (split->memo); free (split->memo);
split->memo = strdup (trans->credit_split.memo); split->memo = strdup (trans->source_split.memo);
free (split->action); free (split->action);
split->action = strdup (trans->credit_split.action); split->action = strdup (trans->source_split.action);
} }
} else { } else {
/* Version 1 files did not do double-entry */ /* Version 1 files did not do double-entry */
xaccInsertSplit( acc, &(trans->credit_split) ); xaccInsertSplit( acc, &(trans->source_split) );
} }
} else { /* else, read version-5 files */ } else { /* else, read version-5 files */
Split *split; Split *split;
/* first, read the credit split, and copy it in place */ /* first, read the credit split, and copy it in place */
split = readSplit (fd, token); split = readSplit (fd, token);
xaccSplitSetMemo ( &(trans->credit_split), split->memo); xaccSplitSetMemo ( &(trans->source_split), split->memo);
xaccSplitSetAction ( &(trans->credit_split), split->action); xaccSplitSetAction ( &(trans->source_split), split->action);
xaccSplitSetReconcile ( &(trans->credit_split), split->reconciled); xaccSplitSetReconcile ( &(trans->source_split), split->reconciled);
trans->credit_split.damount = split->damount; trans->source_split.damount = split->damount;
trans->credit_split.share_price = split->share_price; trans->source_split.share_price = split->share_price;
trans->credit_split.acc = split->acc; trans->source_split.acc = split->acc;
trans->credit_split.parent = trans; trans->source_split.parent = trans;
/* then wire it into place */ /* then wire it into place */
xaccInsertSplit( ((Account *) (trans->credit_split.acc)), &(trans->credit_split) ); xaccInsertSplit( ((Account *) (trans->source_split.acc)), &(trans->source_split) );
/* free the thing that the read returned */ /* free the thing that the read returned */
split->acc = NULL; split->acc = NULL;
@ -1176,15 +1176,15 @@ writeTransaction( int fd, Transaction *trans )
err = writeString( fd, trans->description ); err = writeString( fd, trans->description );
if( -1 == err ) return err; if( -1 == err ) return err;
err = writeSplit( fd, &(trans->credit_split) ); err = writeSplit( fd, &(trans->source_split) );
if( -1 == err ) return err; if( -1 == err ) return err;
/* count the number of splits */ /* count the number of splits */
i = 0; i = 0;
s = trans->debit_splits[i]; s = trans->dest_splits[i];
while (s) { while (s) {
i++; i++;
s = trans->debit_splits[i]; s = trans->dest_splits[i];
} }
XACC_FLIP_INT (i); XACC_FLIP_INT (i);
err = write( fd, &i, sizeof(int) ); err = write( fd, &i, sizeof(int) );
@ -1192,12 +1192,12 @@ writeTransaction( int fd, Transaction *trans )
/* now write the splits */ /* now write the splits */
i = 0; i = 0;
s = trans->debit_splits[i]; s = trans->dest_splits[i];
while (s) { while (s) {
err = writeSplit (fd, s); err = writeSplit (fd, s);
if( -1 == err ) return err; if( -1 == err ) return err;
i++; i++;
s = trans->debit_splits[i]; s = trans->dest_splits[i];
} }
return err; return err;

View File

@ -577,7 +577,7 @@ xaccGetSecurityQIFAccount (Account *acc, char *qifline)
#define XACC_ACTION(q,x) \ #define XACC_ACTION(q,x) \
if (!strncmp (&qifline[1], q, strlen(q))) { \ if (!strncmp (&qifline[1], q, strlen(q))) { \
trans->credit_split.action = strdup(x); \ trans->source_split.action = strdup(x); \
} else } else
@ -626,7 +626,7 @@ char * xaccReadQIFTransaction (int fd, Account *acc)
/* I == share price */ /* I == share price */
if ('I' == qifline [0]) { if ('I' == qifline [0]) {
trans -> credit_split.share_price = xaccParseUSAmount (&qifline[1]); trans -> source_split.share_price = xaccParseUSAmount (&qifline[1]);
} else } else
/* L == name of acount from which transfer occured */ /* L == name of acount from which transfer occured */
@ -637,7 +637,7 @@ char * xaccReadQIFTransaction (int fd, Account *acc)
/* M == memo field */ /* M == memo field */
if ('M' == qifline [0]) { if ('M' == qifline [0]) {
XACC_PREP_STRING (trans->credit_split.memo); XACC_PREP_STRING (trans->source_split.memo);
} else } else
/* N == check numbers for Banks, but Action for portfolios */ /* N == check numbers for Banks, but Action for portfolios */
@ -670,7 +670,7 @@ char * xaccReadQIFTransaction (int fd, Account *acc)
if ('O' == qifline [0]) { if ('O' == qifline [0]) {
double pute; double pute;
adjust = xaccParseUSAmount (&qifline[1]); adjust = xaccParseUSAmount (&qifline[1]);
pute = (trans->credit_split.damount) * (trans->credit_split.share_price); pute = (trans->source_split.damount) * (trans->source_split.share_price);
if (isneg) pute = -pute; if (isneg) pute = -pute;
printf ("QIF Warning: Adjustment of %.2f to amount %.2f not handled \n", adjust, pute); printf ("QIF Warning: Adjustment of %.2f to amount %.2f not handled \n", adjust, pute);
@ -683,8 +683,8 @@ char * xaccReadQIFTransaction (int fd, Account *acc)
/* Q == number of shares */ /* Q == number of shares */
if ('Q' == qifline [0]) { if ('Q' == qifline [0]) {
trans -> credit_split.damount = xaccParseUSAmount (&qifline[1]); trans -> source_split.damount = xaccParseUSAmount (&qifline[1]);
if (isneg) trans -> credit_split.damount = - (trans->credit_split.damount); if (isneg) trans -> source_split.damount = - (trans->source_split.damount);
got_share_quantity = 1; got_share_quantity = 1;
} else } else
@ -709,8 +709,8 @@ char * xaccReadQIFTransaction (int fd, Account *acc)
if ('T' == qifline [0]) { if ('T' == qifline [0]) {
/* ignore T for stock transactions, since T is a dollar amount */ /* ignore T for stock transactions, since T is a dollar amount */
if (0 == got_share_quantity) { if (0 == got_share_quantity) {
trans -> credit_split.damount = xaccParseUSAmount (&qifline[1]); trans -> source_split.damount = xaccParseUSAmount (&qifline[1]);
if (isneg) trans -> credit_split.damount = - (trans->credit_split.damount); if (isneg) trans -> source_split.damount = - (trans->source_split.damount);
} }
} else } else
@ -742,7 +742,7 @@ char * xaccReadQIFTransaction (int fd, Account *acc)
double parse, pute; double parse, pute;
int got, wanted; int got, wanted;
parse = xaccParseUSAmount (&qifline[1]); parse = xaccParseUSAmount (&qifline[1]);
pute = (trans->credit_split.damount) * (trans->credit_split.share_price); pute = (trans->source_split.damount) * (trans->source_split.share_price);
if (isneg) pute = -pute; if (isneg) pute = -pute;
wanted = (int) (100.0 * parse + 0.5); wanted = (int) (100.0 * parse + 0.5);
@ -778,8 +778,8 @@ char * xaccReadQIFTransaction (int fd, Account *acc)
XACC_PREP_NULL_STRING (trans->num); XACC_PREP_NULL_STRING (trans->num);
XACC_PREP_NULL_STRING (trans->description); XACC_PREP_NULL_STRING (trans->description);
XACC_PREP_NULL_STRING (trans->credit_split.memo); XACC_PREP_NULL_STRING (trans->source_split.memo);
XACC_PREP_NULL_STRING (trans->credit_split.action); XACC_PREP_NULL_STRING (trans->source_split.action);
/* fundamentally differnt handling for securities and non-securities */ /* fundamentally differnt handling for securities and non-securities */
@ -809,7 +809,7 @@ char * xaccReadQIFTransaction (int fd, Account *acc)
* sub_acc; the security account is credited. * sub_acc; the security account is credited.
* But, just in case its missing, avoid a core dump */ * But, just in case its missing, avoid a core dump */
if (sub_acc) { if (sub_acc) {
trans->credit_split.acc = (struct _account *) sub_acc; trans->source_split.acc = (struct _account *) sub_acc;
xaccInsertSplit (sub_acc, split); xaccInsertSplit (sub_acc, split);
} }
} else { } else {
@ -821,11 +821,11 @@ char * xaccReadQIFTransaction (int fd, Account *acc)
* account gets the dividend credit; otherwise, the * account gets the dividend credit; otherwise, the
* main account gets it */ * main account gets it */
if (xfer_acc) { if (xfer_acc) {
trans->credit_split.acc = (struct _account *) xfer_acc; trans->source_split.acc = (struct _account *) xfer_acc;
xaccInsertSplit (xfer_acc, &(trans->credit_split)); xaccInsertSplit (xfer_acc, &(trans->source_split));
} else { } else {
trans->credit_split.acc = (struct _account *) acc; trans->source_split.acc = (struct _account *) acc;
xaccInsertSplit (acc, &(trans->credit_split)); xaccInsertSplit (acc, &(trans->source_split));
} }
} }
@ -842,8 +842,8 @@ char * xaccReadQIFTransaction (int fd, Account *acc)
} }
/* the transaction itself appears as a credit */ /* the transaction itself appears as a credit */
trans->credit_split.acc = (struct _account *) acc; trans->source_split.acc = (struct _account *) acc;
xaccInsertSplit (acc, &(trans->credit_split)); xaccInsertSplit (acc, &(trans->source_split));
} }
return qifline; return qifline;

View File

@ -1,7 +1,7 @@
/********************************************************************\ /********************************************************************\
* Transaction.c -- the transaction data structure * * Transaction.c -- the transaction data structure *
* Copyright (C) 1997 Robin D. Clark * * Copyright (C) 1997 Robin D. Clark *
* Copyright (C) 1997 Linas Vepstas * * Copyright (C) 1997, 1998 Linas Vepstas *
* * * *
* This program is free software; you can redistribute it and/or * * This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as * * modify it under the terms of the GNU General Public License as *
@ -114,12 +114,12 @@ xaccFreeSplit( Split *split )
static void static void
MarkChanged (Transaction *trans) MarkChanged (Transaction *trans)
{ {
MARK_SPLIT (&(trans->credit_split)); MARK_SPLIT (&(trans->source_split));
if (trans->debit_splits) { if (trans->dest_splits) {
int i=0; int i=0;
while (trans->debit_splits[i]) { while (trans->dest_splits[i]) {
MARK_SPLIT (trans->debit_splits[i]); MARK_SPLIT (trans->dest_splits[i]);
i++; i++;
} }
} }
@ -200,11 +200,11 @@ xaccInitTransaction( Transaction * trans )
trans->num = strdup(""); trans->num = strdup("");
trans->description = strdup(""); trans->description = strdup("");
trans->debit_splits = (Split **) _malloc (sizeof (Split *)); trans->dest_splits = (Split **) _malloc (sizeof (Split *));
trans->debit_splits[0] = NULL; trans->dest_splits[0] = NULL;
xaccInitSplit ( &(trans->credit_split)); xaccInitSplit ( &(trans->source_split));
trans->credit_split.parent = trans; trans->source_split.parent = trans;
trans->date.year = 1900; trans->date.year = 1900;
trans->date.month = 1; trans->date.month = 1;
@ -235,17 +235,17 @@ xaccFreeTransaction( Transaction *trans )
/* free a transaction only if it is not claimed /* free a transaction only if it is not claimed
* by any accounts. */ * by any accounts. */
if (trans->credit_split.acc) return; if (trans->source_split.acc) return;
i = 0; i = 0;
s = trans->debit_splits[i]; s = trans->dest_splits[i];
while (s) { while (s) {
if (s->acc) return; if (s->acc) return;
i++; i++;
s = trans->debit_splits[i]; s = trans->dest_splits[i];
} }
_free (trans->debit_splits); _free (trans->dest_splits);
free(trans->num); free(trans->num);
free(trans->description); free(trans->description);
@ -272,24 +272,24 @@ xaccTransRecomputeAmount (Transaction *trans)
int i = 0; int i = 0;
double amount = 0.0; double amount = 0.0;
s = trans->debit_splits[i]; s = trans->dest_splits[i];
while (s) { while (s) {
amount += s->share_price * s->damount; amount += s->share_price * s->damount;
i++; i++;
s = trans->debit_splits[i]; s = trans->dest_splits[i];
} }
/* if there is just one split, then the credited /* if there is just one split, then the credited
* and the debited splits should match up. */ * and the debited splits should match up. */
if (1 == i) { if (1 == i) {
s = trans->debit_splits[0]; s = trans->dest_splits[0];
trans -> credit_split.damount = - (s->damount); trans -> source_split.damount = - (s->damount);
trans -> credit_split.share_price = s->share_price; trans -> source_split.share_price = s->share_price;
} else { } else {
trans -> credit_split.damount = -amount; trans -> source_split.damount = -amount;
trans -> credit_split.share_price = 1.0; trans -> source_split.share_price = 1.0;
} }
MARK_SPLIT (&(trans->credit_split)); MARK_SPLIT (&(trans->source_split));
} }
/********************************************************************\ /********************************************************************\
@ -306,15 +306,15 @@ xaccTransAppendSplit (Transaction *trans, Split *split)
/* first, insert the split into the array */ /* 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->dest_splits);
oldarray = trans->debit_splits; oldarray = trans->dest_splits;
trans->debit_splits = (Split **) _malloc ((num+2)*sizeof(Split *)); trans->dest_splits = (Split **) _malloc ((num+2)*sizeof(Split *));
for (i=0; i<num; i++) { for (i=0; i<num; i++) {
(trans->debit_splits)[i] = oldarray[i]; (trans->dest_splits)[i] = oldarray[i];
} }
trans->debit_splits[num] = split; trans->dest_splits[num] = split;
trans->debit_splits[num+1] = NULL; trans->dest_splits[num+1] = NULL;
if (oldarray) _free (oldarray); if (oldarray) _free (oldarray);
} }
@ -332,15 +332,15 @@ xaccTransRemoveSplit (Transaction *trans, Split *split)
if (!trans) return; if (!trans) return;
split->parent = NULL; split->parent = NULL;
s = trans->debit_splits[0]; s = trans->dest_splits[0];
while (s) { while (s) {
trans->debit_splits[i] = trans->debit_splits[n]; trans->dest_splits[i] = trans->dest_splits[n];
if (split == s) { i--; } if (split == s) { i--; }
i++; i++;
n++; n++;
s = trans->debit_splits[n]; s = trans->dest_splits[n];
} }
trans->debit_splits[i] = NULL; trans->dest_splits[i] = NULL;
/* bring dollar amounts into synchrony */ /* bring dollar amounts into synchrony */
xaccTransRecomputeAmount (trans); xaccTransRecomputeAmount (trans);
@ -499,15 +499,15 @@ xaccTransSetDate (Transaction *trans, int day, int mon, int year)
* in thier accounts * in thier accounts
*/ */
split = &(trans->credit_split); split = &(trans->source_split);
acc = (Account *) split->acc; acc = (Account *) split->acc;
xaccRemoveSplit (acc, split); xaccRemoveSplit (acc, split);
xaccInsertSplit (acc, split); xaccInsertSplit (acc, split);
xaccRecomputeBalance (acc); xaccRecomputeBalance (acc);
if (trans->debit_splits) { if (trans->dest_splits) {
int i=0; int i=0;
split = trans->debit_splits[i]; split = trans->dest_splits[i];
while (split) { while (split) {
acc = (Account *) split->acc; acc = (Account *) split->acc;
xaccRemoveSplit (acc, split); xaccRemoveSplit (acc, split);
@ -515,7 +515,7 @@ xaccTransSetDate (Transaction *trans, int day, int mon, int year)
xaccRecomputeBalance (acc); xaccRecomputeBalance (acc);
i++; i++;
split = trans->debit_splits[i]; split = trans->dest_splits[i];
} }
} }
} }
@ -543,17 +543,17 @@ xaccTransSetDescription (Transaction *trans, const char *desc)
void void
xaccTransSetMemo (Transaction *trans, const char *memo) xaccTransSetMemo (Transaction *trans, const char *memo)
{ {
if (trans->credit_split.memo) free (trans->credit_split.memo); if (trans->source_split.memo) free (trans->source_split.memo);
trans->credit_split.memo = strdup (memo); trans->source_split.memo = strdup (memo);
MARK_SPLIT (&(trans->credit_split)); MARK_SPLIT (&(trans->source_split));
/* if there is only one split, then keep memos in sync. */ /* if there is only one split, then keep memos in sync. */
if (trans->debit_splits) { if (trans->dest_splits) {
if (0x0 != trans->debit_splits[0]) { if (0x0 != trans->dest_splits[0]) {
if (0x0 == trans->debit_splits[1]) { if (0x0 == trans->dest_splits[1]) {
free (trans->debit_splits[0]->memo); free (trans->dest_splits[0]->memo);
trans->debit_splits[0]->memo = strdup (memo); trans->dest_splits[0]->memo = strdup (memo);
MARK_SPLIT (trans->debit_splits[0]); MARK_SPLIT (trans->dest_splits[0]);
} }
} }
} }
@ -562,17 +562,17 @@ xaccTransSetMemo (Transaction *trans, const char *memo)
void void
xaccTransSetAction (Transaction *trans, const char *actn) xaccTransSetAction (Transaction *trans, const char *actn)
{ {
if (trans->credit_split.action) free (trans->credit_split.action); if (trans->source_split.action) free (trans->source_split.action);
trans->credit_split.action = strdup (actn); trans->source_split.action = strdup (actn);
MARK_SPLIT (&(trans->credit_split)); MARK_SPLIT (&(trans->source_split));
/* if there is only one split, then keep action in sync. */ /* if there is only one split, then keep action in sync. */
if (trans->debit_splits) { if (trans->dest_splits) {
if (0x0 != trans->debit_splits[0]) { if (0x0 != trans->dest_splits[0]) {
if (0x0 == trans->debit_splits[1]) { if (0x0 == trans->dest_splits[1]) {
free (trans->debit_splits[0]->action); free (trans->dest_splits[0]->action);
trans->debit_splits[0]->action = strdup (actn); trans->dest_splits[0]->action = strdup (actn);
MARK_SPLIT (trans->debit_splits[0]); MARK_SPLIT (trans->dest_splits[0]);
} }
} }
} }
@ -581,8 +581,8 @@ xaccTransSetAction (Transaction *trans, const char *actn)
void void
xaccTransSetReconcile (Transaction *trans, char recn) xaccTransSetReconcile (Transaction *trans, char recn)
{ {
trans->credit_split.reconciled = recn; trans->source_split.reconciled = recn;
MARK_SPLIT (&(trans->credit_split)); MARK_SPLIT (&(trans->source_split));
} }
/********************************************************************\ /********************************************************************\

View File

@ -1,7 +1,7 @@
/********************************************************************\ /********************************************************************\
* Transaction.h -- defines transaction for xacc (X-Accountant) * * Transaction.h -- defines transaction for xacc (X-Accountant) *
* Copyright (C) 1997 Robin D. Clark * * Copyright (C) 1997 Robin D. Clark *
* Copyright (C) 1997 Linas Vepstas * * Copyright (C) 1997, 1998 Linas Vepstas *
* * * *
* This program is free software; you can redistribute it and/or * * This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as * * modify it under the terms of the GNU General Public License as *
@ -75,8 +75,8 @@ typedef struct _transaction {
Date date; /* transaction date */ Date date; /* transaction date */
char * description; char * description;
Split credit_split; /* credited account */ Split source_split; /* source (creidted) account */
Split **debit_splits; /* list of splits, null terminated */ Split **dest_splits; /* list of splits, null terminated */
char write_flag; /* used only during file IO */ char write_flag; /* used only during file IO */
} Transaction; } Transaction;

View File

@ -10,17 +10,17 @@ The term "credited" here is arbitrary, as the value can be
positive or negative. positive or negative.
The notion of "double entry" is embodied in the "transaction" structure. The notion of "double entry" is embodied in the "transaction" structure.
The transaction consists of a date, a single "credit split" and zero The transaction consists of a date, a single "source split" and zero
or more "debit splits". Again, the notion of "credit" and "debit" or more "destination splits". Again, the notion of "source" and
are arbitrary, as the value stored in the split can be positive or "destination" are arbitrary, as the value stored in the split can be
negative. positive or negative.
If a transaction has one or more "debit_splits", then the sum of If a transaction has one or more "dest_splits", then the sum of
the debit-split values *must* equal the value of the credit-split. the destination-split values *must* equal the value of the source-split.
This equality is what forces a double-entry accounting system to This equality is what forces a double-entry accounting system to
balance. balance.
A transaction may have zero "debit-splits". If the transaction value A transaction may have zero "destination-splits". If the transaction value
is non-zero, then by definition, the system as a whole cannot balance. is non-zero, then by definition, the system as a whole cannot balance.
Many simple, home-oriented non-double-entry systems will allow Many simple, home-oriented non-double-entry systems will allow
non-balancing transactions, as these are simpler to comprehend for the non-balancing transactions, as these are simpler to comprehend for the
@ -42,3 +42,46 @@ the value of all of its sub-accounts. Account Groups are implemented
as doubly-linked trees. as doubly-linked trees.
Stocks, non-Currency-Denominated Assets
---------------------------------------
The engine includes support for non-currency-denominated assets,
such as stocks, bonds, mutual funds, inventory. This is done with
two values in the Split structure:
double share_price;
double damount;
"damount" is the number of shares/items. It is an "immutable" quantity,
in that it cannot change except by transfer (sale/purchase). It is the
quantity that is used when computing balances.
"share_price" is the price of the item in question. The share-price is
of course subject to fluctuation.
The net-value of a split is the product of "damount" and "share_price".
The currency balance of an account is the sum of all "damounts" times
the latest, newest share-price.
Currency accounts should use a share price of 1.0 for all splits.
To maintain the double-entry consistency, one must have the following
hold true:
(source_split->damount) * (source_split->share_price) ==
sum of all ((dest_split->damount) * (dest_split->share_price))
Thus, for example, the purchase of shares can be represented as:
source:
debit ABC Bank for $1045 (1045 dollars * dollar "price" of 1.00)
destination:
credit PQR Stock for $1000 (100 shares at $10 per share)
credit StockBroker category $45 in fees