more work on scrubber functions

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@1446 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Linas Vepstas 1998-12-14 07:45:39 +00:00
parent 990940bf72
commit dd456c9b64
3 changed files with 136 additions and 24 deletions

View File

@ -1,11 +1,15 @@
/*
* FILE:
* Scrub.c
*
* FUNCTION:
* Provides a set of functions and utilities for scrubbing clean
* single-entry accounts so that they can be promoted into
* self-consistent, clean double-entry accounts.
*
* HISTORY:
* Created by Linas Vepstas December 1998
* Copyright (c) 1998 Linas Vepstas
*/
#ifndef __XACC_SCRUB_H__
@ -20,18 +24,49 @@
double xaccTransGetUnbalance (Transaction * trans);
/* The xaccScrubOrphans() method searches for transacations that contain
/* The ScrubOrphans() methods search for transacations that contain
* splits that do not have a parent account. These "orphaned splits"
* are placed into an "orphan account" which the user will have to
* go into and clean up. Kind of like the unix "Lost+Found" directory
* for orphaned inodes.
*
* The xaccAccountScrubOrphans() method performs this scrub only for the
* indicated account, and not for any of its children.
*
* The xaccAccountTreeScrubOrphans() method performs this scrub for the
* indicated account and its children.
*
* The xaccGroupScrubOrphans() method performs this scrub for the
* child accounts of this group.
*/
void xaccAccountScrubOrphans (Account *acc);
void xaccAccountTreeScrubOrphans (Account *acc);
void xaccGroupScrubOrphans (AccountGroup *grp);
/* The xaccScrubImbalance() method searches for transactions that do
* not balance to zero. If any such transactions are found, a split
* is created to offset this amount and is added to an "imbalance"
* account.
*/
void xaccAccountScrubImbalance (Account *acc);
void xaccAccountTreeScrubImbalance (Account *acc);
void xaccGroupScrubImbalance (AccountGroup *grp);
#endif /* __XACC_SCRUB_H__ */
#include <nana.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "AccountP.h"
#include "TransactionP.h"
#include "Account.h"
#include "Group.h"
#include "GroupP.h"
#include "Transaction.h"
#include "util.h"
static short module = MOD_SCRUB;
static Account * GetOrMakeAccount (Account *, Transaction *, const char *);
double
xaccGetUnbalance (Transaction * trans) { return 0.0; }
@ -39,32 +74,101 @@ xaccGetUnbalance (Transaction * trans) { return 0.0; }
void
Scrub (Account *acc)
{
ScrubOrphans (acc);
xaccAccountScrubOrphans (acc);
}
/* ================================================================ */
void
ScrubOrphans (Account *acc)
xaccGroupScrubOrphans (AccountGroup *grp)
{
int i=0;
Split *split;
Transaction * trans;
if (!grp) return;
split = acc->splits[0];
while (split) {
Split * s;
int j = 0;
trans = split->parent;
s = trans->splits[0];
while (s) {
if (!s->acc) {
printf ("got one\n");
}
j++; s = trans->splits[j];
}
i++; split = acc->splits[i];
assert ((0 == grp->numAcc) || (grp->account));
for (i=0; i<grp->numAcc; i++) {
xaccAccountTreeScrubOrphans (grp->account[i]);
}
}
void
xaccAccountTreeScrubOrphans (Account *acc)
{
xaccGroupScrubOrphans (xaccAccountGetChildren(acc));
xaccAccountScrubOrphans (acc);
}
/* hack alert -- this string should probably be i18n'ed */
#define ORPHAN_STR "Orphan-"
void
xaccAccountScrubOrphans (Account *acc)
{
int i=0;
Split *split, **slist;
Transaction *trans;
Account * parent;
PINFO ("xaccAccountScrubOrphans(): "
"Looking for orphans in account %s \n", xaccAccountGetName(acc));
slist = xaccAccountGetSplitList (acc);
split = slist[0];
while (split) {
Split * s;
int j = 0;
trans = xaccSplitGetParent (split);
s = xaccTransGetSplit (trans, 0);
while (s) {
parent = xaccSplitGetAccount (s);
if (!parent) {
Account *orph;
DEBUG ("xaccAccountScrubOrphans(): Found an orphan \n");
/* OK, we found an orphan. Put it in an orphan account. */
orph = GetOrMakeAccount (acc, trans, ORPHAN_STR);
xaccAccountInsertSplit (orph, s);
}
j++;
s = xaccTransGetSplit (trans, j);
}
i++; split = slist[i];
}
}
/* ================================================================ */
static Account *
GetOrMakeAccount (Account *peer, Transaction *trans, const char *name_root)
{
char * accname;
char * currency;
Account * acc;
AccountGroup *root;
/* build the account name */
currency = xaccTransFindCommonCurrency (trans);
accname = alloca (strlen (name_root) + strlen (currency) + 1);
strcpy (accname, name_root);
strcat (accname, currency);
/* see if we've got one of these going already ... */
acc = xaccGetPeerAccountFromName (peer, accname);
if (acc) return acc;
/* guess not. We'll have to build one */
acc = xaccMallocAccount ();
xaccAccountBeginEdit (acc, 1);
xaccAccountSetName (acc, accname);
xaccAccountSetCurrency (acc, currency);
xaccAccountSetType (acc, BANK);
/* hang the account off the root */
root = xaccGetAccountRoot (peer);
xaccGroupInsertAccount (root, acc);
xaccAccountCommitEdit (acc);
return acc;
}
/* ==================== END OF FILE ==================== */

View File

@ -45,6 +45,7 @@ int loglevel[MODULE_MAX] =
2, /* REGISTER */
2, /* LEDGER */
2, /* GUI */
4, /* SCRUB */
};
/********************************************************************\

View File

@ -33,15 +33,22 @@
/** DEBUGGING MACROS ************************************************/
/* The debuging macros enable the setting of trace messages */
#include <nana.h>
#include <stdio.h>
#include <nana.h>
/* override standard system assert with nana I assertion */
#ifdef assert
#undef assert
#endif
#define assert I
#define MOD_ENGINE 1
#define MOD_IO 2
#define MOD_REGISTER 3
#define MOD_LEDGER 4
#define MOD_GUI 5
#define MODULE_MAX 6
#define MOD_SCRUB 6
#define MODULE_MAX 7
extern int loglevel[MODULE_MAX];