From 124d1e5d7412d7831dfa01b852dfb82f61b7f00d Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Wed, 7 Jan 1998 23:09:56 +0000 Subject: [PATCH] almost done implementing splits git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@392 57a11ea4-9604-0410-9ed3-97b8803252fd --- src/AccWindow.c | 2 +- src/Account.c | 33 +++++++++++++++++-- src/FileIO.c | 4 +-- src/QIFIO.c | 6 ++-- src/RecnWindow.c | 48 ++++++++++++++-------------- src/RegWindow.c | 81 +++++++++++++++++++++++++++++++---------------- src/Transaction.c | 38 +++++++++++----------- src/XferWindow.c | 18 +++++------ 8 files changed, 144 insertions(+), 86 deletions(-) diff --git a/src/AccWindow.c b/src/AccWindow.c index 9a48be0fc6..54cb0d7e55 100644 --- a/src/AccWindow.c +++ b/src/AccWindow.c @@ -680,7 +680,7 @@ createCB( Widget mw, XtPointer cd, XtPointer cb ) xaccTransSetDescription (trans, OPEN_BALN_STR); /* add the new transaction to the account */ - insertTransaction( acc, trans ); + xaccInsertSplit (acc, &(trans->credit_split) ); /* once the account is set up, add it to account group * If the user indicated a parent acccount, make it a diff --git a/src/Account.c b/src/Account.c index 8957ec5577..1f965f103f 100644 --- a/src/Account.c +++ b/src/Account.c @@ -243,6 +243,35 @@ xaccInsertSplit ( Account *acc, Split *split ) } +/********************************************************************\ +\********************************************************************/ + +void +xaccRemoveSplit ( Account *acc, Split *split ) + { + int i,j; + + if (!acc) return; + if (!split) return; + + /* mark the data file as needing to be saved: */ + if( acc->parent != NULL ) acc->parent->saved = False; + + for( i=0,j=0; jnumSplits; i++,j++ ) { + acc->splits[i] = acc->splits[j]; + if (split == acc->splits[i]) i--; + } + + split->acc = NULL; + + acc->numSplits --; + + /* make sure the array is NULL terminated */ + acc->splits[acc->numSplits] = NULL; + +} + + /********************************************************************\ * xaccRecomputeBalance * * recomputes the partial balances and the current balance for * @@ -396,8 +425,8 @@ xaccCheckDateOrder (Account * acc, Split *split ) /* take care of re-ordering, if necessary */ if( outOfOrder ) { - removeTransaction( acc, position ); - insertTransaction( acc, split ); + xaccRemoveSplit( acc, split ); + xaccInsertSplit( acc, split ); return 1; } return 0; diff --git a/src/FileIO.c b/src/FileIO.c index 9df7c87702..e294dfd55b 100644 --- a/src/FileIO.c +++ b/src/FileIO.c @@ -672,7 +672,7 @@ readTransaction( int fd, Account *acc, int token ) if (peer_acc) { Split *split; split = xaccMallocSplit (); - xaccAppendSplit (trans, split); + xaccTransAppendSplit (trans, split); split -> acc = (struct _account *) peer_acc; xaccInsertSplit (peer_acc, split); split->damount = -num_shares; @@ -718,7 +718,7 @@ readTransaction( int fd, Account *acc, int token ) for (i=0; iparent = trans; - xaccAppendSplit( trans, split); + xaccTransAppendSplit( trans, split); xaccInsertSplit( ((Account *) (split->acc)), split); } } diff --git a/src/QIFIO.c b/src/QIFIO.c index 6c73ac5092..1cdc27bfc6 100644 --- a/src/QIFIO.c +++ b/src/QIFIO.c @@ -696,7 +696,7 @@ char * xaccReadQIFTransaction (int fd, Account *acc) split -> parent = trans; /* parent transaction */ split -> acc = (struct _account *) xaccGetXferQIFAccount (acc, qifline); - xaccAppendSplit (trans, split); + xaccTransAppendSplit (trans, split); /* hack alert -- we should insert this split into * the split account, and remove the L field */ @@ -788,7 +788,7 @@ char * xaccReadQIFTransaction (int fd, Account *acc) if (share_xfer) { if (!split) { split = xaccMallocSplit (); - xaccAppendSplit (trans, split); + xaccTransAppendSplit (trans, split); } /* Insert the transaction into the main brokerage @@ -832,7 +832,7 @@ char * xaccReadQIFTransaction (int fd, Account *acc) if (xfer_acc) { if (!split) { split = xaccMallocSplit (); - xaccAppendSplit (trans, split); + xaccTransAppendSplit (trans, split); } split->acc = (struct _account *) xfer_acc; xaccInsertSplit (xfer_acc, split); diff --git a/src/RecnWindow.c b/src/RecnWindow.c index 8f0721416c..18e1c0813d 100644 --- a/src/RecnWindow.c +++ b/src/RecnWindow.c @@ -92,7 +92,7 @@ recnRefresh( RecnWindow *recnData ) { int i,nrows; char buf[BUFSIZE]; - Transaction *trans; + Split *split; Account *acc = recnData->acc; /* NOTE: an improvement of the current design would be to use the @@ -110,15 +110,17 @@ recnRefresh( RecnWindow *recnData ) /* Add the non-reconciled transactions */ i=0; - while( (trans=getTransaction(acc,i++)) != NULL ) + split = acc->splits[i]; + while( split) { String rows[5]; + Transaction *trans = split->parent; - if( YREC != trans->credit_split.reconciled ) + if( YREC != split->reconciled ) { double themount; - sprintf( buf, "%c", trans->credit_split.reconciled ); + sprintf( buf, "%c", split->reconciled ); rows[0] = XtNewString(buf); rows[1] = trans->num; sprintf( buf, "%2d/%2d/%02d", @@ -131,9 +133,9 @@ recnRefresh( RecnWindow *recnData ) /* for stock accounts, show share quantity, * not currency amount */ if ((STOCK == acc->type) || (MUTUAL == acc->type)) { - themount = xaccGetShareAmount (acc, trans); + themount = split->damount; } else { - themount = xaccGetAmount (acc, trans); + themount = split->damount * split->share_price; } sprintf( buf, "%.2f", DABS(themount) ); rows[4] = XtNewString(buf); @@ -142,13 +144,13 @@ recnRefresh( RecnWindow *recnData ) { XtVaGetValues( recnData->debit, XmNrows, &nrows, NULL ); XbaeMatrixAddRows( recnData->debit, nrows, rows, NULL, NULL, 1 ); - XbaeMatrixSetRowUserData( recnData->debit, nrows, (XtPointer)trans ); + XbaeMatrixSetRowUserData( recnData->debit, nrows, (XtPointer)split ); } else { XtVaGetValues( recnData->credit, XmNrows, &nrows, NULL ); XbaeMatrixAddRows( recnData->credit, nrows, rows, NULL, NULL, 1 ); - XbaeMatrixSetRowUserData( recnData->credit,nrows, (XtPointer)trans ); + XbaeMatrixSetRowUserData( recnData->credit,nrows, (XtPointer)split ); } } } @@ -168,7 +170,7 @@ recnRefresh( RecnWindow *recnData ) void recnRecalculateBalance( RecnWindow *recnData ) { - Transaction *trans; + Split * split; Account *acc = recnData ->acc; char *amt; int i,nrows; @@ -188,11 +190,11 @@ recnRecalculateBalance( RecnWindow *recnData ) String recn = XbaeMatrixGetCell( recnData->debit, i, 0 ); if( recn[0] == YREC ) { - trans = (Transaction *)XbaeMatrixGetRowUserData( recnData->debit, i ); + split = (Split *)XbaeMatrixGetRowUserData( recnData->debit, i ); if (shrs) { - ddebit += xaccGetShareAmount (acc, trans); + ddebit += split->damount; } else { - ddebit += xaccGetAmount (acc, trans); + ddebit += split->damount * split->share_price; } } } @@ -206,11 +208,11 @@ recnRecalculateBalance( RecnWindow *recnData ) String recn = XbaeMatrixGetCell( recnData->credit, i, 0 ); if( recn[0] == YREC ) { - trans = (Transaction *)XbaeMatrixGetRowUserData( recnData->credit, i ); + split = (Split *)XbaeMatrixGetRowUserData( recnData->credit, i ); if (shrs) { - dcredit += xaccGetShareAmount (acc, trans); + dcredit += split->damount; } else { - dcredit += xaccGetAmount (acc, trans); + dcredit += split->damount * split->share_price; } } } @@ -799,7 +801,7 @@ void recnOkCB( Widget mw, XtPointer cd, XtPointer cb ) { int nrows,i; - Transaction *trans; + Split *split; RecnWindow *recnData = (RecnWindow *)cd; AccountGroup *grp = topgroup; /* hack alert -- should pass as arg .. */ @@ -810,8 +812,8 @@ recnOkCB( Widget mw, XtPointer cd, XtPointer cb ) String recn = XbaeMatrixGetCell( recnData->debit, i, 0 ); if( recn[0] == YREC ) { - trans = (Transaction *)XbaeMatrixGetRowUserData( recnData->debit, i ); - xaccTransSetReconcile (trans, YREC); + split = (Split *)XbaeMatrixGetRowUserData( recnData->debit, i ); + split->reconciled = YREC; /* mark the datafile as needing to be saved: */ grp->saved = False; } @@ -824,8 +826,8 @@ recnOkCB( Widget mw, XtPointer cd, XtPointer cb ) String recn = XbaeMatrixGetCell( recnData->credit, i, 0 ); if( recn[0] == YREC ) { - trans = (Transaction *)XbaeMatrixGetRowUserData( recnData->credit, i ); - xaccTransSetReconcile (trans, YREC); + split = (Split *)XbaeMatrixGetRowUserData( recnData->credit, i ); + split->reconciled = YREC; /* mark the datafile as needing to be saved: */ grp->saved = False; } @@ -867,10 +869,10 @@ recnCB( Widget mw, XtPointer cd, XtPointer cb ) if( YREC == val[0] ) { - Transaction *trans = - (Transaction *)XbaeMatrixGetRowUserData( mw, cbs->row ); + Split *split = + (Split *)XbaeMatrixGetRowUserData( mw, cbs->row ); - sprintf( buf, "%c", trans->credit_split.reconciled ); + sprintf( buf, "%c", split->reconciled ); XbaeMatrixSetCell( mw, cbs->row, cbs->column, buf ); } else diff --git a/src/RegWindow.c b/src/RegWindow.c index d0acca0e71..043a03ff01 100644 --- a/src/RegWindow.c +++ b/src/RegWindow.c @@ -23,6 +23,8 @@ * Huntington Beach, CA 92648-4632 * \********************************************************************/ +#ifdef NOT_TODAY + #include #include #include @@ -368,7 +370,12 @@ xaccGetDisplayAmountStrings (RegWindow *regData, Account * acc; int show_debit, show_credit; - acc = (Account *) (trans->debit); + /* hack alert -- should examine all splits ... */ + if (trans->debit_splits[0]) { + acc = (Account *) ((trans->debit_splits[0]) -> acc); + } else { + acc = NULL; + } show_debit = xaccIsAccountInList (acc, regData->blackacc); acc = (Account *) (trans->credit_split.acc); @@ -419,7 +426,13 @@ xaccGetDisplayAmountStrings (RegWindow *regData, * the account type is stock or mutual, since other types * do not have shares. */ show_debit = 0; - acc = (Account *) (trans->debit); + + /* hack alert -- should examine all splits ... */ + if (trans->debit_splits[0]) { + acc = (Account *) ((trans->debit_splits[0]) -> acc); + } else { + acc = NULL; + } if (acc) { if ((MUTUAL == acc->type) || (STOCK == acc->type) ) { show_debit = xaccIsAccountInList (acc, regData->blackacc); @@ -494,10 +507,10 @@ regRefresh( RegWindow *regData ) { if( regData != NULL ) { - Transaction *trans; - Transaction **tarray; + Split *split; + Split **sarray; int old_num_rows, new_num_rows, delta_rows; - int i,j, ntrans, ncols; + int i,j, nsplits, ncols; char buf[BUFSIZE]; String **data = NULL; String **newData; @@ -513,17 +526,17 @@ regRefresh( RegWindow *regData ) /* first, build a sorted array of transactions */ if (1 == regData->numAcc) { - tarray = regData->blackacc[0]->transaction; - ntrans = regData->blackacc[0]->numTrans; + sarray = regData->blackacc[0]->splits; + nsplits = regData->blackacc[0]->numSplits; } else { - tarray = accListGetSortedTrans (regData->blackacc); - ntrans = xaccCountTransactions (tarray); + sarray = accListGetSortedSplits (regData->blackacc); + nsplits = xaccCountSplits (sarray); } /* Allocate one extra transaction row. That extra row * is used to allow the user to add new transactions */ - new_num_rows = NUM_ROWS_PER_TRANS*(ntrans+1) + NUM_HEADER_ROWS; + new_num_rows = NUM_ROWS_PER_TRANS*(nsplits+1) + NUM_HEADER_ROWS; XtVaGetValues( regData->reg, XmNrows, &old_num_rows, NULL ); XtVaGetValues( regData->reg, XmNcells, &data, NULL ); @@ -557,10 +570,12 @@ regRefresh( RegWindow *regData ) NULL, NULL, NULL, delta_rows ); } +#ifdef BROKEN_BECAUSE_OF_SPLITS +/* hack alert -- discard or fix this ... */ /* try to keep all amounts positive */ - for (i=0; i trans->damount) { + for (i=0; i split->damount) { struct _account *tmp; tmp = trans->credit_split.acc; trans->credit_split.acc = trans->debit; @@ -568,15 +583,18 @@ regRefresh( RegWindow *regData ) trans->damount = - (trans->damount); } } +#endif /* and fill in the data for the matrix: */ - for (i=0; iparent; row = NUM_ROWS_PER_TRANS*i + NUM_HEADER_ROWS; - XbaeMatrixSetRowUserData ( regData->reg, row, (XPointer) trans); + XbaeMatrixSetRowUserData ( regData->reg, row, (XPointer) split); sprintf( buf, "%2d/%2d", trans->date.month, trans->date.day ); newData[row+DATE_CELL_R][DATE_CELL_C] = XtNewString(buf); @@ -592,10 +610,16 @@ regRefresh( RegWindow *regData ) (INC_LEDGER == regData->type) || (PORTFOLIO == regData->type) ) { Account *xfer_acc; - xfer_acc = (Account *) trans -> debit; - if (xfer_acc) { - sprintf( buf, "%s", xfer_acc->accountName ); - newData[row+XFRM_CELL_R][XFRM_CELL_C] = XtNewString(buf); + Split *deb; + + /* hack alert -- handle all splits ... */ + deb = trans -> debit_splits[0]; + if (deb) { + xfer_acc = (Account *) (deb->acc); + if (xfer_acc) { + sprintf( buf, "%s", xfer_acc->accountName ); + newData[row+XFRM_CELL_R][XFRM_CELL_C] = XtNewString(buf); + } } xfer_acc = (Account *) trans -> credit_split.acc; if (xfer_acc) { @@ -610,7 +634,9 @@ regRefresh( RegWindow *regData ) Account *main_acc, *xfer_acc; main_acc = regData->blackacc[0]; - xfer_acc = xaccGetOtherAccount (main_acc, trans); + + /* hack alert -- should display all splits ... */ + xfer_acc = (Account *) (split->parent->credit_split.acc); if (xfer_acc) { sprintf( buf, "%s", xfer_acc->accountName ); newData[row+XFRM_CELL_R][XFRM_CELL_C] = XtNewString(buf); @@ -619,13 +645,13 @@ regRefresh( RegWindow *regData ) sprintf( buf, "%s", trans->description ); newData[row+DESC_CELL_R][DESC_CELL_C] = XtNewString(buf); - sprintf( buf, "%s", trans->credit_split.memo ); + sprintf( buf, "%s", split->memo ); newData[row+MEMO_CELL_R][MEMO_CELL_C] = XtNewString(buf); - sprintf( buf, "%c", trans->credit_split.reconciled ); + sprintf( buf, "%c", split->reconciled ); newData[row+RECN_CELL_R][RECN_CELL_C] = XtNewString(buf); - sprintf( buf, "%s", trans->action ); + sprintf( buf, "%s", split->action ); newData[row+ACTN_CELL_R][ACTN_CELL_C] = XtNewString(buf); /* ----------------------------------- */ @@ -653,11 +679,11 @@ regRefresh( RegWindow *regData ) case INC_LEDGER: case GEN_LEDGER: - themount = trans->damount * trans->share_price; + themount = split->damount * split->share_price; break; case PORTFOLIO: - themount = trans->damount; + themount = split->damount; break; default: @@ -683,7 +709,7 @@ regRefresh( RegWindow *regData ) break; case STOCK: case MUTUAL: - sprintf( buf, "%.2f ", trans->share_price ); + sprintf( buf, "%.2f ", split->share_price ); newData[row+PRCC_CELL_R][PRCC_CELL_C] = XtNewString(buf); break; @@ -3377,4 +3403,5 @@ dateCellFormat( Widget mw, XbaeMatrixModifyVerifyCallbackStruct *mvcbs, int do_y } } +#endif /************************** END OF FILE *************************/ diff --git a/src/Transaction.c b/src/Transaction.c index ef02ec4e7f..f3c7607a87 100644 --- a/src/Transaction.c +++ b/src/Transaction.c @@ -54,7 +54,6 @@ xaccInitSplit( Split * split ) split->damount = 0.0; split->share_price = 1.0; - split->write_flag = 0; } /********************************************************************\ @@ -79,9 +78,10 @@ xaccFreeSplit( Split *split ) * by any accounts. */ if (split->acc) return; - xaccRemoveSplit (split); + xaccTransRemoveSplit (split->parent, split); XtFree(split->memo); + XtFree(split->action); /* just in case someone looks up freed memory ... */ split->memo = 0x0; @@ -90,7 +90,6 @@ xaccFreeSplit( Split *split ) split->share_price = 1.0; split->parent = NULL; - split->write_flag = 0; _free(split); } @@ -171,7 +170,7 @@ initTransaction( Transaction * trans ) trans->debit_splits[0] = NULL; xaccInitSplit ( &(trans->credit_split)); - trans->credit_split->parent = trans; + trans->credit_split.parent = trans; trans->date.year = 1900; trans->date.month = 1; @@ -194,17 +193,22 @@ mallocTransaction( void ) void freeTransaction( Transaction *trans ) { + int i; + Split *s; + if (!trans) return; /* free a transaction only if it is not claimed * by any accounts. */ - if (trans->debit) return; if (trans->credit_split.acc) return; -/* -hack alert -- don't do this until splits are fully -implemented and tested. - if (NULL != trans->debit_splits[0]) return; -*/ + + i = 0; + s = trans->debit_splits[i]; + while (s) { + if (s->acc) return; + i++; + s = trans->debit_splits[i]; + } _free (trans->debit_splits); XtFree(trans->num); @@ -256,7 +260,7 @@ xaccTransRecomputeAmount (Transaction *trans) /********************************************************************\ \********************************************************************/ void -xaccAppendSplit (Transaction *trans, Split *split) +xaccTransAppendSplit (Transaction *trans, Split *split) { int i, num; Split **oldarray; @@ -286,17 +290,14 @@ xaccAppendSplit (Transaction *trans, Split *split) \********************************************************************/ void -xaccRemoveSplit (Split *split) +xaccTransRemoveSplit (Transaction *trans, Split *split) { int i=0, n=0; Split *s; - Transaction *trans; if (!split) return; - trans = (Transaction *) split->parent; - split->parent = NULL; - if (!trans) return; + split->parent = NULL; s = trans->debit_splits[0]; while (s) { @@ -310,8 +311,6 @@ xaccRemoveSplit (Split *split) /* bring dollar amounts into synchrony */ xaccTransRecomputeAmount (trans); - - /* hack alert -- we should also remove it from the account */ } /********************************************************************\ @@ -345,7 +344,8 @@ xaccSplitOrder (Split **sa, Split **sb) if ( !(*sa) && (*sb) ) return +1; if ( !(*sa) && !(*sb) ) return 0; - retval = xaccTransOrder (sa->parent, sb->parent); + retval = xaccTransOrder ( ((Transaction **) &((*sa)->parent)), + ((Transaction **) &((*sb)->parent))); if (0 != retval) return retval; /* otherwise, sort on memo strings */ diff --git a/src/XferWindow.c b/src/XferWindow.c index 90d67bcc6c..fbee0c4c47 100644 --- a/src/XferWindow.c +++ b/src/XferWindow.c @@ -442,6 +442,7 @@ xferCB( Widget mw, XtPointer cd, XtPointer cb ) { XferWindow *xferData = (XferWindow *)cd; Transaction *trans; + Split *split; Account *acc; String str; float val=0.0; @@ -456,7 +457,9 @@ xferCB( Widget mw, XtPointer cd, XtPointer cb ) grp->saved = False; /* a double-entry transfer -- just one record, two accounts */ - trans = mallocTransaction(); + trans = mallocTransaction(); + split = xaccMallocSplit(); + xaccTransAppendSplit (trans, split); /* Create the transaction */ str = XmTextGetString(xferData->date); @@ -465,20 +468,18 @@ xferCB( Widget mw, XtPointer cd, XtPointer cb ) &(trans->date.day), &(trans->date.year) ); str = XmTextGetString(xferData->amount); sscanf( str, "%f", &val ); /* sscanf must take float not double arg */ - trans->damount = val; - trans->num = XtNewString(""); - + split->damount = -val; + xaccTransSetMemo (trans, XmTextGetString(xferData->memo)); xaccTransSetDescription (trans, XmTextGetString(xferData->desc)); xaccTransSetReconcile (trans, NREC); /* make note of which accounts this was transfered from & to */ - trans->debit = (struct _account *) getAccount(grp,xferData->from); + split->acc = (struct _account *) getAccount(grp,xferData->from); trans->credit_split.acc = (struct _account *) getAccount(grp,xferData->to); /* insert transaction into from acount */ - acc = getAccount(grp,xferData->from); - insertTransaction( acc, trans ); + xaccInsertSplit (((Account *) (split->acc)), split); /* Refresh the "from" account register window */ regRefresh(acc->regData); @@ -486,8 +487,7 @@ xferCB( Widget mw, XtPointer cd, XtPointer cb ) recnRefresh(acc->recnData); /* insert transaction into to acount */ - acc = getAccount(grp,xferData->to); - insertTransaction( acc, trans ); + xaccInsertSplit (((Account *) (trans->credit_split.acc)), &(trans->credit_split)); /* Refresh the "to" account register window */ regRefresh(acc->regData);