mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Use GLists to store splits in transactions. Remove cruft.
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3120 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
134940aab9
commit
4f84ccd735
@ -3230,9 +3230,10 @@ xaccSRLoadRegister (SplitRegister *reg, Split **slist,
|
||||
|
||||
xaccTransBeginEdit (trans, TRUE);
|
||||
xaccTransSetDateSecs (trans, info->last_date_entered);
|
||||
blank_split = xaccMallocSplit ();
|
||||
xaccTransAppendSplit (trans, blank_split);
|
||||
xaccTransCommitEdit (trans);
|
||||
|
||||
blank_split = xaccTransGetSplit (trans, 0);
|
||||
info->blank_split_guid = *xaccSplitGetGUID (blank_split);
|
||||
|
||||
info->blank_split_edited = FALSE;
|
||||
|
@ -664,30 +664,25 @@ xaccAccountFixSplitDateOrder (Account * acc, Split *split ) {
|
||||
/********************************************************************\
|
||||
* xaccCheckTransDateOrder *
|
||||
* check this transaction to see if the date is in correct order *
|
||||
* If it is not, reorder the transactions ... *
|
||||
* If it is not, reorder the transactions. *
|
||||
* This routine perfroms the check for both of the double-entry *
|
||||
* transaction entries ... *
|
||||
* transaction entries. *
|
||||
* *
|
||||
* Args: trans -- the transaction to check *
|
||||
* Return: int -- non-zero if out of order *
|
||||
\********************************************************************/
|
||||
|
||||
void
|
||||
xaccTransFixSplitDateOrder (Transaction *trans )
|
||||
xaccTransFixSplitDateOrder (Transaction *trans)
|
||||
{
|
||||
Account * acc;
|
||||
Split *s;
|
||||
int i = 0;
|
||||
GList *node;
|
||||
|
||||
if (NULL == trans) return;
|
||||
if (trans == NULL) return;
|
||||
|
||||
i=0;
|
||||
s = trans->splits[0];
|
||||
while (s) {
|
||||
acc = (Account *) (s->acc);
|
||||
xaccAccountFixSplitDateOrder (acc, s);
|
||||
i++;
|
||||
s = trans->splits[i];
|
||||
for (node = trans->splits; node; node = node->next)
|
||||
{
|
||||
Split *s = node->data;
|
||||
xaccAccountFixSplitDateOrder (s->acc, s);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,7 +114,7 @@ struct _account {
|
||||
gnc_numeric share_cleared_balance;
|
||||
gnc_numeric share_reconciled_balance;
|
||||
|
||||
GList *splits; /* ptr to array of ptrs to splits */
|
||||
GList *splits; /* list of split pointers */
|
||||
|
||||
/* The "changed" flag is used to invalidate cached values in this structure.
|
||||
* Currently, the balances and the cost basis are cached.
|
||||
|
@ -64,21 +64,21 @@ xaccAccountGetBackend (Account * acc)
|
||||
Backend *
|
||||
xaccTransactionGetBackend (Transaction *trans)
|
||||
{
|
||||
Backend *be;
|
||||
GList *node;
|
||||
Split *s;
|
||||
|
||||
if (!trans) return NULL;
|
||||
|
||||
/* find an account */
|
||||
s = trans->splits[0];
|
||||
s = xaccTransGetSplit (trans, 0);
|
||||
if (!s) return NULL;
|
||||
|
||||
/* I suppose it would be more 'technically correct' to make sure that
|
||||
* all splits share teh same backend, and flag an error if they
|
||||
* all splits share the same backend, and flag an error if they
|
||||
* don't. However, at this point, it seems quite unlikely, so we'll
|
||||
* just use teh first backend we find.
|
||||
* just use the first backend we find.
|
||||
*/
|
||||
be = xaccAccountGetBackend (s->acc);
|
||||
return be;
|
||||
return xaccAccountGetBackend (s->acc);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
|
@ -22,12 +22,12 @@
|
||||
\********************************************************************/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "Account.h"
|
||||
#include "AccountP.h"
|
||||
#include "DateUtils.h"
|
||||
@ -189,8 +189,7 @@ xaccCloseLog (void)
|
||||
void
|
||||
xaccTransWriteLog (Transaction *trans, char flag)
|
||||
{
|
||||
Split *split;
|
||||
int i = 0;
|
||||
GList *node;
|
||||
char *dnow, *dent, *dpost, *drecn;
|
||||
|
||||
if (!gen_logs) return;
|
||||
@ -202,10 +201,13 @@ xaccTransWriteLog (Transaction *trans, char flag)
|
||||
|
||||
fprintf (trans_log, "===== START\n");
|
||||
|
||||
split = trans->splits[0];
|
||||
while (split) {
|
||||
for (node = trans->splits; node; node = node->next) {
|
||||
Split *split = node->data;
|
||||
char * accname = "";
|
||||
if (split->acc) accname = split->acc->accountName;
|
||||
|
||||
if (split->acc)
|
||||
accname = split->acc->accountName;
|
||||
|
||||
drecn = xaccDateUtilGetStamp (split->date_reconciled.tv_sec);
|
||||
|
||||
/* use tab-separated fields */
|
||||
@ -229,9 +231,8 @@ xaccTransWriteLog (Transaction *trans, char flag)
|
||||
drecn
|
||||
);
|
||||
free (drecn);
|
||||
i++;
|
||||
split = trans->splits[i];
|
||||
}
|
||||
|
||||
fprintf (trans_log, "===== END\n");
|
||||
free (dnow);
|
||||
free (dent);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -172,16 +172,6 @@ void xaccTransSetDateEnteredTS (Transaction *trans,
|
||||
void xaccTransSetNum (Transaction *trans, const char *num);
|
||||
void xaccTransSetDescription (Transaction *trans, const char *desc);
|
||||
|
||||
/* The xaccTransSetMemo() and xaccTransSetAction() methods are
|
||||
* convenience routines to keep the memo and action fields
|
||||
* of two-split transactions in sync. If the transaction has
|
||||
* precisely two splits, then these routines will set the memo
|
||||
* and action of both splits. Otherwise, they will set the
|
||||
* memo and action of the first split (source split) only.
|
||||
*/
|
||||
void xaccTransSetMemo (Transaction *trans, const char *memo);
|
||||
void xaccTransSetAction (Transaction *trans, const char *action);
|
||||
|
||||
/* The xaccTransAppendSplit() method will append the indicated
|
||||
* split to the collection of splits in this transaction.
|
||||
* If the split is already a part of another transaction,
|
||||
@ -473,10 +463,6 @@ int xaccSplitDateOrder (Split *sa, Split *sb);
|
||||
/********************************************************************\
|
||||
* Miscellaneous utility routines.
|
||||
\********************************************************************/
|
||||
/*
|
||||
* count the number of transactions in the null-terminated array
|
||||
*/
|
||||
int xaccCountTransactions (Transaction **tarray);
|
||||
|
||||
/* count the number of splits in the indicated array */
|
||||
int xaccCountSplits (Split **sarray);
|
||||
@ -507,12 +493,11 @@ Split * xaccGetOtherSplit (Split *split);
|
||||
*/
|
||||
int xaccIsPeerSplit (Split *split_1, Split *split_2);
|
||||
|
||||
/* The IthSplit() and IthTransaction() routines merely dereference
|
||||
* the lists supplied as arguments; i.e. they return list[i].
|
||||
* These routines are needed by the perl swig wrappers, which
|
||||
* are unable to dereference on their own.
|
||||
/* The IthSplit() routine merely dereferences
|
||||
* the list supplied as argument; i.e. it returns list[i].
|
||||
* This routine is needed by the perl swig wrappers, which
|
||||
* is unable to dereference on their own.
|
||||
*/
|
||||
Transaction * IthTransaction (Transaction **tarray, int i);
|
||||
Split * IthSplit (Split **sarray, int i);
|
||||
|
||||
#endif /* __XACC_TRANSACTION_H__ */
|
||||
|
@ -100,9 +100,7 @@ struct _split
|
||||
* it's NULL until accessed. */
|
||||
kvp_frame * kvp_data;
|
||||
|
||||
/* The reconciled field ...
|
||||
*/
|
||||
char reconciled;
|
||||
char reconciled; /* The reconciled field */
|
||||
Timespec date_reconciled; /* date split was reconciled */
|
||||
|
||||
/* value is the amount of the account's currency involved,
|
||||
@ -155,7 +153,7 @@ struct _transaction
|
||||
* it's NULL until accessed. */
|
||||
kvp_frame * kvp_data;
|
||||
|
||||
Split **splits; /* list of splits, null terminated */
|
||||
GList *splits; /* list of splits */
|
||||
|
||||
/* marker is used to track the progress of transaction traversals.
|
||||
* 0 is never a legitimate marker value, so we can tell is we hit
|
||||
@ -192,7 +190,7 @@ void xaccSplitSetGUID (Split *split, GUID *guid);
|
||||
* not check to see if any of the member splits are referenced
|
||||
* by an account.
|
||||
*/
|
||||
void xaccFreeTransaction (Transaction *);
|
||||
void xaccFreeTransaction (Transaction *trans);
|
||||
|
||||
/* The xaccFreeSplit() method simply frees all memory associated
|
||||
* with the split. It does not verify that the split isn't
|
||||
@ -200,13 +198,7 @@ void xaccFreeTransaction (Transaction *);
|
||||
* account, then calling this method will leave the system in an
|
||||
* inconsistent state.
|
||||
*/
|
||||
void xaccFreeSplit (Split *); /* frees memory */
|
||||
|
||||
/* The xaccTransRemoveSplit() routine will remove the indicated
|
||||
* split from the transaction. It will *NOT* otherwise
|
||||
* re-adjust balances, modify accounts, etc.
|
||||
*/
|
||||
void xaccTransRemoveSplit (Transaction*, Split *);
|
||||
void xaccFreeSplit (Split *split); /* frees memory */
|
||||
|
||||
|
||||
/*
|
||||
@ -216,7 +208,7 @@ void xaccTransRemoveSplit (Transaction*, Split *);
|
||||
* splits in a transaction to total up to exactly zero.
|
||||
*
|
||||
* It is worthwhile to understand the algorithm that this routine
|
||||
* uses to acheive balance. It goes like this:
|
||||
* uses to achieve balance. It goes like this:
|
||||
* If the indicated split is a destination split (i.e. is not
|
||||
* the first split), then the total value of the destination
|
||||
* splits is computed, and the value of the source split (ie.
|
||||
@ -224,7 +216,7 @@ void xaccTransRemoveSplit (Transaction*, Split *);
|
||||
* (the share price of the source split is not changed).
|
||||
* If the indicated split is the source split, then the value
|
||||
* of the very first destination split is adjusted so that
|
||||
* the balance is zero. If there is not destination split,
|
||||
* the balance is zero. If there is not destination split,
|
||||
* one of two outcomes are possible, depending on whether
|
||||
* "forced_double_entry" is enabled or disabled.
|
||||
* (1) if forced-double-entry is disabled, the fact that
|
||||
@ -236,12 +228,12 @@ void xaccTransRemoveSplit (Transaction*, Split *);
|
||||
* destination split properly.
|
||||
*/
|
||||
|
||||
void xaccSplitRebalance (Split *);
|
||||
void xaccSplitRebalance (Split *split);
|
||||
|
||||
|
||||
/* FIXME: this is probably wrong, but it'll have to wait until Bill
|
||||
returns. It's *ONLY* for file IO. Don't use these elsewhere. */
|
||||
void xaccSplitSetValueDirectly(Split *s, gnc_numeric n);
|
||||
void xaccSplitSetQuantityDirectly(Split *s, gnc_numeric n);
|
||||
void xaccSplitSetValueDirectly(Split *split, gnc_numeric value);
|
||||
void xaccSplitSetQuantityDirectly(Split *split, gnc_numeric quantity);
|
||||
|
||||
#endif /* __XACC_TRANSACTION_P_H__ */
|
||||
|
@ -662,20 +662,6 @@ readAccount( int fd, AccountGroup *grp, int token )
|
||||
"\texpected %d got %d transactions \n",numTrans,i);
|
||||
break;
|
||||
}
|
||||
#ifdef DELINT_BLANK_SPLITS_HACK
|
||||
/* This is dangerous, as it can destroy real data. */
|
||||
{
|
||||
int j=0;
|
||||
Split *s = trans->splits[0];
|
||||
while (s) {
|
||||
if (DEQ(0.0,s->damount) && DEQ (1.0,s->share_price)) {
|
||||
xaccTransRemoveSplit (trans, s);
|
||||
break;
|
||||
}
|
||||
j++; s=trans->splits[j];
|
||||
}
|
||||
}
|
||||
#endif /* DELINT_BLANK_SPLITS_HACK */
|
||||
}
|
||||
|
||||
/* Not needed now. Since we always look in ids_to_finished_accounts
|
||||
@ -780,6 +766,40 @@ readAccInfo(int fd, Account *acc, int token) {
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
xaccTransSetMemo (Transaction *trans, const char *memo)
|
||||
{
|
||||
Split *s;
|
||||
|
||||
if (!trans || !memo) return;
|
||||
|
||||
s = xaccTransGetSplit (trans, 0);
|
||||
xaccSplitSetMemo (s, memo);
|
||||
|
||||
if (xaccTransCountSplits (trans) != 2)
|
||||
return;
|
||||
|
||||
s = xaccTransGetSplit (trans, 1);
|
||||
xaccSplitSetMemo (s, memo);
|
||||
}
|
||||
|
||||
static void
|
||||
xaccTransSetAction (Transaction *trans, const char *action)
|
||||
{
|
||||
Split *s;
|
||||
|
||||
if (!trans || !action) return;
|
||||
|
||||
s = xaccTransGetSplit (trans, 0);
|
||||
xaccSplitSetAction (s, action);
|
||||
|
||||
if (xaccTransCountSplits (trans) != 2)
|
||||
return;
|
||||
|
||||
s = xaccTransGetSplit (trans, 1);
|
||||
xaccSplitSetAction (s, action);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* readTransaction *
|
||||
* reads in the data for a transaction from the datafile *
|
||||
@ -809,6 +829,12 @@ readTransaction( int fd, Account *acc, int token )
|
||||
trans = xaccMallocTransaction();
|
||||
xaccTransBeginEdit (trans, 1);
|
||||
|
||||
/* add in one split -- xaccMallocTransaction no longer auto-creates them. */
|
||||
{
|
||||
Split *s = xaccMallocSplit ();
|
||||
xaccTransAppendSplit (trans, s);
|
||||
}
|
||||
|
||||
tmp = readString( fd, token );
|
||||
if (NULL == tmp)
|
||||
{
|
||||
@ -1084,14 +1110,16 @@ readTransaction( int fd, Account *acc, int token )
|
||||
|
||||
if (5 == token)
|
||||
{
|
||||
Split *s = trans->splits->data;
|
||||
|
||||
/* Version 5 files included a split that immediately
|
||||
* followed the transaction, before the destination splits.
|
||||
* Later versions don't have this. */
|
||||
offset = 1;
|
||||
split = readSplit (fd, token);
|
||||
xaccRemoveEntity(&trans->splits[0]->guid);
|
||||
xaccFreeSplit (trans->splits[0]);
|
||||
trans->splits[0] = split;
|
||||
xaccRemoveEntity(&s->guid);
|
||||
xaccFreeSplit (s);
|
||||
trans->splits->data = split;
|
||||
split->parent = trans;
|
||||
}
|
||||
|
||||
@ -1108,13 +1136,14 @@ readTransaction( int fd, Account *acc, int token )
|
||||
for (i=0; i<numSplits; i++) {
|
||||
split = readSplit (fd, token);
|
||||
if (0 == i+offset) {
|
||||
Split *s = trans->splits->data;
|
||||
/* the first split has been malloced. just replace it */
|
||||
xaccRemoveEntity (&trans->splits[i+offset]->guid);
|
||||
xaccFreeSplit (trans->splits[i+offset]);
|
||||
trans->splits[i+offset] = split;
|
||||
xaccRemoveEntity (&s->guid);
|
||||
xaccFreeSplit (s);
|
||||
trans->splits->data = split;
|
||||
split->parent = trans;
|
||||
} else {
|
||||
xaccTransAppendSplit( trans, split);
|
||||
xaccTransAppendSplit(trans, split);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3344,22 +3344,11 @@ txn_restore_start_handler(GSList* sibling_data,
|
||||
gpointer *result,
|
||||
const gchar *tag) {
|
||||
Transaction *trans = xaccMallocTransaction();
|
||||
|
||||
|
||||
if(!trans) return(FALSE);
|
||||
|
||||
xaccTransBeginEdit(trans, 1);
|
||||
|
||||
/* Kill the pointless initial splits -- why are these here?
|
||||
FIXME: Can we kill them in Transaction.c? */
|
||||
{
|
||||
int i = 0;
|
||||
Split *useless;
|
||||
while((useless = xaccTransGetSplit(trans, i))) {
|
||||
xaccSplitDestroy(useless);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
*data_for_children = trans;
|
||||
|
||||
return(TRUE);
|
||||
|
@ -726,9 +726,11 @@ gnc_xfer_dialog_ok_cb(GtkWidget * widget, gpointer data)
|
||||
string = gtk_entry_get_text(GTK_ENTRY(xferData->description_entry));
|
||||
xaccTransSetDescription(trans, string);
|
||||
|
||||
/* first split is already there */
|
||||
curr_split = xaccTransGetSplit(trans, 0);
|
||||
/* second split must be created */
|
||||
/* create first split */
|
||||
curr_split = xaccMallocSplit();
|
||||
xaccTransAppendSplit(trans, curr_split);
|
||||
|
||||
/* create second split */
|
||||
from_split = xaccMallocSplit();
|
||||
xaccTransAppendSplit(trans, from_split);
|
||||
|
||||
@ -741,9 +743,10 @@ gnc_xfer_dialog_ok_cb(GtkWidget * widget, gpointer data)
|
||||
DxaccSplitSetBaseValue(curr_split, amount, from_currency);
|
||||
DxaccSplitSetBaseValue(curr_split, to_amount, to_currency);
|
||||
|
||||
/* TransSetMemo will set the memo for both splits */
|
||||
/* Set the memo fields */
|
||||
string = gtk_entry_get_text(GTK_ENTRY(xferData->memo_entry));
|
||||
xaccTransSetMemo(trans, string);
|
||||
xaccSplitSetMemo(curr_split, string);
|
||||
xaccSplitSetMemo(from_split, string);
|
||||
|
||||
/* finish transaction */
|
||||
xaccAccountCommitEdit(from);
|
||||
@ -763,9 +766,11 @@ gnc_xfer_dialog_ok_cb(GtkWidget * widget, gpointer data)
|
||||
string = gtk_entry_get_text(GTK_ENTRY(xferData->description_entry));
|
||||
xaccTransSetDescription(trans, string);
|
||||
|
||||
/* first split is already there */
|
||||
curr_split = xaccTransGetSplit(trans, 0);
|
||||
/* second split must be created */
|
||||
/* create first split */
|
||||
curr_split = xaccMallocSplit();
|
||||
xaccTransAppendSplit(trans, curr_split);
|
||||
|
||||
/* create second split */
|
||||
to_split = xaccMallocSplit();
|
||||
xaccTransAppendSplit(trans, to_split);
|
||||
|
||||
@ -778,9 +783,10 @@ gnc_xfer_dialog_ok_cb(GtkWidget * widget, gpointer data)
|
||||
DxaccSplitSetBaseValue(curr_split, -amount, from_currency);
|
||||
DxaccSplitSetBaseValue(curr_split, -to_amount, to_currency);
|
||||
|
||||
/* TransSetMemo will set the memo for both splits */
|
||||
/* set the memo fields */
|
||||
string = gtk_entry_get_text(GTK_ENTRY(xferData->memo_entry));
|
||||
xaccTransSetMemo(trans, string);
|
||||
xaccSplitSetMemo(curr_split, string);
|
||||
xaccSplitSetMemo(to_split, string);
|
||||
|
||||
/* finish transaction */
|
||||
xaccAccountCommitEdit(curr);
|
||||
@ -806,18 +812,20 @@ gnc_xfer_dialog_ok_cb(GtkWidget * widget, gpointer data)
|
||||
string = gtk_entry_get_text(GTK_ENTRY(xferData->description_entry));
|
||||
xaccTransSetDescription(trans, string);
|
||||
|
||||
/* first split is already there */
|
||||
to_split = xaccTransGetSplit(trans, 0);
|
||||
/* create first split */
|
||||
to_split = xaccMallocSplit();
|
||||
xaccTransAppendSplit(trans, to_split);
|
||||
DxaccSplitSetShareAmount(to_split, amount);
|
||||
|
||||
/* second split must be created */
|
||||
/* create second split */
|
||||
from_split = xaccMallocSplit();
|
||||
DxaccSplitSetShareAmount(from_split, -amount);
|
||||
xaccTransAppendSplit(trans, from_split);
|
||||
|
||||
/* TransSetMemo will set the memo for both splits */
|
||||
/* set the memo fields */
|
||||
string = gtk_entry_get_text(GTK_ENTRY(xferData->memo_entry));
|
||||
xaccTransSetMemo(trans, string);
|
||||
xaccSplitSetMemo(to_split, string);
|
||||
xaccSplitSetMemo(from_split, string);
|
||||
|
||||
/* Now do the 'to' account */
|
||||
xaccAccountBeginEdit(to);
|
||||
|
@ -234,20 +234,11 @@
|
||||
(let ((gnc-xtn (gnc:transaction-create)))
|
||||
(gnc:transaction-begin-edit gnc-xtn 1)
|
||||
|
||||
;; destroy any automagic splits in the transaction
|
||||
(let ((numsplits (gnc:transaction-get-split-count gnc-xtn)))
|
||||
(if (not (eqv? 0 numsplits))
|
||||
(let splitloop ((ind (- numsplits 1)))
|
||||
(gnc:split-destroy
|
||||
(gnc:transaction-get-split gnc-xtn ind))
|
||||
(if (> ind 0)
|
||||
(loop (- ind 1))))))
|
||||
|
||||
;; build the transaction
|
||||
(qif-import:qif-xtn-to-gnc-xtn
|
||||
xtn qif-file gnc-xtn gnc-acct-hash
|
||||
qif-acct-map qif-cat-map)
|
||||
|
||||
|
||||
;; rebalance and commit everything
|
||||
(gnc:transaction-commit-edit gnc-xtn)))))
|
||||
(qif-file:xtns qif-file)))
|
||||
|
Loading…
Reference in New Issue
Block a user