Robert Graham Merkel's reimplementation of the transaction report.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3686 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Dave Peticolas
2001-02-25 03:21:39 +00:00
parent c8a7adb87c
commit 84cbba8ec2
12 changed files with 1034 additions and 618 deletions

View File

@@ -59,7 +59,9 @@ struct _querystruct {
sort_type_t primary_sort;
sort_type_t secondary_sort;
sort_type_t tertiary_sort;
gboolean sort_increasing;
gboolean primary_increasing;
gboolean secondary_increasing;
gboolean tertiary_increasing;
int max_splits;
/* cache the results so we don't have to run the whole search
@@ -211,7 +213,9 @@ xaccInitQuery(Query * q, QueryTerm * initial_term) {
q->secondary_sort = BY_NONE;
q->tertiary_sort = BY_NONE;
q->sort_increasing = TRUE;
q->primary_increasing = TRUE;
q->secondary_increasing = TRUE;
q->tertiary_increasing = TRUE;
}
@@ -447,7 +451,9 @@ xaccQueryCopy(Query *q) {
copy->secondary_sort = q->secondary_sort;
copy->tertiary_sort = q->tertiary_sort;
copy->sort_increasing = q->sort_increasing;
copy->primary_increasing = q->primary_increasing;
copy->secondary_increasing = q->secondary_increasing;
copy->tertiary_increasing = q->tertiary_increasing;
copy->max_splits = q->max_splits;
copy->changed = q->changed;
@@ -703,7 +709,7 @@ split_cmp_func(sort_type_t how, gconstpointer ga, gconstpointer gb)
Transaction * tb;
unsigned long n1;
unsigned long n2;
char *da, *db;
const char *da, *db;
gnc_numeric fa, fb;
if (sa && !sb) return -1;
@@ -804,6 +810,20 @@ split_cmp_func(sort_type_t how, gconstpointer ga, gconstpointer gb)
}
break;
case BY_ACCOUNT_NAME:
return xaccSplitCompareAccountCodes(sa,sb);
break;
case BY_ACCOUNT_CODE:
return xaccSplitCompareAccountNames(sa, sb);
break;
case BY_CORR_ACCOUNT_NAME:
return xaccSplitCompareOtherAccountNames(sa, sb);
case BY_CORR_ACCOUNT_CODE:
return xaccSplitCompareOtherAccountCodes(sa, sb);
case BY_NONE:
return 0;
break;
@@ -815,15 +835,10 @@ split_cmp_func(sort_type_t how, gconstpointer ga, gconstpointer gb)
static int
split_sort_func(gconstpointer a, gconstpointer b) {
int retval;
int multiplier;
assert(split_sort_query);
if (split_sort_query->sort_increasing)
multiplier = 1;
else
multiplier = -1;
retval = split_cmp_func(split_sort_query->primary_sort, a, b);
if((retval == 0) &&
(split_sort_query->secondary_sort != BY_NONE)) {
@@ -831,14 +846,14 @@ split_sort_func(gconstpointer a, gconstpointer b) {
if((retval == 0) &&
(split_sort_query->tertiary_sort != BY_NONE)) {
retval = split_cmp_func(split_sort_query->tertiary_sort, a, b);
return retval * multiplier;
return split_sort_query->tertiary_increasing ? retval : - retval;
}
else {
return retval * multiplier;
return split_sort_query->secondary_increasing ? retval : - retval;
}
}
else {
return retval * multiplier;
return split_sort_query->primary_increasing ? retval : - retval;
}
}
@@ -2221,9 +2236,14 @@ xaccQuerySetSortOrder(Query * q, sort_type_t primary,
* xaccQuerySetSortIncreasing
*******************************************************************/
void
xaccQuerySetSortIncreasing(Query * q, gboolean increasing)
xaccQuerySetSortIncreasing(Query * q, gboolean prim_increasing,
gboolean sec_increasing,
gboolean tert_increasing)
{
q->sort_increasing = increasing;
q->primary_increasing = prim_increasing;
q->secondary_increasing = sec_increasing;
q->tertiary_increasing = tert_increasing;
return;
}
/*******************************************************************

View File

@@ -50,6 +50,10 @@ typedef enum {
BY_MEMO,
BY_DESC,
BY_RECONCILE,
BY_ACCOUNT_NAME,
BY_ACCOUNT_CODE,
BY_CORR_ACCOUNT_NAME,
BY_CORR_ACCOUNT_CODE,
BY_NONE
} sort_type_t;
@@ -287,7 +291,9 @@ void xaccQueryAddPredicate (Query * q, PredicateData *pred, QueryOp op);
void xaccQuerySetSortOrder(Query * q, sort_type_t primary,
sort_type_t secondary, sort_type_t tertiary);
void xaccQuerySetSortIncreasing(Query * q, gboolean increasing);
void xaccQuerySetSortIncreasing(Query * q, gboolean prim_increasing,
gboolean sec_increasing,
gboolean tert_increasing);
void xaccQuerySetMaxSplits(Query * q, int n);
int xaccQueryGetMaxSplits(Query * q);

View File

@@ -1822,7 +1822,137 @@ xaccTransOrder (Transaction *ta, Transaction *tb)
return 0;
}
static gboolean
get_corr_account_split(Split *sa, Split **retval)
{
Split *current_split;
GList *split_list;
Transaction * ta;
gnc_numeric sa_balance, current_balance;
gboolean sa_balance_positive, current_balance_positive, seen_different = FALSE;
*retval = NULL;
g_return_val_if_fail(sa, TRUE);
ta = xaccSplitGetParent(sa);
sa_balance = xaccSplitGetBalance(sa);
sa_balance_positive = gnc_numeric_positive_p(sa_balance);
for(split_list = xaccTransGetSplitList(ta);split_list; split_list = split_list->next)
{
current_split = split_list->data;
if(current_split != sa)
{
current_balance = xaccSplitGetBalance(current_split);
current_balance_positive = gnc_numeric_positive_p(current_balance);
if((sa_balance_positive && !current_balance_positive) ||
(!sa_balance_positive && current_balance_positive))
{
if(seen_different)
{
*retval = NULL;
return TRUE;
}
else
{
seen_different = TRUE;
*retval = current_split;
}
}
}
}
return FALSE;
}
const char *
xaccSplitGetCorrAccountName(Split *sa)
{
static const char *split_const = "Split";
Split *other_split;
Account *other_split_acc;
if(get_corr_account_split(sa, &other_split))
{
return split_const;
}
else
{
other_split_acc = xaccSplitGetAccount(other_split);
return xaccAccountGetName(other_split_acc);
}
}
const char *
xaccSplitGetCorrAccountCode(Split *sa)
{
static const char *split_const = "Split";
Split *other_split;
Account *other_split_acc;
if(get_corr_account_split(sa, &other_split))
{
return split_const;
}
else
{
other_split_acc = xaccSplitGetAccount(other_split);
return xaccAccountGetName(other_split_acc);
}
}
int
xaccSplitCompareAccountNames(Split *sa, Split *sb)
{
Account *aa, *ab;
if (!sa && !sb) return 0;
if (!sa) return -1;
if (!sb) return 1;
aa = xaccSplitGetAccount(sa);
ab = xaccSplitGetAccount(sb);
return safe_strcmp(xaccAccountGetName(aa), xaccAccountGetName(ab));
}
int
xaccSplitCompareAccountCodes(Split *sa, Split *sb)
{
Account *aa, *ab;
if (!sa && !sb) return 0;
if (!sa) return -1;
if (!sb) return 1;
aa = xaccSplitGetAccount(sa);
ab = xaccSplitGetAccount(sb);
return safe_strcmp(xaccAccountGetName(aa), xaccAccountGetName(ab));
}
int
xaccSplitCompareOtherAccountNames(Split *sa, Split *sb)
{
const char *ca, *cb;
if (!sa && !sb) return 0;
if (!sa) return -1;
if (!sb) return 1;
ca = xaccSplitGetCorrAccountName(sa);
cb = xaccSplitGetCorrAccountName(sb);
return safe_strcmp(ca, cb);
}
int
xaccSplitCompareOtherAccountCodes(Split *sa, Split *sb)
{
const char *ca, *cb;
if (!sa && !sb) return 0;
if (!sa) return -1;
if (!sb) return 1;
ca = xaccSplitGetCorrAccountCode(sa);
cb = xaccSplitGetCorrAccountCode(sb);
return safe_strcmp(ca, cb);
}
/********************************************************************\
\********************************************************************/

View File

@@ -506,6 +506,36 @@ int xaccSplitDateOrder (Split *sa, Split *sb);
* Miscellaneous utility routines.
\********************************************************************/
/*
* These functions compare two splits by different criteria. The *Other*
* functions attempt to find the split on the other side of a transaction
* and compare on it. They return similar to strcmp.
*
* These functions were added because converting strings to guile
* for comparisons in the transaction report is terribly inefficient.
* More may be added here in future if it turns out that other types
* of comparisons also induces guile slowdowns.
*/
int xaccSplitCompareAccountNames(Split *sa, Split *sb);
int xaccSplitCompareAccountCodes(Split *sa, Split *sb);
int xaccSplitCompareOtherAccountNames(Split *sa, Split *sb);
int xaccSplitCompareOtherAccountCodes(Split *sa, Split *sb);
/*
* These functions take a split, get the corresponding split on the
* "other side" of the transaction, and extract either the name or code
* of that split, reverting to returning a constant "Split" if the
* transaction has more than one split on the "other side". These
* were added for the transaction report, and is in C because the code
* was already written in C for the above functions and duplication
* is silly.
*/
const char * xaccSplitGetCorrAccountName(Split *sa);
const char * xaccSplitGetCorrAccountCode(Split *sa);
/*
* The xaccGetAccountByName() is a convenience routine that
* is essentially identical to xaccGetPeerAccountFromName(),