mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
|
||||
@@ -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(),
|
||||
|
||||
Reference in New Issue
Block a user