mirror of
https://github.com/Gnucash/gnucash.git
synced 2024-12-02 05:29:20 -06:00
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:
parent
990940bf72
commit
dd456c9b64
@ -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 ==================== */
|
||||
|
@ -45,6 +45,7 @@ int loglevel[MODULE_MAX] =
|
||||
2, /* REGISTER */
|
||||
2, /* LEDGER */
|
||||
2, /* GUI */
|
||||
4, /* SCRUB */
|
||||
};
|
||||
|
||||
/********************************************************************\
|
||||
|
@ -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];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user