mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
cleanup order in which scrubbing is performed,
add additional debug printouts of actions performed. Will catch fixes of type reported by Dave Reed <drlinux@columbus.rr.com> git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@8186 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
b4edce8281
commit
0865da3b4a
@ -84,6 +84,31 @@ xaccAccountTreeScrubOrphans (Account *acc)
|
||||
xaccAccountScrubOrphans (acc);
|
||||
}
|
||||
|
||||
static void
|
||||
TransScrubOrphansFast (Transaction *trans, AccountGroup *root)
|
||||
{
|
||||
GList *node;
|
||||
|
||||
if (!trans) return;
|
||||
|
||||
for (node = trans->splits; node; node = node->next)
|
||||
{
|
||||
Split *split = node->data;
|
||||
Account *orph;
|
||||
|
||||
if (split->acc) continue;
|
||||
|
||||
DEBUG ("Found an orphan \n");
|
||||
|
||||
orph = xaccScrubUtilityGetOrMakeAccount (root, trans->common_currency, _("Orphan"));
|
||||
if (!orph) continue;
|
||||
|
||||
xaccAccountBeginEdit (orph);
|
||||
xaccAccountInsertSplit (orph, split);
|
||||
xaccAccountCommitEdit (orph);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
xaccAccountScrubOrphans (Account *acc)
|
||||
{
|
||||
@ -100,37 +125,25 @@ xaccAccountScrubOrphans (Account *acc)
|
||||
{
|
||||
Split *split = node->data;
|
||||
|
||||
xaccTransScrubOrphans (xaccSplitGetParent (split),
|
||||
TransScrubOrphansFast (xaccSplitGetParent (split),
|
||||
xaccAccountGetRoot (acc));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
xaccTransScrubOrphans (Transaction *trans, AccountGroup *root)
|
||||
xaccTransScrubOrphans (Transaction *trans)
|
||||
{
|
||||
GList *node;
|
||||
|
||||
if (!trans) return;
|
||||
|
||||
for (node = xaccTransGetSplitList (trans); node; node = node->next)
|
||||
SplitList *node;
|
||||
for (node = trans->splits; node; node = node->next)
|
||||
{
|
||||
Split *split = node->data;
|
||||
Account *account;
|
||||
Account *orph;
|
||||
|
||||
account = xaccSplitGetAccount (split);
|
||||
if (account)
|
||||
continue;
|
||||
|
||||
DEBUG ("Found an orphan \n");
|
||||
|
||||
orph = xaccScrubUtilityGetOrMakeAccount (root, trans->common_currency, _("Orphan"));
|
||||
if (!orph)
|
||||
continue;
|
||||
|
||||
xaccAccountBeginEdit (orph);
|
||||
xaccAccountInsertSplit (orph, split);
|
||||
xaccAccountCommitEdit (orph);
|
||||
if (split->acc)
|
||||
{
|
||||
TransScrubOrphansFast (trans, xaccAccountGetRoot(split->acc));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -188,43 +201,35 @@ xaccSplitScrub (Split *split)
|
||||
Account *account;
|
||||
Transaction *trans;
|
||||
gnc_numeric value;
|
||||
gboolean trans_was_open;
|
||||
gnc_commodity *commodity;
|
||||
gnc_commodity *currency;
|
||||
int scu;
|
||||
|
||||
if (!split)
|
||||
return;
|
||||
if (!split) return;
|
||||
|
||||
trans = xaccSplitGetParent (split);
|
||||
if (!trans)
|
||||
return;
|
||||
if (!trans) return;
|
||||
|
||||
account = xaccSplitGetAccount (split);
|
||||
|
||||
/* If theres no account, this split is an orphan.
|
||||
* We need to fix that first, before proceeding.
|
||||
*/
|
||||
if (!account)
|
||||
{
|
||||
/* xxxxxxxxxx FIXME: if theres no account, we should
|
||||
scrub for orphans, and fix that !!
|
||||
only then should we proceed!
|
||||
xaccTransScrubOrphans (trans,
|
||||
--linas march 2003
|
||||
*/
|
||||
value = xaccSplitGetValue (split);
|
||||
|
||||
if (gnc_numeric_same (xaccSplitGetAmount (split),
|
||||
xaccSplitGetValue (split),
|
||||
value.denom, GNC_RND_ROUND))
|
||||
return;
|
||||
|
||||
xaccSplitSetAmount (split, value);
|
||||
|
||||
return;
|
||||
xaccTransScrubOrphans (trans);
|
||||
account = xaccSplitGetAccount (split);
|
||||
}
|
||||
|
||||
commodity = xaccAccountGetCommodity (account);
|
||||
currency = xaccTransGetCurrency (trans);
|
||||
|
||||
if (!commodity || !gnc_commodity_equiv (commodity, currency))
|
||||
/* If the account doesn't have a commodity,
|
||||
* we should attempt to fix that first.
|
||||
*/
|
||||
if (!account->commodity)
|
||||
{
|
||||
xaccAccountScrubCommodity (account);
|
||||
}
|
||||
if (!account->commodity || !gnc_commodity_equiv (account->commodity, currency))
|
||||
return;
|
||||
|
||||
scu = MIN (xaccAccountGetCommoditySCU (account),
|
||||
@ -234,19 +239,20 @@ only then should we proceed!
|
||||
|
||||
if (gnc_numeric_same (xaccSplitGetAmount (split),
|
||||
value, scu, GNC_RND_ROUND))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PINFO ("split with mismatched values");
|
||||
|
||||
trans_was_open = xaccTransIsOpen (trans);
|
||||
|
||||
if (!trans_was_open)
|
||||
xaccTransBeginEdit (trans);
|
||||
PWARN ("Adjusted split with mismatched values, desc=\"%s\" memo=\"%s\""
|
||||
" old amount %s %s, new amount %s",
|
||||
trans->description, split->memo,
|
||||
gnc_numeric_to_string (split->amount),
|
||||
gnc_commodity_get_mnemonic (currency),
|
||||
gnc_numeric_to_string (split->value));
|
||||
|
||||
xaccTransBeginEdit (trans);
|
||||
xaccSplitSetAmount (split, value);
|
||||
|
||||
if (!trans_was_open)
|
||||
xaccTransCommitEdit (trans);
|
||||
xaccTransCommitEdit (trans);
|
||||
}
|
||||
|
||||
/* ================================================================ */
|
||||
@ -374,8 +380,8 @@ xaccTransScrubImbalance (Transaction *trans, AccountGroup *root,
|
||||
* already existing denominator (bug #104343), because either one
|
||||
* of the denominators might already be reduced. */
|
||||
new_value = gnc_numeric_sub (new_value, imbalance,
|
||||
gnc_commodity_get_fraction(currency),
|
||||
GNC_RND_ROUND);
|
||||
gnc_commodity_get_fraction(currency),
|
||||
GNC_RND_ROUND);
|
||||
|
||||
xaccSplitSetValue (balance_split, new_value);
|
||||
|
||||
@ -404,17 +410,16 @@ xaccTransScrubImbalance (Transaction *trans, AccountGroup *root,
|
||||
void
|
||||
xaccTransScrubCurrency (Transaction *trans)
|
||||
{
|
||||
SplitList *node;
|
||||
gnc_commodity *currency;
|
||||
|
||||
if (!trans) return;
|
||||
|
||||
/* If there are any orphaned splits in a transaction, then the
|
||||
* TransScrubCurrency will fail for that transaction.
|
||||
xxxxxxxxxxxxxxxxa FIXME: finish fixing me!!
|
||||
--linas march 2003
|
||||
xaccTransScrubOrphans (xaccSplitGetParent (split),
|
||||
xaccAccountGetRoot (acc));
|
||||
*/
|
||||
/* If there are any orphaned splits in a transaction, then the
|
||||
* this routine will fail. Therefore, we want to make sure that
|
||||
* tehre are no orphans (splits without parent account).
|
||||
*/
|
||||
xaccTransScrubOrphans (trans);
|
||||
|
||||
currency = xaccTransGetCurrency (trans);
|
||||
if (currency) return;
|
||||
@ -451,59 +456,52 @@ xxxxxxxxxxxxxxxxa FIXME: finish fixing me!!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (node=trans->splits; node; node=node->next)
|
||||
{
|
||||
SplitList *node;
|
||||
for (node=trans->splits; node; node=node->next)
|
||||
Split *sp = node->data;
|
||||
|
||||
if (!gnc_numeric_equal(xaccSplitGetAmount (sp),
|
||||
xaccSplitGetValue (sp)))
|
||||
{
|
||||
Split *sp = node->data;
|
||||
/*
|
||||
xxxxxxxxxxxxxxx FIXME: this loop should perform the more
|
||||
through SplitScrub at this point, although the actual flow
|
||||
of logic for fixing things needs to be tweaked, because
|
||||
some of the fixes are being done in the wrong order.
|
||||
--linas march 2003
|
||||
*/
|
||||
if (!gnc_numeric_equal(xaccSplitGetAmount (sp),
|
||||
xaccSplitGetValue (sp)))
|
||||
gnc_commodity *acc_currency = xaccAccountGetCommodity (sp->acc);
|
||||
if (acc_currency == currency)
|
||||
{
|
||||
Account *acc = xaccSplitGetAccount (sp);
|
||||
gnc_commodity *acc_currency = xaccAccountGetCommodity (acc);
|
||||
if (acc_currency == currency) {
|
||||
/* This Split needs fixing: The transaction-currency equals
|
||||
* the account-currency/commodity, but the amount/values are
|
||||
* inequal i.e. they still correspond to the security
|
||||
* (amount) and the currency (value). In the new model, the
|
||||
* value is the amount in the account-commodity -- so it
|
||||
* needs to be set to equal the amount (since the
|
||||
* account-currency doesn't exist anymore).
|
||||
*
|
||||
* Note: Nevertheless we lose some information here. Namely,
|
||||
* the information that the 'amount' in 'account-old-security'
|
||||
* was worth 'value' in 'account-old-currency'. Maybe it would
|
||||
* be better to store that information in the price database?
|
||||
* But then, for old currency transactions there is still the
|
||||
* 'other' transaction, which is going to keep that
|
||||
* information. So I don't bother with that here. -- cstim,
|
||||
* 2002/11/20. */
|
||||
/* This Split needs fixing: The transaction-currency equals
|
||||
* the account-currency/commodity, but the amount/values are
|
||||
* inequal i.e. they still correspond to the security
|
||||
* (amount) and the currency (value). In the new model, the
|
||||
* value is the amount in the account-commodity -- so it
|
||||
* needs to be set to equal the amount (since the
|
||||
* account-currency doesn't exist anymore).
|
||||
*
|
||||
* Note: Nevertheless we lose some information here. Namely,
|
||||
* the information that the 'amount' in 'account-old-security'
|
||||
* was worth 'value' in 'account-old-currency'. Maybe it would
|
||||
* be better to store that information in the price database?
|
||||
* But then, for old currency transactions there is still the
|
||||
* 'other' transaction, which is going to keep that
|
||||
* information. So I don't bother with that here. -- cstim,
|
||||
* 2002/11/20. */
|
||||
|
||||
/*PWARN ("## Error likely: Split '%s' Amount %s %s, value %s",
|
||||
xaccSplitGetMemo (sp),
|
||||
gnc_numeric_to_string (amount),
|
||||
gnc_commodity_get_mnemonic (currency),
|
||||
gnc_numeric_to_string (value));*/
|
||||
xaccTransBeginEdit (trans);
|
||||
xaccSplitSetValue (sp, xaccSplitGetAmount (sp));
|
||||
xaccTransCommitEdit (trans);
|
||||
}
|
||||
/*else {
|
||||
PWARN ("Ok: Split '%s' Amount %s %s, value %s %s",
|
||||
xaccSplitGetMemo (sp),
|
||||
gnc_numeric_to_string (amount),
|
||||
gnc_commodity_get_mnemonic (currency),
|
||||
gnc_numeric_to_string (value),
|
||||
gnc_commodity_get_mnemonic (acc_currency));
|
||||
}*/
|
||||
PWARN ("Adjusted split with mismatched values, desc=\"%s\" memo=\"%s\""
|
||||
" old amount %s %s, new amount %s",
|
||||
trans->description, sp->memo,
|
||||
gnc_numeric_to_string (sp->amount),
|
||||
gnc_commodity_get_mnemonic (currency),
|
||||
gnc_numeric_to_string (sp->value));
|
||||
xaccTransBeginEdit (trans);
|
||||
xaccSplitSetAmount (sp, sp->value);
|
||||
xaccTransCommitEdit (trans);
|
||||
}
|
||||
/*else {
|
||||
PINFO ("Ok: Split '%s' Amount %s %s, value %s %s",
|
||||
xaccSplitGetMemo (sp),
|
||||
gnc_numeric_to_string (amount),
|
||||
gnc_commodity_get_mnemonic (currency),
|
||||
gnc_numeric_to_string (value),
|
||||
gnc_commodity_get_mnemonic (acc_currency));
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -536,7 +534,7 @@ xaccAccountScrubCommodity (Account *account)
|
||||
return;
|
||||
}
|
||||
|
||||
PERR ("account with no commodity");
|
||||
PERR ("Account \"%s\" does not have a commodity!", account->accountName);
|
||||
}
|
||||
|
||||
/* ================================================================ */
|
||||
|
@ -31,7 +31,7 @@
|
||||
*
|
||||
* HISTORY:
|
||||
* Created by Linas Vepstas December 1998
|
||||
* Copyright (c) 1998, 1999, 2000 Linas Vepstas <linas@linas.org>
|
||||
* Copyright (c) 1998-2000, 2003 Linas Vepstas <linas@linas.org>
|
||||
*/
|
||||
|
||||
#ifndef XACC_SCRUB_H
|
||||
@ -47,7 +47,7 @@
|
||||
* for orphaned inodes.
|
||||
*
|
||||
* The xaccTransScrubOrphans() method scrubs only the splits in the
|
||||
* given transaction. A root account group must be provided.
|
||||
* given transaction.
|
||||
*
|
||||
* The xaccAccountScrubOrphans() method performs this scrub only for the
|
||||
* indicated account, and not for any of its children.
|
||||
@ -58,15 +58,24 @@
|
||||
* The xaccGroupScrubOrphans() method performs this scrub for the
|
||||
* child accounts of this group.
|
||||
*/
|
||||
void xaccTransScrubOrphans (Transaction *trans, AccountGroup *root);
|
||||
void xaccTransScrubOrphans (Transaction *trans);
|
||||
void xaccAccountScrubOrphans (Account *acc);
|
||||
void xaccAccountTreeScrubOrphans (Account *acc);
|
||||
void xaccGroupScrubOrphans (AccountGroup *grp);
|
||||
|
||||
/** The ScrubSplit methods ensure that splits with the same commodity
|
||||
* and currency have the same amount and value.
|
||||
/** The xaccSplitScrub method ensures that if this split has the same
|
||||
* commodity and currency, then it will have the same amount and value.
|
||||
* If the commoidty is the currency, the split->amount is set to the
|
||||
* split value. In addition, if this split is an orphan, that is
|
||||
* fixed first. If the split account doesn't have a commodity declared,
|
||||
* an attempt is made to fix that first.
|
||||
*/
|
||||
void xaccSplitScrub (Split *split);
|
||||
|
||||
/** The xacc*ScrubSplits() calls xaccSplitScrub() on each split
|
||||
* in the respective structure: transaction, account,
|
||||
* account & it's children, account-group.
|
||||
*/
|
||||
void xaccTransScrubSplits (Transaction *trans);
|
||||
void xaccAccountScrubSplits (Account *account);
|
||||
void xaccAccountTreeScrubSplits (Account *account);
|
||||
|
Loading…
Reference in New Issue
Block a user