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);
|
xaccTransBeginEdit (trans, TRUE);
|
||||||
xaccTransSetDateSecs (trans, info->last_date_entered);
|
xaccTransSetDateSecs (trans, info->last_date_entered);
|
||||||
|
blank_split = xaccMallocSplit ();
|
||||||
|
xaccTransAppendSplit (trans, blank_split);
|
||||||
xaccTransCommitEdit (trans);
|
xaccTransCommitEdit (trans);
|
||||||
|
|
||||||
blank_split = xaccTransGetSplit (trans, 0);
|
|
||||||
info->blank_split_guid = *xaccSplitGetGUID (blank_split);
|
info->blank_split_guid = *xaccSplitGetGUID (blank_split);
|
||||||
|
|
||||||
info->blank_split_edited = FALSE;
|
info->blank_split_edited = FALSE;
|
||||||
|
@ -664,30 +664,25 @@ xaccAccountFixSplitDateOrder (Account * acc, Split *split ) {
|
|||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
* xaccCheckTransDateOrder *
|
* xaccCheckTransDateOrder *
|
||||||
* check this transaction to see if the date is in correct order *
|
* 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 *
|
* This routine perfroms the check for both of the double-entry *
|
||||||
* transaction entries ... *
|
* transaction entries. *
|
||||||
* *
|
* *
|
||||||
* Args: trans -- the transaction to check *
|
* Args: trans -- the transaction to check *
|
||||||
* Return: int -- non-zero if out of order *
|
* Return: int -- non-zero if out of order *
|
||||||
\********************************************************************/
|
\********************************************************************/
|
||||||
|
|
||||||
void
|
void
|
||||||
xaccTransFixSplitDateOrder (Transaction *trans )
|
xaccTransFixSplitDateOrder (Transaction *trans)
|
||||||
{
|
{
|
||||||
Account * acc;
|
GList *node;
|
||||||
Split *s;
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
if (NULL == trans) return;
|
if (trans == NULL) return;
|
||||||
|
|
||||||
i=0;
|
for (node = trans->splits; node; node = node->next)
|
||||||
s = trans->splits[0];
|
{
|
||||||
while (s) {
|
Split *s = node->data;
|
||||||
acc = (Account *) (s->acc);
|
xaccAccountFixSplitDateOrder (s->acc, s);
|
||||||
xaccAccountFixSplitDateOrder (acc, s);
|
|
||||||
i++;
|
|
||||||
s = trans->splits[i];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ struct _account {
|
|||||||
gnc_numeric share_cleared_balance;
|
gnc_numeric share_cleared_balance;
|
||||||
gnc_numeric share_reconciled_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.
|
/* The "changed" flag is used to invalidate cached values in this structure.
|
||||||
* Currently, the balances and the cost basis are cached.
|
* Currently, the balances and the cost basis are cached.
|
||||||
|
@ -64,21 +64,21 @@ xaccAccountGetBackend (Account * acc)
|
|||||||
Backend *
|
Backend *
|
||||||
xaccTransactionGetBackend (Transaction *trans)
|
xaccTransactionGetBackend (Transaction *trans)
|
||||||
{
|
{
|
||||||
Backend *be;
|
GList *node;
|
||||||
Split *s;
|
Split *s;
|
||||||
|
|
||||||
if (!trans) return NULL;
|
if (!trans) return NULL;
|
||||||
|
|
||||||
/* find an account */
|
/* find an account */
|
||||||
s = trans->splits[0];
|
s = xaccTransGetSplit (trans, 0);
|
||||||
if (!s) return NULL;
|
if (!s) return NULL;
|
||||||
|
|
||||||
/* I suppose it would be more 'technically correct' to make sure that
|
/* 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
|
* 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 xaccAccountGetBackend (s->acc);
|
||||||
return be;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
|
@ -22,12 +22,12 @@
|
|||||||
\********************************************************************/
|
\********************************************************************/
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include "Account.h"
|
#include "Account.h"
|
||||||
#include "AccountP.h"
|
#include "AccountP.h"
|
||||||
#include "DateUtils.h"
|
#include "DateUtils.h"
|
||||||
@ -189,8 +189,7 @@ xaccCloseLog (void)
|
|||||||
void
|
void
|
||||||
xaccTransWriteLog (Transaction *trans, char flag)
|
xaccTransWriteLog (Transaction *trans, char flag)
|
||||||
{
|
{
|
||||||
Split *split;
|
GList *node;
|
||||||
int i = 0;
|
|
||||||
char *dnow, *dent, *dpost, *drecn;
|
char *dnow, *dent, *dpost, *drecn;
|
||||||
|
|
||||||
if (!gen_logs) return;
|
if (!gen_logs) return;
|
||||||
@ -202,10 +201,13 @@ xaccTransWriteLog (Transaction *trans, char flag)
|
|||||||
|
|
||||||
fprintf (trans_log, "===== START\n");
|
fprintf (trans_log, "===== START\n");
|
||||||
|
|
||||||
split = trans->splits[0];
|
for (node = trans->splits; node; node = node->next) {
|
||||||
while (split) {
|
Split *split = node->data;
|
||||||
char * accname = "";
|
char * accname = "";
|
||||||
if (split->acc) accname = split->acc->accountName;
|
|
||||||
|
if (split->acc)
|
||||||
|
accname = split->acc->accountName;
|
||||||
|
|
||||||
drecn = xaccDateUtilGetStamp (split->date_reconciled.tv_sec);
|
drecn = xaccDateUtilGetStamp (split->date_reconciled.tv_sec);
|
||||||
|
|
||||||
/* use tab-separated fields */
|
/* use tab-separated fields */
|
||||||
@ -229,9 +231,8 @@ xaccTransWriteLog (Transaction *trans, char flag)
|
|||||||
drecn
|
drecn
|
||||||
);
|
);
|
||||||
free (drecn);
|
free (drecn);
|
||||||
i++;
|
|
||||||
split = trans->splits[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf (trans_log, "===== END\n");
|
fprintf (trans_log, "===== END\n");
|
||||||
free (dnow);
|
free (dnow);
|
||||||
free (dent);
|
free (dent);
|
||||||
|
@ -23,14 +23,14 @@
|
|||||||
* *
|
* *
|
||||||
\********************************************************************/
|
\********************************************************************/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include "Account.h"
|
#include "Account.h"
|
||||||
#include "AccountP.h"
|
#include "AccountP.h"
|
||||||
#include "BackendP.h"
|
#include "BackendP.h"
|
||||||
@ -300,12 +300,12 @@ xaccConfigGetForceDoubleEntry (void)
|
|||||||
static void
|
static void
|
||||||
MarkChanged (Transaction *trans)
|
MarkChanged (Transaction *trans)
|
||||||
{
|
{
|
||||||
if (trans->splits) {
|
GList *node;
|
||||||
int i=0;
|
|
||||||
while (trans->splits[i]) {
|
for (node = trans->splits; node; node = node->next)
|
||||||
MARK_SPLIT (trans->splits[i]);
|
{
|
||||||
i++;
|
Split *s = node->data;
|
||||||
}
|
MARK_SPLIT (s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -554,23 +554,13 @@ xaccSplitGetShareReconciledBalance (Split *s) {
|
|||||||
\********************************************************************/
|
\********************************************************************/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xaccInitTransaction( Transaction * trans )
|
xaccInitTransaction (Transaction * trans)
|
||||||
{
|
{
|
||||||
Split *split;
|
|
||||||
|
|
||||||
/* Fill in some sane defaults */
|
/* Fill in some sane defaults */
|
||||||
trans->num = g_strdup("");
|
trans->num = g_strdup("");
|
||||||
trans->description = g_strdup("");
|
trans->description = g_strdup("");
|
||||||
|
|
||||||
trans->splits = g_malloc (3 * sizeof (Split *));
|
trans->splits = NULL;
|
||||||
|
|
||||||
/* Create a single split only. As soon as the balance becomes
|
|
||||||
* non-zero, additional splits will get created.
|
|
||||||
*/
|
|
||||||
split = xaccMallocSplit ();
|
|
||||||
split->parent = trans;
|
|
||||||
trans->splits[0] = split;
|
|
||||||
trans->splits[1] = NULL;
|
|
||||||
|
|
||||||
trans->date_entered.tv_sec = 0;
|
trans->date_entered.tv_sec = 0;
|
||||||
trans->date_entered.tv_nsec = 0;
|
trans->date_entered.tv_nsec = 0;
|
||||||
@ -611,22 +601,16 @@ static Transaction *
|
|||||||
xaccCloneTransaction (Transaction *t)
|
xaccCloneTransaction (Transaction *t)
|
||||||
{
|
{
|
||||||
Transaction *trans;
|
Transaction *trans;
|
||||||
int n;
|
GList *node;
|
||||||
|
|
||||||
trans = g_new(Transaction, 1);
|
trans = g_new(Transaction, 1);
|
||||||
|
|
||||||
trans->num = g_strdup(t->num);
|
trans->num = g_strdup(t->num);
|
||||||
trans->description = g_strdup(t->description);
|
trans->description = g_strdup(t->description);
|
||||||
|
|
||||||
n=0; while (t->splits[n]) n++;
|
trans->splits = g_list_copy (t->splits);
|
||||||
trans->splits = g_malloc ((n+1)* sizeof (Split *));
|
for (node = trans->splits; node; node = node->next)
|
||||||
|
node->data = xaccCloneSplit (node->data);
|
||||||
n=0;
|
|
||||||
while (t->splits[n]) {
|
|
||||||
trans->splits[n] = xaccCloneSplit (t->splits[n]);
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
trans->splits[n] = NULL;
|
|
||||||
|
|
||||||
trans->date_entered.tv_sec = t->date_entered.tv_sec;
|
trans->date_entered.tv_sec = t->date_entered.tv_sec;
|
||||||
trans->date_entered.tv_nsec = t->date_entered.tv_nsec;
|
trans->date_entered.tv_nsec = t->date_entered.tv_nsec;
|
||||||
@ -649,27 +633,19 @@ xaccCloneTransaction (Transaction *t)
|
|||||||
\********************************************************************/
|
\********************************************************************/
|
||||||
|
|
||||||
void
|
void
|
||||||
xaccFreeTransaction( Transaction *trans )
|
xaccFreeTransaction (Transaction *trans)
|
||||||
{
|
{
|
||||||
int i;
|
GList *node;
|
||||||
Split *s;
|
|
||||||
|
|
||||||
if (!trans) return;
|
if (!trans) return;
|
||||||
|
|
||||||
ENTER ("addr=%p\n", trans);
|
ENTER ("addr=%p\n", trans);
|
||||||
|
|
||||||
/* free up the destination splits */
|
/* free up the destination splits */
|
||||||
if (trans->splits) {
|
for (node = trans->splits; node; node = node->next)
|
||||||
i = 0;
|
xaccFreeSplit (node->data);
|
||||||
s = trans->splits[i];
|
g_list_free (trans->splits);
|
||||||
while (s) {
|
trans->splits = NULL;
|
||||||
xaccFreeSplit (s);
|
|
||||||
i++;
|
|
||||||
s = trans->splits[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (trans->splits);
|
|
||||||
|
|
||||||
/* free up transaction strings */
|
/* free up transaction strings */
|
||||||
g_free (trans->num);
|
g_free (trans->num);
|
||||||
@ -728,23 +704,25 @@ xaccTransEqual(const Transaction *ta, const Transaction *tb,
|
|||||||
if(kvp_frame_compare(ta->kvp_data, tb->kvp_data) != 0) return FALSE;
|
if(kvp_frame_compare(ta->kvp_data, tb->kvp_data) != 0) return FALSE;
|
||||||
|
|
||||||
if(check_splits) {
|
if(check_splits) {
|
||||||
Split** sa = ta->splits;
|
GList *sa = ta->splits;
|
||||||
Split** sb = tb->splits;
|
GList *sb = tb->splits;
|
||||||
|
|
||||||
if(!sa && sb) return FALSE;
|
if(!sa && sb) return FALSE;
|
||||||
if(!sb && sa) return FALSE;
|
if(!sb && sa) return FALSE;
|
||||||
|
|
||||||
if(sa && sb) {
|
if(sa && sb) {
|
||||||
/* presume that the splits are in the same order */
|
/* presume that the splits are in the same order */
|
||||||
while(*sa && *sb) {
|
while(sa && sb) {
|
||||||
if(!xaccSplitEqual(*sa, *sb, check_guids, FALSE)) return(FALSE);
|
if(!xaccSplitEqual(sa->data, sb->data, check_guids, FALSE))
|
||||||
sa++;
|
return(FALSE);
|
||||||
sb++;
|
sa = sa->next;
|
||||||
|
sb = sb->next;
|
||||||
}
|
}
|
||||||
if(*sa != NULL) return(FALSE);
|
if(sa != NULL) return(FALSE);
|
||||||
if(*sb != NULL) return(FALSE);
|
if(sb != NULL) return(FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -918,18 +896,21 @@ xaccSplitGetBaseValue (Split *s, const gnc_commodity * base_currency) {
|
|||||||
\********************************************************************/
|
\********************************************************************/
|
||||||
|
|
||||||
static gnc_numeric
|
static gnc_numeric
|
||||||
ComputeValue (Split **sarray, Split * skip_me,
|
ComputeValue (GList *splits, Split * skip_me,
|
||||||
const gnc_commodity * base_currency)
|
const gnc_commodity * base_currency)
|
||||||
{
|
{
|
||||||
Split *s;
|
GList *node;
|
||||||
int i=0;
|
|
||||||
gnc_numeric value;
|
gnc_numeric value;
|
||||||
|
|
||||||
s = sarray[0];
|
|
||||||
value = gnc_numeric_zero();
|
value = gnc_numeric_zero();
|
||||||
|
|
||||||
while (s) {
|
for (node = splits; node; node = node->next)
|
||||||
if (s != skip_me) {
|
{
|
||||||
|
Split *s = node->data;
|
||||||
|
|
||||||
|
if (s == skip_me)
|
||||||
|
continue;
|
||||||
|
|
||||||
/* ahh -- users may not want or use the double entry
|
/* ahh -- users may not want or use the double entry
|
||||||
* features of this engine. So, in particular, there
|
* features of this engine. So, in particular, there
|
||||||
* may be the occasional split without a parent account.
|
* may be the occasional split without a parent account.
|
||||||
@ -969,8 +950,6 @@ ComputeValue (Split **sarray, Split * skip_me,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i++; s = sarray [i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@ -1020,36 +999,30 @@ xaccIsCommonCurrency(const gnc_commodity * currency_1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const gnc_commodity *
|
static const gnc_commodity *
|
||||||
FindCommonExclSCurrency (Split **slist, const gnc_commodity * ra,
|
FindCommonExclSCurrency (GList *splits, const gnc_commodity * ra,
|
||||||
const gnc_commodity * rb, Split *excl_split) {
|
const gnc_commodity * rb, Split *excl_split)
|
||||||
Split * s;
|
{
|
||||||
int i = 0;
|
GList *node;
|
||||||
|
|
||||||
if (!slist) return NULL;
|
if (!splits) return NULL;
|
||||||
|
|
||||||
i = 0;
|
for (node = splits; node; node = node->next)
|
||||||
s = slist[0];
|
{
|
||||||
|
Split *s = node->data;
|
||||||
/* If s is to be excluded, go ahead in the list until one split is
|
|
||||||
not excluded or is NULL. */
|
|
||||||
while (s && (s == excl_split)) {
|
|
||||||
i++; s = slist[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
while (s) {
|
|
||||||
const gnc_commodity * sa, * sb;
|
const gnc_commodity * sa, * sb;
|
||||||
|
|
||||||
|
if (s == excl_split)
|
||||||
|
continue;
|
||||||
|
|
||||||
/* Novice/casual users may not want or use the double entry
|
/* Novice/casual users may not want or use the double entry
|
||||||
* features of this engine. Because of this, there
|
* features of this engine. Because of this, there
|
||||||
* may be the occasional split without a parent account.
|
* may be the occasional split without a parent account.
|
||||||
* Well, that's ok, we'll just go with the flow.
|
* Well, that's ok, we'll just go with the flow.
|
||||||
*/
|
*/
|
||||||
if (force_double_entry) {
|
if (force_double_entry)
|
||||||
assert (s->acc);
|
assert (s->acc);
|
||||||
} else
|
else if (s->acc == NULL)
|
||||||
if (NULL == s->acc) {
|
continue;
|
||||||
i++; s=slist[i]; continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
sa = s->acc->currency;
|
sa = s->acc->currency;
|
||||||
sb = s->acc->security;
|
sb = s->acc->security;
|
||||||
@ -1080,14 +1053,6 @@ FindCommonExclSCurrency (Split **slist, const gnc_commodity * ra,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((!ra) && (!rb)) return NULL;
|
if ((!ra) && (!rb)) return NULL;
|
||||||
|
|
||||||
i++;
|
|
||||||
s = slist[i];
|
|
||||||
|
|
||||||
/* If s is to be excluded, go ahead in the list until one split is
|
|
||||||
not excluded or is NULL. */
|
|
||||||
while (s && (s == excl_split))
|
|
||||||
{ i++; s = slist[i]; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ra);
|
return (ra);
|
||||||
@ -1098,23 +1063,26 @@ FindCommonExclSCurrency (Split **slist, const gnc_commodity * ra,
|
|||||||
* common currency.
|
* common currency.
|
||||||
*/
|
*/
|
||||||
static const gnc_commodity *
|
static const gnc_commodity *
|
||||||
FindCommonCurrency (Split **slist,
|
FindCommonCurrency (GList *splits,
|
||||||
const gnc_commodity * ra, const gnc_commodity * rb)
|
const gnc_commodity * ra, const gnc_commodity * rb)
|
||||||
{
|
{
|
||||||
return FindCommonExclSCurrency(slist, ra, rb, NULL);
|
return FindCommonExclSCurrency(splits, ra, rb, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
const gnc_commodity *
|
const gnc_commodity *
|
||||||
xaccTransFindCommonCurrency (Transaction *trans)
|
xaccTransFindCommonCurrency (Transaction *trans)
|
||||||
{
|
{
|
||||||
const gnc_commodity * ra, * rb;
|
const gnc_commodity * ra, * rb;
|
||||||
|
Split *split;
|
||||||
|
|
||||||
if (trans->splits == NULL) return NULL;
|
if (trans->splits == NULL) return NULL;
|
||||||
if (trans->splits[0] == NULL) return NULL;
|
|
||||||
if (trans->splits[0]->acc == NULL) return NULL;
|
|
||||||
|
|
||||||
ra = trans->splits[0]->acc->currency;
|
split = trans->splits->data;
|
||||||
rb = trans->splits[0]->acc->security;
|
|
||||||
|
if (split->acc == NULL) return NULL;
|
||||||
|
|
||||||
|
ra = split->acc->currency;
|
||||||
|
rb = split->acc->security;
|
||||||
|
|
||||||
return FindCommonCurrency (trans->splits, ra, rb);
|
return FindCommonCurrency (trans->splits, ra, rb);
|
||||||
}
|
}
|
||||||
@ -1145,15 +1113,16 @@ xaccTransIsCommonExclSCurrency (Transaction *trans,
|
|||||||
static void
|
static void
|
||||||
xaccTransRebalance (Transaction * trans)
|
xaccTransRebalance (Transaction * trans)
|
||||||
{
|
{
|
||||||
xaccSplitRebalance (trans->splits[0]);
|
if (!trans || !trans->splits)
|
||||||
|
return;
|
||||||
|
|
||||||
|
xaccSplitRebalance (trans->splits->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
xaccSplitRebalance (Split *split)
|
xaccSplitRebalance (Split *split)
|
||||||
{
|
{
|
||||||
Transaction *trans;
|
Transaction *trans;
|
||||||
Split *s;
|
|
||||||
int i = 0;
|
|
||||||
gnc_numeric value;
|
gnc_numeric value;
|
||||||
const gnc_commodity * base_currency = NULL;
|
const gnc_commodity * base_currency = NULL;
|
||||||
|
|
||||||
@ -1174,7 +1143,7 @@ xaccSplitRebalance (Split *split)
|
|||||||
if(split->acc->editlevel > 0) return;
|
if(split->acc->editlevel > 0) return;
|
||||||
|
|
||||||
assert (trans->splits);
|
assert (trans->splits);
|
||||||
assert (trans->splits[0]);
|
assert (trans->splits->data);
|
||||||
|
|
||||||
/* lets find out if we are dealing with multiple currencies,
|
/* lets find out if we are dealing with multiple currencies,
|
||||||
* and which one(s) all of the splits have in common. */
|
* and which one(s) all of the splits have in common. */
|
||||||
@ -1183,9 +1152,11 @@ xaccSplitRebalance (Split *split)
|
|||||||
base_currency = FindCommonCurrency (trans->splits, ra, rb);
|
base_currency = FindCommonCurrency (trans->splits, ra, rb);
|
||||||
|
|
||||||
if (!base_currency) {
|
if (!base_currency) {
|
||||||
|
GList *node;
|
||||||
PERR ("no common split currencies\n");
|
PERR ("no common split currencies\n");
|
||||||
s = trans->splits[0];
|
for (node = trans->splits; node; node = node->next) {
|
||||||
while (s) {
|
Split *s = node->data;
|
||||||
|
|
||||||
if (s->acc) {
|
if (s->acc) {
|
||||||
PERR ("\taccount=%s currency=%s security=%s\n",
|
PERR ("\taccount=%s currency=%s security=%s\n",
|
||||||
s->acc->accountName,
|
s->acc->accountName,
|
||||||
@ -1194,24 +1165,25 @@ xaccSplitRebalance (Split *split)
|
|||||||
} else {
|
} else {
|
||||||
PERR ("\t*** No parent account *** \n");
|
PERR ("\t*** No parent account *** \n");
|
||||||
}
|
}
|
||||||
i++; s = trans->splits[i];
|
|
||||||
}
|
}
|
||||||
assert (0);
|
assert (0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert (trans->splits);
|
assert (trans->splits);
|
||||||
assert (trans->splits[0]);
|
assert (trans->splits->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (split == trans->splits[0]) {
|
if (split == trans->splits->data) {
|
||||||
|
Split *s;
|
||||||
|
|
||||||
/* The indicated split is the source split.
|
/* The indicated split is the source split.
|
||||||
* Pick a destination split (by default,
|
* Pick a destination split (by default,
|
||||||
* the first destination split), and force
|
* the first destination split), and force
|
||||||
* the total on it.
|
* the total on it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
s = trans->splits[1];
|
s = g_list_nth_data (trans->splits, 1);
|
||||||
if (s) {
|
if (s) {
|
||||||
/* the new value of the destination split will be the result. */
|
/* the new value of the destination split will be the result. */
|
||||||
value = ComputeValue (trans->splits, s, base_currency);
|
value = ComputeValue (trans->splits, s, base_currency);
|
||||||
@ -1225,9 +1197,10 @@ xaccSplitRebalance (Split *split)
|
|||||||
base_currency);
|
base_currency);
|
||||||
MARK_SPLIT (s);
|
MARK_SPLIT (s);
|
||||||
xaccAccountRecomputeBalance (s->acc);
|
xaccAccountRecomputeBalance (s->acc);
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
Split *s;
|
||||||
|
|
||||||
/* There are no destination splits !!
|
/* There are no destination splits !!
|
||||||
* Either this is allowed, in which case
|
* Either this is allowed, in which case
|
||||||
* we just blow it off, or its forbidden,
|
* we just blow it off, or its forbidden,
|
||||||
@ -1254,18 +1227,19 @@ xaccSplitRebalance (Split *split)
|
|||||||
|
|
||||||
s->memo = g_strdup (split->memo);
|
s->memo = g_strdup (split->memo);
|
||||||
s->action = g_strdup (split->action);
|
s->action = g_strdup (split->action);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
Split *s;
|
||||||
|
|
||||||
/* The indicated split is a destination split.
|
/* The indicated split is a destination split.
|
||||||
* Compute grand total of all destination splits,
|
* Compute grand total of all destination splits,
|
||||||
* and force the source split to balance.
|
* and force the source split to balance.
|
||||||
*/
|
*/
|
||||||
s = trans->splits[0];
|
|
||||||
|
s = trans->splits->data;
|
||||||
value = ComputeValue (trans->splits, s, base_currency);
|
value = ComputeValue (trans->splits, s, base_currency);
|
||||||
|
|
||||||
/* KLUDGE -- bg */
|
/* KLUDGE -- bg */
|
||||||
@ -1282,7 +1256,6 @@ xaccSplitRebalance (Split *split)
|
|||||||
* into the current account. If there's not current account,
|
* into the current account. If there's not current account,
|
||||||
* force them into a lost & found account */
|
* force them into a lost & found account */
|
||||||
/* hack alert -- implement the above */
|
/* hack alert -- implement the above */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
@ -1327,9 +1300,8 @@ xaccTransBeginEdit (Transaction *trans, gboolean defer)
|
|||||||
void
|
void
|
||||||
xaccTransCommitEdit (Transaction *trans)
|
xaccTransCommitEdit (Transaction *trans)
|
||||||
{
|
{
|
||||||
int i;
|
GList *node;
|
||||||
Split *split;
|
Split *split;
|
||||||
Account *acc;
|
|
||||||
Backend *be;
|
Backend *be;
|
||||||
|
|
||||||
if (!trans) return;
|
if (!trans) return;
|
||||||
@ -1341,8 +1313,7 @@ xaccTransCommitEdit (Transaction *trans)
|
|||||||
* has no splits in it, in which case we delete the transaction and
|
* has no splits in it, in which case we delete the transaction and
|
||||||
* return.
|
* return.
|
||||||
*/
|
*/
|
||||||
split = trans->splits[0];
|
if (!trans->splits || (trans->open & BEING_DESTROYED))
|
||||||
if (!split || (trans->open & BEING_DESTROYED))
|
|
||||||
{
|
{
|
||||||
PINFO ("delete trans at addr=%p\n", trans);
|
PINFO ("delete trans at addr=%p\n", trans);
|
||||||
/* Make a log in the journal before destruction. */
|
/* Make a log in the journal before destruction. */
|
||||||
@ -1352,6 +1323,8 @@ xaccTransCommitEdit (Transaction *trans)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
split = trans->splits->data;
|
||||||
|
|
||||||
/* try to get the sorting order lined up according to
|
/* try to get the sorting order lined up according to
|
||||||
* when the user typed things in. */
|
* when the user typed things in. */
|
||||||
if (0 == trans->date_entered.tv_sec) {
|
if (0 == trans->date_entered.tv_sec) {
|
||||||
@ -1362,7 +1335,7 @@ xaccTransCommitEdit (Transaction *trans)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Alternately the transaction may have only one split in
|
/* Alternately the transaction may have only one split in
|
||||||
* it, in which case ... that's OK if and only if the split has no
|
* it, in which case that's OK if and only if the split has no
|
||||||
* value (i.e. is only recording a price). Otherwise, a single
|
* value (i.e. is only recording a price). Otherwise, a single
|
||||||
* split with a value can't possibly balance, thus violating the
|
* split with a value can't possibly balance, thus violating the
|
||||||
* rules of double-entry, and that's way bogus. So create
|
* rules of double-entry, and that's way bogus. So create
|
||||||
@ -1370,7 +1343,8 @@ xaccTransCommitEdit (Transaction *trans)
|
|||||||
* or in some dummy account (if force==2).
|
* or in some dummy account (if force==2).
|
||||||
*/
|
*/
|
||||||
if ((1 == force_double_entry) &&
|
if ((1 == force_double_entry) &&
|
||||||
(NULL == trans->splits[1]) && (!gnc_numeric_zero_p(split->damount))) {
|
(NULL == g_list_nth(trans->splits, 1)) &&
|
||||||
|
(!gnc_numeric_zero_p(split->damount))) {
|
||||||
Split * s = xaccMallocSplit();
|
Split * s = xaccMallocSplit();
|
||||||
xaccTransAppendSplit (trans, s);
|
xaccTransAppendSplit (trans, s);
|
||||||
xaccAccountInsertSplit (split->acc, s);
|
xaccAccountInsertSplit (split->acc, s);
|
||||||
@ -1407,23 +1381,15 @@ xaccTransCommitEdit (Transaction *trans)
|
|||||||
/* ------------------------------------------------- */
|
/* ------------------------------------------------- */
|
||||||
/* Make sure all associated splits are in proper order
|
/* Make sure all associated splits are in proper order
|
||||||
* in their accounts. */
|
* in their accounts. */
|
||||||
i=0;
|
for (node = trans->splits; node; node = node->next) {
|
||||||
split = trans->splits[i];
|
split = node->data;
|
||||||
while (split) {
|
xaccAccountFixSplitDateOrder(split->acc, split);
|
||||||
acc = split ->acc;
|
|
||||||
xaccAccountFixSplitDateOrder(acc, trans->splits[i]);
|
|
||||||
i++;
|
|
||||||
split = trans->splits[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Recompute the account balances. */
|
/* Recompute the account balances. */
|
||||||
i=0;
|
for (node = trans->splits; node; node = node->next) {
|
||||||
split = trans->splits[i];
|
split = node->data;
|
||||||
while (split) {
|
xaccAccountRecomputeBalance (split->acc);
|
||||||
acc = split->acc;
|
|
||||||
xaccAccountRecomputeBalance (acc);
|
|
||||||
i++;
|
|
||||||
split = trans->splits[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trans->open = 0;
|
trans->open = 0;
|
||||||
@ -1441,9 +1407,8 @@ void
|
|||||||
xaccTransRollbackEdit (Transaction *trans)
|
xaccTransRollbackEdit (Transaction *trans)
|
||||||
{
|
{
|
||||||
Transaction *orig;
|
Transaction *orig;
|
||||||
Split *s, *so;
|
int force_it=0, mismatch=0;
|
||||||
Account * acc;
|
int i;
|
||||||
int force_it=0, mismatch=0, i;
|
|
||||||
|
|
||||||
if (!trans) return;
|
if (!trans) return;
|
||||||
|
|
||||||
@ -1476,16 +1441,25 @@ xaccTransRollbackEdit (Transaction *trans)
|
|||||||
* forcing will suck memory cycles. So instead we'll try the gentle
|
* forcing will suck memory cycles. So instead we'll try the gentle
|
||||||
* approach first. Note that even in the gentle approach, the
|
* approach first. Note that even in the gentle approach, the
|
||||||
* CheckDateOrder routine could be cpu-cyle brutal, so it maybe
|
* CheckDateOrder routine could be cpu-cyle brutal, so it maybe
|
||||||
* it could use some tuning ...
|
* it could use some tuning.
|
||||||
*/
|
*/
|
||||||
if (trans->open & BEING_DESTROYED) {
|
if (trans->open & BEING_DESTROYED) {
|
||||||
force_it = 1;
|
force_it = 1;
|
||||||
mismatch = 0;
|
mismatch = 0;
|
||||||
} else {
|
}
|
||||||
i=0;
|
else {
|
||||||
s = trans->splits[0];
|
GList *node;
|
||||||
so = orig->splits[0];
|
GList *node_orig;
|
||||||
while (s && so) {
|
Split *s, *so;
|
||||||
|
|
||||||
|
s = so = NULL;
|
||||||
|
|
||||||
|
for (i = 0, node = trans->splits, node_orig = orig->splits ;
|
||||||
|
node && node_orig ;
|
||||||
|
i++, node = node->next, node_orig = node_orig->next) {
|
||||||
|
s = node->data;
|
||||||
|
so = node_orig->data;
|
||||||
|
|
||||||
if (so->acc != s->acc) { force_it = 1; mismatch=i; break; }
|
if (so->acc != s->acc) { force_it = 1; mismatch=i; break; }
|
||||||
|
|
||||||
#define HONKY_CAT(val) { g_free(s->val); s->val=so->val; so->val=NULL; }
|
#define HONKY_CAT(val) { g_free(s->val); s->val=so->val; so->val=NULL; }
|
||||||
@ -1505,10 +1479,8 @@ xaccTransRollbackEdit (Transaction *trans)
|
|||||||
xaccAccountFixSplitDateOrder (s->acc, s);
|
xaccAccountFixSplitDateOrder (s->acc, s);
|
||||||
MARK_SPLIT (s);
|
MARK_SPLIT (s);
|
||||||
xaccAccountRecomputeBalance (s->acc);
|
xaccAccountRecomputeBalance (s->acc);
|
||||||
i++;
|
|
||||||
s = trans->splits[i];
|
|
||||||
so = orig->splits[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (so != s) { force_it = 1; mismatch=i; }
|
if (so != s) { force_it = 1; mismatch=i; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1517,38 +1489,43 @@ xaccTransRollbackEdit (Transaction *trans)
|
|||||||
* Unfortunately, this can suck up CPU cycles in the Remove/Insert routines.
|
* Unfortunately, this can suck up CPU cycles in the Remove/Insert routines.
|
||||||
*/
|
*/
|
||||||
if (force_it) {
|
if (force_it) {
|
||||||
i=0; s = trans->splits[i];
|
GList *node;
|
||||||
while (s && (i<mismatch)) {
|
|
||||||
xaccFreeSplit (orig->splits[i]);
|
for (i = 0, node = trans->splits ;
|
||||||
orig->splits[i] = s;
|
node && i < mismatch ;
|
||||||
i++;
|
i++, node = node->next) {
|
||||||
s = trans->splits[i];
|
Split *s = node->data;
|
||||||
|
GList *node_orig;
|
||||||
|
|
||||||
|
node_orig = g_list_nth (orig->splits, i);
|
||||||
|
xaccFreeSplit (node_orig->data);
|
||||||
|
node_orig->data = s;
|
||||||
}
|
}
|
||||||
i=mismatch; s = trans->splits[i];
|
|
||||||
while (s) {
|
for (node = g_list_nth (trans->splits, mismatch) ;
|
||||||
acc = s->acc;
|
node ; node = node->next) {
|
||||||
|
Split *s = node->data;
|
||||||
|
|
||||||
MARK_SPLIT (s);
|
MARK_SPLIT (s);
|
||||||
xaccAccountRemoveSplit (acc, s);
|
xaccAccountRemoveSplit (s->acc, s);
|
||||||
xaccAccountRecomputeBalance (acc);
|
xaccAccountRecomputeBalance (s->acc);
|
||||||
xaccRemoveEntity(&s->guid);
|
xaccRemoveEntity(&s->guid);
|
||||||
xaccFreeSplit (s);
|
xaccFreeSplit (s);
|
||||||
i++;
|
|
||||||
s = trans->splits[i];
|
|
||||||
}
|
}
|
||||||
g_free (trans->splits);
|
|
||||||
|
g_list_free (trans->splits);
|
||||||
|
|
||||||
trans->splits = orig->splits;
|
trans->splits = orig->splits;
|
||||||
orig->splits = NULL;
|
orig->splits = NULL;
|
||||||
|
|
||||||
i=mismatch; s = trans->splits[i];
|
for (node = g_list_nth (trans->splits, mismatch) ;
|
||||||
while (s) {
|
node ; node = node->next) {
|
||||||
acc = s->acc;
|
Split *s = node->data;
|
||||||
|
|
||||||
MARK_SPLIT (s);
|
MARK_SPLIT (s);
|
||||||
xaccStoreEntity(s, &s->guid, GNC_ID_SPLIT);
|
xaccStoreEntity(s, &s->guid, GNC_ID_SPLIT);
|
||||||
xaccAccountInsertSplit (acc, s);
|
xaccAccountInsertSplit (s->acc, s);
|
||||||
xaccAccountRecomputeBalance (acc);
|
xaccAccountRecomputeBalance (s->acc);
|
||||||
i++;
|
|
||||||
s = trans->splits[i];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1575,46 +1552,58 @@ xaccTransIsOpen (Transaction *trans)
|
|||||||
void
|
void
|
||||||
xaccTransDestroy (Transaction *trans)
|
xaccTransDestroy (Transaction *trans)
|
||||||
{
|
{
|
||||||
int i;
|
GList *node;
|
||||||
Split *split;
|
|
||||||
Account *acc;
|
|
||||||
|
|
||||||
if (!trans) return;
|
if (!trans) return;
|
||||||
CHECK_OPEN (trans);
|
CHECK_OPEN (trans);
|
||||||
trans->open |= BEING_DESTROYED;
|
trans->open |= BEING_DESTROYED;
|
||||||
xaccTransWriteLog (trans, 'D');
|
xaccTransWriteLog (trans, 'D');
|
||||||
|
|
||||||
i=0;
|
for (node = trans->splits; node; node = node->next) {
|
||||||
split = trans->splits[i];
|
Split *split = node->data;
|
||||||
while (split) {
|
|
||||||
MARK_SPLIT (split);
|
MARK_SPLIT (split);
|
||||||
acc = split ->acc;
|
|
||||||
xaccAccountRemoveSplit (acc, split);
|
xaccAccountRemoveSplit (split->acc, split);
|
||||||
xaccAccountRecomputeBalance (acc);
|
xaccAccountRecomputeBalance (split->acc);
|
||||||
xaccRemoveEntity(&split->guid);
|
xaccRemoveEntity(&split->guid);
|
||||||
xaccFreeSplit (split);
|
xaccFreeSplit (split);
|
||||||
trans->splits[i] = NULL;
|
|
||||||
i++;
|
node->data = NULL;
|
||||||
split = trans->splits[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_list_free (trans->splits);
|
||||||
|
trans->splits = NULL;
|
||||||
|
|
||||||
xaccRemoveEntity(&trans->guid);
|
xaccRemoveEntity(&trans->guid);
|
||||||
|
|
||||||
/* the actual free is done with the commit call, else its rolled back */
|
/* the actual free is done with the commit call, else its rolled back */
|
||||||
/* xaccFreeTransaction (trans); don't do this here ... */
|
/* xaccFreeTransaction (trans); don't do this here ... */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************\
|
||||||
|
* TransRemoveSplit is an engine private function and does not/should
|
||||||
|
* not cause any rebalancing to occur.
|
||||||
|
\********************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
xaccTransRemoveSplit (Transaction *trans, Split *split)
|
||||||
|
{
|
||||||
|
if (trans == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
trans->splits = g_list_remove (trans->splits, split);
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
\********************************************************************/
|
\********************************************************************/
|
||||||
|
|
||||||
void
|
void
|
||||||
xaccSplitDestroy (Split *split)
|
xaccSplitDestroy (Split *split)
|
||||||
{
|
{
|
||||||
Account *acc;
|
|
||||||
Transaction *trans;
|
Transaction *trans;
|
||||||
int numsplits = 0;
|
gboolean ismember = FALSE;
|
||||||
int ismember = 0;
|
GList *node;
|
||||||
Split *s;
|
|
||||||
|
|
||||||
if (!split) return;
|
if (!split) return;
|
||||||
|
|
||||||
@ -1625,14 +1614,16 @@ xaccSplitDestroy (Split *split)
|
|||||||
|
|
||||||
xaccRemoveEntity(&split->guid);
|
xaccRemoveEntity(&split->guid);
|
||||||
|
|
||||||
numsplits = 0;
|
for (node = trans->splits; node; node = node->next)
|
||||||
s = trans->splits[0];
|
{
|
||||||
while (s) {
|
Split *s = node->data;
|
||||||
MARK_SPLIT(s);
|
|
||||||
if (s == split) ismember = 1;
|
MARK_SPLIT(s); /* why??? */
|
||||||
numsplits ++;
|
|
||||||
s = trans->splits[numsplits];
|
if (s == split)
|
||||||
|
ismember = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert (ismember);
|
assert (ismember);
|
||||||
|
|
||||||
/* If the account has three or more splits,
|
/* If the account has three or more splits,
|
||||||
@ -1646,14 +1637,12 @@ xaccSplitDestroy (Split *split)
|
|||||||
*/
|
*/
|
||||||
MARK_SPLIT (split);
|
MARK_SPLIT (split);
|
||||||
xaccTransRemoveSplit (trans, split);
|
xaccTransRemoveSplit (trans, split);
|
||||||
acc = split->acc;
|
xaccAccountRemoveSplit (split->acc, split);
|
||||||
xaccAccountRemoveSplit (acc, split);
|
xaccAccountRecomputeBalance (split->acc);
|
||||||
xaccAccountRecomputeBalance (acc);
|
|
||||||
xaccFreeSplit (split);
|
xaccFreeSplit (split);
|
||||||
|
|
||||||
if (2 < numsplits) {
|
if (g_list_length (trans->splits) > 1)
|
||||||
xaccSplitRebalance (trans->splits[0]);
|
xaccTransRebalance (trans);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
@ -1662,8 +1651,6 @@ xaccSplitDestroy (Split *split)
|
|||||||
void
|
void
|
||||||
xaccTransAppendSplit (Transaction *trans, Split *split)
|
xaccTransAppendSplit (Transaction *trans, Split *split)
|
||||||
{
|
{
|
||||||
int i, num;
|
|
||||||
Split **oldarray;
|
|
||||||
Transaction *oldtrans;
|
Transaction *oldtrans;
|
||||||
|
|
||||||
if (!trans) return;
|
if (!trans) return;
|
||||||
@ -1674,54 +1661,17 @@ xaccTransAppendSplit (Transaction *trans, Split *split)
|
|||||||
/* first, make sure that the split isn't already inserted
|
/* first, make sure that the split isn't already inserted
|
||||||
* elsewhere. If so, then remove it. */
|
* elsewhere. If so, then remove it. */
|
||||||
oldtrans = split->parent;
|
oldtrans = split->parent;
|
||||||
if (oldtrans) {
|
if (oldtrans)
|
||||||
xaccTransRemoveSplit (oldtrans, split);
|
xaccTransRemoveSplit (oldtrans, split);
|
||||||
xaccTransRebalance (oldtrans);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* now, insert the split into the array */
|
/* now, insert the split into the array */
|
||||||
split->parent = trans;
|
split->parent = trans;
|
||||||
num = xaccCountSplits (trans->splits);
|
trans->splits = g_list_append (trans->splits, split);
|
||||||
|
|
||||||
oldarray = trans->splits;
|
|
||||||
trans->splits = (Split **) g_malloc ((num+2)*sizeof(Split *));
|
|
||||||
for (i=0; i<num; i++) {
|
|
||||||
(trans->splits)[i] = oldarray[i];
|
|
||||||
}
|
|
||||||
trans->splits[num] = split;
|
|
||||||
trans->splits[num+1] = NULL;
|
|
||||||
|
|
||||||
g_free (oldarray);
|
|
||||||
|
|
||||||
/* force double entry to always be consistent */
|
/* force double entry to always be consistent */
|
||||||
xaccSplitRebalance (split);
|
xaccSplitRebalance (split);
|
||||||
}
|
if (oldtrans && oldtrans != trans)
|
||||||
|
xaccTransRebalance (oldtrans);
|
||||||
/********************************************************************\
|
|
||||||
* TransRemoveSplit is an engine private function and does not/should
|
|
||||||
* not cause any rebalancing to occur.
|
|
||||||
\********************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
xaccTransRemoveSplit (Transaction *trans, Split *split)
|
|
||||||
{
|
|
||||||
int i=0, n=0;
|
|
||||||
Split *s;
|
|
||||||
|
|
||||||
if (!split) return;
|
|
||||||
if (!trans) return;
|
|
||||||
split->parent = NULL;
|
|
||||||
|
|
||||||
s = trans->splits[0];
|
|
||||||
while (s) {
|
|
||||||
trans->splits[i] = trans->splits[n];
|
|
||||||
if (split == s) { i--; }
|
|
||||||
i++;
|
|
||||||
n++;
|
|
||||||
s = trans->splits[n];
|
|
||||||
}
|
|
||||||
trans->splits[i] = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
@ -1864,25 +1814,6 @@ xaccTransOrder (Transaction *ta, Transaction *tb)
|
|||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
\********************************************************************/
|
\********************************************************************/
|
||||||
|
|
||||||
int
|
|
||||||
xaccCountTransactions (Transaction **tarray)
|
|
||||||
{
|
|
||||||
Transaction *trans;
|
|
||||||
int ntrans = 0;
|
|
||||||
|
|
||||||
if (!tarray) return 0;
|
|
||||||
|
|
||||||
trans = tarray[0];
|
|
||||||
while (trans) {
|
|
||||||
ntrans ++;
|
|
||||||
trans = tarray[ntrans];
|
|
||||||
}
|
|
||||||
return ntrans;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************\
|
|
||||||
\********************************************************************/
|
|
||||||
|
|
||||||
void
|
void
|
||||||
xaccTransSetDateSecs (Transaction *trans, time_t secs)
|
xaccTransSetDateSecs (Transaction *trans, time_t secs)
|
||||||
{
|
{
|
||||||
@ -1991,50 +1922,6 @@ xaccTransSetDescription (Transaction *trans, const char *desc)
|
|||||||
MarkChanged (trans);
|
MarkChanged (trans);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SET_TRANS_FIELD(trans,field,value) \
|
|
||||||
{ \
|
|
||||||
char * tmp; \
|
|
||||||
if (!trans) return; \
|
|
||||||
CHECK_OPEN (trans); \
|
|
||||||
\
|
|
||||||
/* the engine *must* always be internally consistent */ \
|
|
||||||
assert (trans->splits); \
|
|
||||||
assert (trans->splits[0]); \
|
|
||||||
\
|
|
||||||
/* there must be two splits if value of one non-zero */ \
|
|
||||||
if (force_double_entry) { \
|
|
||||||
if (! gnc_numeric_zero_p(trans->splits[0]->damount)) { \
|
|
||||||
assert (trans->splits[1]); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
tmp = g_strdup (value); \
|
|
||||||
g_free (trans->splits[0]->field); \
|
|
||||||
trans->splits[0]->field = tmp; \
|
|
||||||
MARK_SPLIT (trans->splits[0]); \
|
|
||||||
\
|
|
||||||
/* If there are just two splits, then keep them in sync. */ \
|
|
||||||
if (NULL != trans->splits[1]) { \
|
|
||||||
if (NULL == trans->splits[2]) { \
|
|
||||||
g_free (trans->splits[1]->field); \
|
|
||||||
trans->splits[1]->field = g_strdup (tmp); \
|
|
||||||
MARK_SPLIT (trans->splits[1]); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
xaccTransSetMemo (Transaction *trans, const char *mimeo)
|
|
||||||
{
|
|
||||||
SET_TRANS_FIELD (trans, memo, mimeo);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
xaccTransSetAction (Transaction *trans, const char *actn)
|
|
||||||
{
|
|
||||||
SET_TRANS_FIELD (trans, action, actn);
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
\********************************************************************/
|
\********************************************************************/
|
||||||
|
|
||||||
@ -2042,12 +1929,9 @@ Split *
|
|||||||
xaccTransGetSplit (Transaction *trans, int i)
|
xaccTransGetSplit (Transaction *trans, int i)
|
||||||
{
|
{
|
||||||
if (!trans) return NULL;
|
if (!trans) return NULL;
|
||||||
if (0 > i) return NULL;
|
if (i < 0) return NULL;
|
||||||
/* hack alert - should check if i > sizeof array */
|
|
||||||
if (trans->splits) {
|
return g_list_nth_data (trans->splits, i);
|
||||||
return (trans->splits[i]);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
@ -2096,7 +1980,7 @@ int
|
|||||||
xaccTransCountSplits (Transaction *trans)
|
xaccTransCountSplits (Transaction *trans)
|
||||||
{
|
{
|
||||||
if (!trans) return 0;
|
if (!trans) return 0;
|
||||||
return (xaccCountSplits (trans->splits));
|
return g_list_length (trans->splits);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
@ -2256,28 +2140,25 @@ xaccSplitGetSharePrice (Split * split) {
|
|||||||
Account *
|
Account *
|
||||||
xaccGetAccountByName (Transaction *trans, const char * name)
|
xaccGetAccountByName (Transaction *trans, const char * name)
|
||||||
{
|
{
|
||||||
Split *s;
|
|
||||||
Account *acc = NULL;
|
Account *acc = NULL;
|
||||||
int i;
|
GList *node;
|
||||||
|
|
||||||
if (!trans) return NULL;
|
if (!trans) return NULL;
|
||||||
if (!name) return NULL;
|
if (!name) return NULL;
|
||||||
|
|
||||||
/* walk through the splits, looking for one, any one, that has a
|
/* walk through the splits, looking for one, any one, that has a
|
||||||
* parent account */
|
* parent account */
|
||||||
i = 0;
|
for (node = trans->splits; node; node = node->next)
|
||||||
s = trans->splits[0];
|
{
|
||||||
while (s) {
|
Split *s = node->data;
|
||||||
|
|
||||||
acc = s->acc;
|
acc = s->acc;
|
||||||
if (acc) break;
|
if (acc) break;
|
||||||
i++;
|
|
||||||
s = trans->splits[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!acc) return 0x0;
|
if (!acc) return NULL;
|
||||||
|
|
||||||
acc = xaccGetPeerAccountFromName (acc, name);
|
return xaccGetPeerAccountFromName (acc, name);
|
||||||
return acc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
@ -2287,28 +2168,25 @@ Account *
|
|||||||
xaccGetAccountByFullName (Transaction *trans, const char * name,
|
xaccGetAccountByFullName (Transaction *trans, const char * name,
|
||||||
const char separator)
|
const char separator)
|
||||||
{
|
{
|
||||||
Split *s;
|
|
||||||
Account *acc = NULL;
|
Account *acc = NULL;
|
||||||
int i;
|
GList *node;
|
||||||
|
|
||||||
if (!trans) return NULL;
|
if (!trans) return NULL;
|
||||||
if (!name) return NULL;
|
if (!name) return NULL;
|
||||||
|
|
||||||
/* walk through the splits, looking for one, any one, that has a
|
/* walk through the splits, looking for one, any one, that has a
|
||||||
* parent account */
|
* parent account */
|
||||||
i = 0;
|
for (node = trans->splits; node; node = node->next)
|
||||||
s = trans->splits[0];
|
{
|
||||||
while (s) {
|
Split *s = node->data;
|
||||||
|
|
||||||
acc = s->acc;
|
acc = s->acc;
|
||||||
if (acc) break;
|
if (acc) break;
|
||||||
i++;
|
|
||||||
s = trans->splits[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!acc) return NULL;
|
if (!acc) return NULL;
|
||||||
|
|
||||||
acc = xaccGetPeerAccountFromFullName (acc, name, separator);
|
return xaccGetPeerAccountFromFullName (acc, name, separator);
|
||||||
return acc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
@ -2317,17 +2195,22 @@ xaccGetAccountByFullName (Transaction *trans, const char * name,
|
|||||||
Split *
|
Split *
|
||||||
xaccGetOtherSplit (Split *split)
|
xaccGetOtherSplit (Split *split)
|
||||||
{
|
{
|
||||||
|
Split *s1, *s2;
|
||||||
Transaction *trans;
|
Transaction *trans;
|
||||||
|
|
||||||
if (!split) return NULL;
|
if (!split) return NULL;
|
||||||
trans = split->parent;
|
trans = split->parent;
|
||||||
|
|
||||||
/* if more than two splits, return NULL */
|
if (g_list_length (trans->splits) != 2)
|
||||||
if ((trans->splits[1]) && (trans->splits[2])) return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (split == trans->splits[0]) return (trans->splits[1]);
|
s1 = g_list_nth_data (trans->splits, 0);
|
||||||
if (split == trans->splits[1]) return (trans->splits[0]);
|
s2 = g_list_nth_data (trans->splits, 1);
|
||||||
return NULL; /* never reached, in theory */
|
|
||||||
|
if (s1 == split)
|
||||||
|
return s2;
|
||||||
|
|
||||||
|
return s1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
@ -2354,12 +2237,5 @@ IthSplit (Split **list, int i)
|
|||||||
return list[i];
|
return list[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
Transaction *
|
|
||||||
IthTransaction (Transaction **list, int i)
|
|
||||||
{
|
|
||||||
if (!list || 0 > i) return NULL;
|
|
||||||
return list[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************ END OF ************************************\
|
/************************ END OF ************************************\
|
||||||
\************************* FILE *************************************/
|
\************************* FILE *************************************/
|
||||||
|
@ -172,16 +172,6 @@ void xaccTransSetDateEnteredTS (Transaction *trans,
|
|||||||
void xaccTransSetNum (Transaction *trans, const char *num);
|
void xaccTransSetNum (Transaction *trans, const char *num);
|
||||||
void xaccTransSetDescription (Transaction *trans, const char *desc);
|
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
|
/* The xaccTransAppendSplit() method will append the indicated
|
||||||
* split to the collection of splits in this transaction.
|
* split to the collection of splits in this transaction.
|
||||||
* If the split is already a part of another transaction,
|
* If the split is already a part of another transaction,
|
||||||
@ -473,10 +463,6 @@ int xaccSplitDateOrder (Split *sa, Split *sb);
|
|||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
* Miscellaneous utility routines.
|
* 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 */
|
/* count the number of splits in the indicated array */
|
||||||
int xaccCountSplits (Split **sarray);
|
int xaccCountSplits (Split **sarray);
|
||||||
@ -507,12 +493,11 @@ Split * xaccGetOtherSplit (Split *split);
|
|||||||
*/
|
*/
|
||||||
int xaccIsPeerSplit (Split *split_1, Split *split_2);
|
int xaccIsPeerSplit (Split *split_1, Split *split_2);
|
||||||
|
|
||||||
/* The IthSplit() and IthTransaction() routines merely dereference
|
/* The IthSplit() routine merely dereferences
|
||||||
* the lists supplied as arguments; i.e. they return list[i].
|
* the list supplied as argument; i.e. it returns list[i].
|
||||||
* These routines are needed by the perl swig wrappers, which
|
* This routine is needed by the perl swig wrappers, which
|
||||||
* are unable to dereference on their own.
|
* is unable to dereference on their own.
|
||||||
*/
|
*/
|
||||||
Transaction * IthTransaction (Transaction **tarray, int i);
|
|
||||||
Split * IthSplit (Split **sarray, int i);
|
Split * IthSplit (Split **sarray, int i);
|
||||||
|
|
||||||
#endif /* __XACC_TRANSACTION_H__ */
|
#endif /* __XACC_TRANSACTION_H__ */
|
||||||
|
@ -100,9 +100,7 @@ struct _split
|
|||||||
* it's NULL until accessed. */
|
* it's NULL until accessed. */
|
||||||
kvp_frame * kvp_data;
|
kvp_frame * kvp_data;
|
||||||
|
|
||||||
/* The reconciled field ...
|
char reconciled; /* The reconciled field */
|
||||||
*/
|
|
||||||
char reconciled;
|
|
||||||
Timespec date_reconciled; /* date split was reconciled */
|
Timespec date_reconciled; /* date split was reconciled */
|
||||||
|
|
||||||
/* value is the amount of the account's currency involved,
|
/* value is the amount of the account's currency involved,
|
||||||
@ -155,7 +153,7 @@ struct _transaction
|
|||||||
* it's NULL until accessed. */
|
* it's NULL until accessed. */
|
||||||
kvp_frame * kvp_data;
|
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.
|
/* marker is used to track the progress of transaction traversals.
|
||||||
* 0 is never a legitimate marker value, so we can tell is we hit
|
* 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
|
* not check to see if any of the member splits are referenced
|
||||||
* by an account.
|
* by an account.
|
||||||
*/
|
*/
|
||||||
void xaccFreeTransaction (Transaction *);
|
void xaccFreeTransaction (Transaction *trans);
|
||||||
|
|
||||||
/* The xaccFreeSplit() method simply frees all memory associated
|
/* The xaccFreeSplit() method simply frees all memory associated
|
||||||
* with the split. It does not verify that the split isn't
|
* 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
|
* account, then calling this method will leave the system in an
|
||||||
* inconsistent state.
|
* inconsistent state.
|
||||||
*/
|
*/
|
||||||
void xaccFreeSplit (Split *); /* frees memory */
|
void xaccFreeSplit (Split *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 *);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -216,7 +208,7 @@ void xaccTransRemoveSplit (Transaction*, Split *);
|
|||||||
* splits in a transaction to total up to exactly zero.
|
* splits in a transaction to total up to exactly zero.
|
||||||
*
|
*
|
||||||
* It is worthwhile to understand the algorithm that this routine
|
* 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
|
* If the indicated split is a destination split (i.e. is not
|
||||||
* the first split), then the total value of the destination
|
* the first split), then the total value of the destination
|
||||||
* splits is computed, and the value of the source split (ie.
|
* splits is computed, and the value of the source split (ie.
|
||||||
@ -236,12 +228,12 @@ void xaccTransRemoveSplit (Transaction*, Split *);
|
|||||||
* destination split properly.
|
* destination split properly.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void xaccSplitRebalance (Split *);
|
void xaccSplitRebalance (Split *split);
|
||||||
|
|
||||||
|
|
||||||
/* FIXME: this is probably wrong, but it'll have to wait until Bill
|
/* 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. */
|
returns. It's *ONLY* for file IO. Don't use these elsewhere. */
|
||||||
void xaccSplitSetValueDirectly(Split *s, gnc_numeric n);
|
void xaccSplitSetValueDirectly(Split *split, gnc_numeric value);
|
||||||
void xaccSplitSetQuantityDirectly(Split *s, gnc_numeric n);
|
void xaccSplitSetQuantityDirectly(Split *split, gnc_numeric quantity);
|
||||||
|
|
||||||
#endif /* __XACC_TRANSACTION_P_H__ */
|
#endif /* __XACC_TRANSACTION_P_H__ */
|
||||||
|
@ -662,20 +662,6 @@ readAccount( int fd, AccountGroup *grp, int token )
|
|||||||
"\texpected %d got %d transactions \n",numTrans,i);
|
"\texpected %d got %d transactions \n",numTrans,i);
|
||||||
break;
|
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
|
/* 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);
|
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 *
|
* readTransaction *
|
||||||
* reads in the data for a transaction from the datafile *
|
* reads in the data for a transaction from the datafile *
|
||||||
@ -809,6 +829,12 @@ readTransaction( int fd, Account *acc, int token )
|
|||||||
trans = xaccMallocTransaction();
|
trans = xaccMallocTransaction();
|
||||||
xaccTransBeginEdit (trans, 1);
|
xaccTransBeginEdit (trans, 1);
|
||||||
|
|
||||||
|
/* add in one split -- xaccMallocTransaction no longer auto-creates them. */
|
||||||
|
{
|
||||||
|
Split *s = xaccMallocSplit ();
|
||||||
|
xaccTransAppendSplit (trans, s);
|
||||||
|
}
|
||||||
|
|
||||||
tmp = readString( fd, token );
|
tmp = readString( fd, token );
|
||||||
if (NULL == tmp)
|
if (NULL == tmp)
|
||||||
{
|
{
|
||||||
@ -1084,14 +1110,16 @@ readTransaction( int fd, Account *acc, int token )
|
|||||||
|
|
||||||
if (5 == token)
|
if (5 == token)
|
||||||
{
|
{
|
||||||
|
Split *s = trans->splits->data;
|
||||||
|
|
||||||
/* Version 5 files included a split that immediately
|
/* Version 5 files included a split that immediately
|
||||||
* followed the transaction, before the destination splits.
|
* followed the transaction, before the destination splits.
|
||||||
* Later versions don't have this. */
|
* Later versions don't have this. */
|
||||||
offset = 1;
|
offset = 1;
|
||||||
split = readSplit (fd, token);
|
split = readSplit (fd, token);
|
||||||
xaccRemoveEntity(&trans->splits[0]->guid);
|
xaccRemoveEntity(&s->guid);
|
||||||
xaccFreeSplit (trans->splits[0]);
|
xaccFreeSplit (s);
|
||||||
trans->splits[0] = split;
|
trans->splits->data = split;
|
||||||
split->parent = trans;
|
split->parent = trans;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1108,13 +1136,14 @@ readTransaction( int fd, Account *acc, int token )
|
|||||||
for (i=0; i<numSplits; i++) {
|
for (i=0; i<numSplits; i++) {
|
||||||
split = readSplit (fd, token);
|
split = readSplit (fd, token);
|
||||||
if (0 == i+offset) {
|
if (0 == i+offset) {
|
||||||
|
Split *s = trans->splits->data;
|
||||||
/* the first split has been malloced. just replace it */
|
/* the first split has been malloced. just replace it */
|
||||||
xaccRemoveEntity (&trans->splits[i+offset]->guid);
|
xaccRemoveEntity (&s->guid);
|
||||||
xaccFreeSplit (trans->splits[i+offset]);
|
xaccFreeSplit (s);
|
||||||
trans->splits[i+offset] = split;
|
trans->splits->data = split;
|
||||||
split->parent = trans;
|
split->parent = trans;
|
||||||
} else {
|
} else {
|
||||||
xaccTransAppendSplit( trans, split);
|
xaccTransAppendSplit(trans, split);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3349,17 +3349,6 @@ txn_restore_start_handler(GSList* sibling_data,
|
|||||||
|
|
||||||
xaccTransBeginEdit(trans, 1);
|
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;
|
*data_for_children = trans;
|
||||||
|
|
||||||
return(TRUE);
|
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));
|
string = gtk_entry_get_text(GTK_ENTRY(xferData->description_entry));
|
||||||
xaccTransSetDescription(trans, string);
|
xaccTransSetDescription(trans, string);
|
||||||
|
|
||||||
/* first split is already there */
|
/* create first split */
|
||||||
curr_split = xaccTransGetSplit(trans, 0);
|
curr_split = xaccMallocSplit();
|
||||||
/* second split must be created */
|
xaccTransAppendSplit(trans, curr_split);
|
||||||
|
|
||||||
|
/* create second split */
|
||||||
from_split = xaccMallocSplit();
|
from_split = xaccMallocSplit();
|
||||||
xaccTransAppendSplit(trans, from_split);
|
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, amount, from_currency);
|
||||||
DxaccSplitSetBaseValue(curr_split, to_amount, to_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));
|
string = gtk_entry_get_text(GTK_ENTRY(xferData->memo_entry));
|
||||||
xaccTransSetMemo(trans, string);
|
xaccSplitSetMemo(curr_split, string);
|
||||||
|
xaccSplitSetMemo(from_split, string);
|
||||||
|
|
||||||
/* finish transaction */
|
/* finish transaction */
|
||||||
xaccAccountCommitEdit(from);
|
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));
|
string = gtk_entry_get_text(GTK_ENTRY(xferData->description_entry));
|
||||||
xaccTransSetDescription(trans, string);
|
xaccTransSetDescription(trans, string);
|
||||||
|
|
||||||
/* first split is already there */
|
/* create first split */
|
||||||
curr_split = xaccTransGetSplit(trans, 0);
|
curr_split = xaccMallocSplit();
|
||||||
/* second split must be created */
|
xaccTransAppendSplit(trans, curr_split);
|
||||||
|
|
||||||
|
/* create second split */
|
||||||
to_split = xaccMallocSplit();
|
to_split = xaccMallocSplit();
|
||||||
xaccTransAppendSplit(trans, to_split);
|
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, -amount, from_currency);
|
||||||
DxaccSplitSetBaseValue(curr_split, -to_amount, to_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));
|
string = gtk_entry_get_text(GTK_ENTRY(xferData->memo_entry));
|
||||||
xaccTransSetMemo(trans, string);
|
xaccSplitSetMemo(curr_split, string);
|
||||||
|
xaccSplitSetMemo(to_split, string);
|
||||||
|
|
||||||
/* finish transaction */
|
/* finish transaction */
|
||||||
xaccAccountCommitEdit(curr);
|
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));
|
string = gtk_entry_get_text(GTK_ENTRY(xferData->description_entry));
|
||||||
xaccTransSetDescription(trans, string);
|
xaccTransSetDescription(trans, string);
|
||||||
|
|
||||||
/* first split is already there */
|
/* create first split */
|
||||||
to_split = xaccTransGetSplit(trans, 0);
|
to_split = xaccMallocSplit();
|
||||||
|
xaccTransAppendSplit(trans, to_split);
|
||||||
DxaccSplitSetShareAmount(to_split, amount);
|
DxaccSplitSetShareAmount(to_split, amount);
|
||||||
|
|
||||||
/* second split must be created */
|
/* create second split */
|
||||||
from_split = xaccMallocSplit();
|
from_split = xaccMallocSplit();
|
||||||
DxaccSplitSetShareAmount(from_split, -amount);
|
DxaccSplitSetShareAmount(from_split, -amount);
|
||||||
xaccTransAppendSplit(trans, from_split);
|
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));
|
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 */
|
/* Now do the 'to' account */
|
||||||
xaccAccountBeginEdit(to);
|
xaccAccountBeginEdit(to);
|
||||||
|
@ -234,15 +234,6 @@
|
|||||||
(let ((gnc-xtn (gnc:transaction-create)))
|
(let ((gnc-xtn (gnc:transaction-create)))
|
||||||
(gnc:transaction-begin-edit gnc-xtn 1)
|
(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
|
;; build the transaction
|
||||||
(qif-import:qif-xtn-to-gnc-xtn
|
(qif-import:qif-xtn-to-gnc-xtn
|
||||||
xtn qif-file gnc-xtn gnc-acct-hash
|
xtn qif-file gnc-xtn gnc-acct-hash
|
||||||
|
Loading…
Reference in New Issue
Block a user