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

View File

@ -1,7 +1,7 @@
/********************************************************************\
* Account.c -- the Account data structure *
* 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 *
* modify it under the terms of the GNU General Public License as *
@ -126,14 +126,14 @@ xaccFreeAccount( Account *acc )
Transaction *trans = (Transaction *) s->parent;
j=0;
debit_s = trans->debit_splits[0];
debit_s = trans->dest_splits[0];
while (debit_s) {
if (debit_s->acc) { dont_free_transaction = 1; break; }
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 );
}
@ -449,16 +449,16 @@ xaccCheckTransDateOrder (Transaction *trans )
if (NULL == trans) return 0;
acc = (Account *) (trans->credit_split.acc);
outOfOrder += xaccCheckDateOrder (acc, &(trans->credit_split));
acc = (Account *) (trans->source_split.acc);
outOfOrder += xaccCheckDateOrder (acc, &(trans->source_split));
i=0;
s = trans->debit_splits[0];
s = trans->dest_splits[0];
while (s) {
acc = (Account *) (s->acc);
outOfOrder += xaccCheckDateOrder (acc, s);
i++;
s = trans->debit_splits[i];
s = trans->dest_splits[i];
}
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.
*/
trans = (Transaction *) (split->parent);
if (split != &(trans->credit_split)) {
partner_split = &(trans->credit_split);
if (split != &(trans->source_split)) {
partner_split = &(trans->source_split);
} else {
/* perform that transfer *only* if there is one split */
if (trans->debit_splits) {
if (0x0 != trans->debit_splits[0]) {
if (0x0 == trans->debit_splits[1]) {
partner_split = trans->debit_splits[0];
if (trans->dest_splits) {
if (0x0 != trans->dest_splits[0]) {
if (0x0 == trans->dest_splits[1]) {
partner_split = trans->dest_splits[0];
}
}
}

View File

@ -46,7 +46,7 @@
* Account ::== accID flags type accountName description *
* notes numTran (Transaction)^numTrans *
* numGroups (Group)^numGroups *
* Transaction ::== num date description credit_split *
* Transaction ::== num date description source_split *
* numSplits (Split)^numSplits *
* Split ::== memo action reconciled *
* 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
* use the reconcile window to mark the transaction reconciled
*/
if( YREC == trans->credit_split.reconciled ) {
if( YREC == trans->source_split.reconciled ) {
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
* YREC are defined to be... this way it might loose all
* the reconciled data, but at least the field is valid */
if( (YREC != trans->credit_split.reconciled) &&
(FREC != trans->credit_split.reconciled) &&
(CREC != trans->credit_split.reconciled) ) {
if( (YREC != trans->source_split.reconciled) &&
(FREC != trans->source_split.reconciled) &&
(CREC != trans->source_split.reconciled) ) {
xaccTransSetReconcile (trans, NREC);
}
@ -607,7 +607,7 @@ readTransaction( int fd, Account *acc, int token )
}
XACC_FLIP_INT (amount);
num_shares = 0.01 * ((double) amount); /* file stores pennies */
trans->credit_split.damount = num_shares;
trans->source_split.damount = num_shares;
} else {
double damount;
@ -621,7 +621,7 @@ readTransaction( int fd, Account *acc, int token )
}
XACC_FLIP_DOUBLE (damount);
num_shares = damount;
trans->credit_split.damount = num_shares;
trans->source_split.damount = num_shares;
/* ... next read the share price ... */
err = read( fd, &damount, sizeof(double) );
@ -633,7 +633,7 @@ readTransaction( int fd, Account *acc, int token )
}
XACC_FLIP_DOUBLE (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);
@ -653,11 +653,11 @@ readTransaction( int fd, Account *acc, int token )
XACC_FLIP_INT (acc_id);
INFO_2 ("readTransaction(): credit %d\n", 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
* 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 */
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 */
split->damount = -num_shares;
split->share_price = share_price;
split->reconciled = trans->credit_split.reconciled;
split->reconciled = trans->source_split.reconciled;
free (split->memo);
split->memo = strdup (trans->credit_split.memo);
split->memo = strdup (trans->source_split.memo);
free (split->action);
split->action = strdup (trans->credit_split.action);
split->action = strdup (trans->source_split.action);
}
} else {
/* Version 1 files did not do double-entry */
xaccInsertSplit( acc, &(trans->credit_split) );
xaccInsertSplit( acc, &(trans->source_split) );
}
} else { /* else, read version-5 files */
Split *split;
/* first, read the credit split, and copy it in place */
split = readSplit (fd, token);
xaccSplitSetMemo ( &(trans->credit_split), split->memo);
xaccSplitSetAction ( &(trans->credit_split), split->action);
xaccSplitSetReconcile ( &(trans->credit_split), split->reconciled);
trans->credit_split.damount = split->damount;
trans->credit_split.share_price = split->share_price;
trans->credit_split.acc = split->acc;
trans->credit_split.parent = trans;
xaccSplitSetMemo ( &(trans->source_split), split->memo);
xaccSplitSetAction ( &(trans->source_split), split->action);
xaccSplitSetReconcile ( &(trans->source_split), split->reconciled);
trans->source_split.damount = split->damount;
trans->source_split.share_price = split->share_price;
trans->source_split.acc = split->acc;
trans->source_split.parent = trans;
/* 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 */
split->acc = NULL;
@ -1176,15 +1176,15 @@ writeTransaction( int fd, Transaction *trans )
err = writeString( fd, trans->description );
if( -1 == err ) return err;
err = writeSplit( fd, &(trans->credit_split) );
err = writeSplit( fd, &(trans->source_split) );
if( -1 == err ) return err;
/* count the number of splits */
i = 0;
s = trans->debit_splits[i];
s = trans->dest_splits[i];
while (s) {
i++;
s = trans->debit_splits[i];
s = trans->dest_splits[i];
}
XACC_FLIP_INT (i);
err = write( fd, &i, sizeof(int) );
@ -1192,12 +1192,12 @@ writeTransaction( int fd, Transaction *trans )
/* now write the splits */
i = 0;
s = trans->debit_splits[i];
s = trans->dest_splits[i];
while (s) {
err = writeSplit (fd, s);
if( -1 == err ) return err;
i++;
s = trans->debit_splits[i];
s = trans->dest_splits[i];
}
return err;

View File

@ -577,7 +577,7 @@ xaccGetSecurityQIFAccount (Account *acc, char *qifline)
#define XACC_ACTION(q,x) \
if (!strncmp (&qifline[1], q, strlen(q))) { \
trans->credit_split.action = strdup(x); \
trans->source_split.action = strdup(x); \
} else
@ -626,7 +626,7 @@ char * xaccReadQIFTransaction (int fd, Account *acc)
/* I == share price */
if ('I' == qifline [0]) {
trans -> credit_split.share_price = xaccParseUSAmount (&qifline[1]);
trans -> source_split.share_price = xaccParseUSAmount (&qifline[1]);
} else
/* L == name of acount from which transfer occured */
@ -637,7 +637,7 @@ char * xaccReadQIFTransaction (int fd, Account *acc)
/* M == memo field */
if ('M' == qifline [0]) {
XACC_PREP_STRING (trans->credit_split.memo);
XACC_PREP_STRING (trans->source_split.memo);
} else
/* N == check numbers for Banks, but Action for portfolios */
@ -670,7 +670,7 @@ char * xaccReadQIFTransaction (int fd, Account *acc)
if ('O' == qifline [0]) {
double pute;
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;
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 */
if ('Q' == qifline [0]) {
trans -> credit_split.damount = xaccParseUSAmount (&qifline[1]);
if (isneg) trans -> credit_split.damount = - (trans->credit_split.damount);
trans -> source_split.damount = xaccParseUSAmount (&qifline[1]);
if (isneg) trans -> source_split.damount = - (trans->source_split.damount);
got_share_quantity = 1;
} else
@ -709,8 +709,8 @@ char * xaccReadQIFTransaction (int fd, Account *acc)
if ('T' == qifline [0]) {
/* ignore T for stock transactions, since T is a dollar amount */
if (0 == got_share_quantity) {
trans -> credit_split.damount = xaccParseUSAmount (&qifline[1]);
if (isneg) trans -> credit_split.damount = - (trans->credit_split.damount);
trans -> source_split.damount = xaccParseUSAmount (&qifline[1]);
if (isneg) trans -> source_split.damount = - (trans->source_split.damount);
}
} else
@ -742,7 +742,7 @@ char * xaccReadQIFTransaction (int fd, Account *acc)
double parse, pute;
int got, wanted;
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;
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->description);
XACC_PREP_NULL_STRING (trans->credit_split.memo);
XACC_PREP_NULL_STRING (trans->credit_split.action);
XACC_PREP_NULL_STRING (trans->source_split.memo);
XACC_PREP_NULL_STRING (trans->source_split.action);
/* 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.
* But, just in case its missing, avoid a core dump */
if (sub_acc) {
trans->credit_split.acc = (struct _account *) sub_acc;
trans->source_split.acc = (struct _account *) sub_acc;
xaccInsertSplit (sub_acc, split);
}
} else {
@ -821,11 +821,11 @@ char * xaccReadQIFTransaction (int fd, Account *acc)
* account gets the dividend credit; otherwise, the
* main account gets it */
if (xfer_acc) {
trans->credit_split.acc = (struct _account *) xfer_acc;
xaccInsertSplit (xfer_acc, &(trans->credit_split));
trans->source_split.acc = (struct _account *) xfer_acc;
xaccInsertSplit (xfer_acc, &(trans->source_split));
} else {
trans->credit_split.acc = (struct _account *) acc;
xaccInsertSplit (acc, &(trans->credit_split));
trans->source_split.acc = (struct _account *) acc;
xaccInsertSplit (acc, &(trans->source_split));
}
}
@ -842,8 +842,8 @@ char * xaccReadQIFTransaction (int fd, Account *acc)
}
/* the transaction itself appears as a credit */
trans->credit_split.acc = (struct _account *) acc;
xaccInsertSplit (acc, &(trans->credit_split));
trans->source_split.acc = (struct _account *) acc;
xaccInsertSplit (acc, &(trans->source_split));
}
return qifline;

View File

@ -1,7 +1,7 @@
/********************************************************************\
* Transaction.c -- the transaction data structure *
* 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 *
* modify it under the terms of the GNU General Public License as *
@ -114,12 +114,12 @@ xaccFreeSplit( Split *split )
static void
MarkChanged (Transaction *trans)
{
MARK_SPLIT (&(trans->credit_split));
MARK_SPLIT (&(trans->source_split));
if (trans->debit_splits) {
if (trans->dest_splits) {
int i=0;
while (trans->debit_splits[i]) {
MARK_SPLIT (trans->debit_splits[i]);
while (trans->dest_splits[i]) {
MARK_SPLIT (trans->dest_splits[i]);
i++;
}
}
@ -200,11 +200,11 @@ xaccInitTransaction( Transaction * trans )
trans->num = strdup("");
trans->description = strdup("");
trans->debit_splits = (Split **) _malloc (sizeof (Split *));
trans->debit_splits[0] = NULL;
trans->dest_splits = (Split **) _malloc (sizeof (Split *));
trans->dest_splits[0] = NULL;
xaccInitSplit ( &(trans->credit_split));
trans->credit_split.parent = trans;
xaccInitSplit ( &(trans->source_split));
trans->source_split.parent = trans;
trans->date.year = 1900;
trans->date.month = 1;
@ -235,17 +235,17 @@ xaccFreeTransaction( Transaction *trans )
/* free a transaction only if it is not claimed
* by any accounts. */
if (trans->credit_split.acc) return;
if (trans->source_split.acc) return;
i = 0;
s = trans->debit_splits[i];
s = trans->dest_splits[i];
while (s) {
if (s->acc) return;
i++;
s = trans->debit_splits[i];
s = trans->dest_splits[i];
}
_free (trans->debit_splits);
_free (trans->dest_splits);
free(trans->num);
free(trans->description);
@ -272,24 +272,24 @@ xaccTransRecomputeAmount (Transaction *trans)
int i = 0;
double amount = 0.0;
s = trans->debit_splits[i];
s = trans->dest_splits[i];
while (s) {
amount += s->share_price * s->damount;
i++;
s = trans->debit_splits[i];
s = trans->dest_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;
s = trans->dest_splits[0];
trans -> source_split.damount = - (s->damount);
trans -> source_split.share_price = s->share_price;
} else {
trans -> credit_split.damount = -amount;
trans -> credit_split.share_price = 1.0;
trans -> source_split.damount = -amount;
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 */
split->parent = (struct _transaction *) trans;
num = xaccCountSplits (trans->debit_splits);
num = xaccCountSplits (trans->dest_splits);
oldarray = trans->debit_splits;
trans->debit_splits = (Split **) _malloc ((num+2)*sizeof(Split *));
oldarray = trans->dest_splits;
trans->dest_splits = (Split **) _malloc ((num+2)*sizeof(Split *));
for (i=0; i<num; i++) {
(trans->debit_splits)[i] = oldarray[i];
(trans->dest_splits)[i] = oldarray[i];
}
trans->debit_splits[num] = split;
trans->debit_splits[num+1] = NULL;
trans->dest_splits[num] = split;
trans->dest_splits[num+1] = NULL;
if (oldarray) _free (oldarray);
}
@ -332,15 +332,15 @@ xaccTransRemoveSplit (Transaction *trans, Split *split)
if (!trans) return;
split->parent = NULL;
s = trans->debit_splits[0];
s = trans->dest_splits[0];
while (s) {
trans->debit_splits[i] = trans->debit_splits[n];
trans->dest_splits[i] = trans->dest_splits[n];
if (split == s) { i--; }
i++;
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 */
xaccTransRecomputeAmount (trans);
@ -499,15 +499,15 @@ xaccTransSetDate (Transaction *trans, int day, int mon, int year)
* in thier accounts
*/
split = &(trans->credit_split);
split = &(trans->source_split);
acc = (Account *) split->acc;
xaccRemoveSplit (acc, split);
xaccInsertSplit (acc, split);
xaccRecomputeBalance (acc);
if (trans->debit_splits) {
if (trans->dest_splits) {
int i=0;
split = trans->debit_splits[i];
split = trans->dest_splits[i];
while (split) {
acc = (Account *) split->acc;
xaccRemoveSplit (acc, split);
@ -515,7 +515,7 @@ xaccTransSetDate (Transaction *trans, int day, int mon, int year)
xaccRecomputeBalance (acc);
i++;
split = trans->debit_splits[i];
split = trans->dest_splits[i];
}
}
}
@ -543,17 +543,17 @@ xaccTransSetDescription (Transaction *trans, const char *desc)
void
xaccTransSetMemo (Transaction *trans, const char *memo)
{
if (trans->credit_split.memo) free (trans->credit_split.memo);
trans->credit_split.memo = strdup (memo);
MARK_SPLIT (&(trans->credit_split));
if (trans->source_split.memo) free (trans->source_split.memo);
trans->source_split.memo = strdup (memo);
MARK_SPLIT (&(trans->source_split));
/* if there is only one split, then keep memos in sync. */
if (trans->debit_splits) {
if (0x0 != trans->debit_splits[0]) {
if (0x0 == trans->debit_splits[1]) {
free (trans->debit_splits[0]->memo);
trans->debit_splits[0]->memo = strdup (memo);
MARK_SPLIT (trans->debit_splits[0]);
if (trans->dest_splits) {
if (0x0 != trans->dest_splits[0]) {
if (0x0 == trans->dest_splits[1]) {
free (trans->dest_splits[0]->memo);
trans->dest_splits[0]->memo = strdup (memo);
MARK_SPLIT (trans->dest_splits[0]);
}
}
}
@ -562,17 +562,17 @@ xaccTransSetMemo (Transaction *trans, const char *memo)
void
xaccTransSetAction (Transaction *trans, const char *actn)
{
if (trans->credit_split.action) free (trans->credit_split.action);
trans->credit_split.action = strdup (actn);
MARK_SPLIT (&(trans->credit_split));
if (trans->source_split.action) free (trans->source_split.action);
trans->source_split.action = strdup (actn);
MARK_SPLIT (&(trans->source_split));
/* if there is only one split, then keep action in sync. */
if (trans->debit_splits) {
if (0x0 != trans->debit_splits[0]) {
if (0x0 == trans->debit_splits[1]) {
free (trans->debit_splits[0]->action);
trans->debit_splits[0]->action = strdup (actn);
MARK_SPLIT (trans->debit_splits[0]);
if (trans->dest_splits) {
if (0x0 != trans->dest_splits[0]) {
if (0x0 == trans->dest_splits[1]) {
free (trans->dest_splits[0]->action);
trans->dest_splits[0]->action = strdup (actn);
MARK_SPLIT (trans->dest_splits[0]);
}
}
}
@ -581,8 +581,8 @@ xaccTransSetAction (Transaction *trans, const char *actn)
void
xaccTransSetReconcile (Transaction *trans, char recn)
{
trans->credit_split.reconciled = recn;
MARK_SPLIT (&(trans->credit_split));
trans->source_split.reconciled = recn;
MARK_SPLIT (&(trans->source_split));
}
/********************************************************************\

View File

@ -1,7 +1,7 @@
/********************************************************************\
* Transaction.h -- defines transaction for xacc (X-Accountant) *
* 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 *
* modify it under the terms of the GNU General Public License as *
@ -75,8 +75,8 @@ typedef struct _transaction {
Date date; /* transaction date */
char * description;
Split credit_split; /* credited account */
Split **debit_splits; /* list of splits, null terminated */
Split source_split; /* source (creidted) account */
Split **dest_splits; /* list of splits, null terminated */
char write_flag; /* used only during file IO */
} Transaction;

View File

@ -10,17 +10,17 @@ The term "credited" here is arbitrary, as the value can be
positive or negative.
The notion of "double entry" is embodied in the "transaction" structure.
The transaction consists of a date, a single "credit split" and zero
or more "debit splits". Again, the notion of "credit" and "debit"
are arbitrary, as the value stored in the split can be positive or
negative.
The transaction consists of a date, a single "source split" and zero
or more "destination splits". Again, the notion of "source" and
"destination" are arbitrary, as the value stored in the split can be
positive or negative.
If a transaction has one or more "debit_splits", then the sum of
the debit-split values *must* equal the value of the credit-split.
If a transaction has one or more "dest_splits", then the sum of
the destination-split values *must* equal the value of the source-split.
This equality is what forces a double-entry accounting system to
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.
Many simple, home-oriented non-double-entry systems will allow
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.
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