mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
move low-level API routines to scrub2, high-level to Scrub3
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@9389 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
288a062c13
commit
325d4ffd66
@ -140,23 +140,6 @@ xaccLotFill (GNCLot *lot)
|
||||
|
||||
/* ============================================================== */
|
||||
|
||||
void
|
||||
xaccAccountScrubDoubleBalance (Account *acc)
|
||||
{
|
||||
LotList *node;
|
||||
if (!acc) return;
|
||||
|
||||
ENTER ("acc=%s", acc->accountName);
|
||||
for (node = acc->lots; node; node=node->next)
|
||||
{
|
||||
GNCLot *lot = node->data;
|
||||
xaccLotScrubDoubleBalance (lot);
|
||||
}
|
||||
LEAVE ("acc=%s", acc->accountName);
|
||||
}
|
||||
|
||||
/* ============================================================== */
|
||||
|
||||
void
|
||||
xaccLotScrubDoubleBalance (GNCLot *lot)
|
||||
{
|
||||
@ -221,4 +204,231 @@ xaccLotScrubDoubleBalance (GNCLot *lot)
|
||||
LEAVE ("lot=%s", kvp_frame_get_string (gnc_lot_get_slots (lot), "/title"));
|
||||
}
|
||||
|
||||
/* ================================================================= */
|
||||
|
||||
static inline gboolean
|
||||
is_subsplit (Split *split)
|
||||
{
|
||||
KvpValue *kval;
|
||||
|
||||
/* generic stop-progress conditions */
|
||||
if (!split) return FALSE;
|
||||
g_return_val_if_fail (split->parent, FALSE);
|
||||
|
||||
/* If there are no sub-splits, then there's nothing to do. */
|
||||
kval = kvp_frame_get_slot (split->kvp_data, "lot-split");
|
||||
if (!kval) return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* ================================================================= */
|
||||
|
||||
void
|
||||
xaccScrubSubSplitPrice (Split *split)
|
||||
{
|
||||
gnc_numeric src_amt, src_val;
|
||||
SplitList *node;
|
||||
|
||||
if (FALSE == is_subsplit (split)) return;
|
||||
|
||||
ENTER (" ");
|
||||
/* Get 'price' of the indicated split */
|
||||
src_amt = xaccSplitGetAmount (split);
|
||||
src_val = xaccSplitGetValue (split);
|
||||
|
||||
/* Loop over splits, adjust each so that it has the same
|
||||
* ratio (i.e. price). Change the value to get things
|
||||
* right; do not change the amount */
|
||||
for (node=split->parent->splits; node; node=node->next)
|
||||
{
|
||||
Split *s = node->data;
|
||||
Transaction *txn = s->parent;
|
||||
gnc_numeric dst_amt, dst_val, target_val;
|
||||
gnc_numeric delta;
|
||||
int scu;
|
||||
|
||||
/* Skip the reference split */
|
||||
if (s == split) continue;
|
||||
|
||||
scu = gnc_commodity_get_fraction (txn->common_currency);
|
||||
|
||||
dst_amt = xaccSplitGetAmount (s);
|
||||
dst_val = xaccSplitGetValue (s);
|
||||
target_val = gnc_numeric_mul (dst_amt, src_val,
|
||||
GNC_DENOM_AUTO, GNC_DENOM_REDUCE);
|
||||
target_val = gnc_numeric_div (target_val, src_amt,
|
||||
scu, GNC_DENOM_EXACT);
|
||||
|
||||
/* If the required price changes are 'small', do nothing.
|
||||
* That is a case that the user will have to deal with
|
||||
* manually. This routine is really intended only for
|
||||
* a gross level of synchronization.
|
||||
*/
|
||||
delta = gnc_numeric_sub_fixed (target_val, dst_val);
|
||||
delta = gnc_numeric_abs (delta);
|
||||
if (3 * delta.num < delta.denom) continue;
|
||||
|
||||
/* If the amount is small, pass on that too */
|
||||
if ((-2 < dst_amt.num) && (dst_amt.num < 2)) continue;
|
||||
|
||||
/* Make the actual adjustment */
|
||||
xaccTransBeginEdit (txn);
|
||||
xaccSplitSetValue (s, target_val);
|
||||
xaccTransCommitEdit (txn);
|
||||
}
|
||||
LEAVE (" ");
|
||||
}
|
||||
|
||||
/* ================================================================= */
|
||||
|
||||
/* Remove the guid of b from a */
|
||||
static void
|
||||
remove_guids (Split *sa, Split *sb)
|
||||
{
|
||||
KvpFrame *ksub;
|
||||
|
||||
/* Find and remove the matching guid's */
|
||||
ksub = gnc_kvp_bag_find_by_guid (sa->kvp_data, "lot-split",
|
||||
"peer_guid", &sb->guid);
|
||||
if (!ksub)
|
||||
{
|
||||
PERR ("merging splits that didn't have correct gemini values!\n"
|
||||
"looking for guid=%s\n"
|
||||
"bag held: %s",
|
||||
guid_to_string (&sb->guid),
|
||||
kvp_frame_to_string (sa->kvp_data));
|
||||
return;
|
||||
}
|
||||
gnc_kvp_bag_remove_frame (sa->kvp_data, "lot-split", ksub);
|
||||
kvp_frame_delete (ksub);
|
||||
}
|
||||
|
||||
/* The 'merge_splits() routine causes the amount & value of sb
|
||||
* to be merged into sa; it then destroys sb. It also performs
|
||||
* some other misc cleanup */
|
||||
|
||||
static void
|
||||
merge_splits (Split *sa, Split *sb)
|
||||
{
|
||||
Account *act;
|
||||
Transaction *txn;
|
||||
gnc_numeric amt, val;
|
||||
|
||||
act = xaccSplitGetAccount (sb);
|
||||
xaccAccountBeginEdit (act);
|
||||
|
||||
txn = sa->parent;
|
||||
xaccTransBeginEdit (txn);
|
||||
|
||||
/* Remove the guid of sb from the 'gemini' of sa */
|
||||
remove_guids (sa, sb);
|
||||
|
||||
/* Add amount of sb into sa, ditto for value. */
|
||||
amt = xaccSplitGetAmount (sa);
|
||||
amt = gnc_numeric_add_fixed (amt, xaccSplitGetAmount (sb));
|
||||
xaccSplitSetAmount (sa, amt);
|
||||
|
||||
val = xaccSplitGetValue (sa);
|
||||
val = gnc_numeric_add_fixed (val, xaccSplitGetValue (sb));
|
||||
xaccSplitSetValue (sa, val);
|
||||
|
||||
/* Set reconcile to no; after this much violence,
|
||||
* no way its reconciled. */
|
||||
xaccSplitSetReconcile (sa, NREC);
|
||||
|
||||
/* If sb has associated gains splits, trash them. */
|
||||
if ((sb->gains_split) &&
|
||||
(sb->gains_split->gains & GAINS_STATUS_GAINS))
|
||||
{
|
||||
Transaction *t = sb->gains_split->parent;
|
||||
xaccTransBeginEdit (t);
|
||||
xaccTransDestroy (t);
|
||||
xaccTransCommitEdit (t);
|
||||
}
|
||||
|
||||
/* Finally, delete sb */
|
||||
xaccSplitDestroy(sb);
|
||||
|
||||
xaccTransCommitEdit (txn);
|
||||
xaccAccountCommitEdit (act);
|
||||
}
|
||||
|
||||
gboolean
|
||||
xaccScrubMergeSubSplits (Split *split)
|
||||
{
|
||||
gboolean rc = FALSE;
|
||||
Transaction *txn;
|
||||
SplitList *node;
|
||||
GNCLot *lot;
|
||||
|
||||
if (FALSE == is_subsplit (split)) return FALSE;
|
||||
|
||||
txn = split->parent;
|
||||
lot = xaccSplitGetLot (split);
|
||||
|
||||
ENTER (" ");
|
||||
restart:
|
||||
for (node=txn->splits; node; node=node->next)
|
||||
{
|
||||
Split *s = node->data;
|
||||
if (xaccSplitGetLot (s) != lot) continue;
|
||||
if (s == split) continue;
|
||||
|
||||
/* OK, this split is in the same lot (and thus same account)
|
||||
* as the indicated split. It must be a subsplit (although
|
||||
* we should double-check the kvp's to be sure). Merge the
|
||||
* two back together again. */
|
||||
merge_splits (split, s);
|
||||
rc = TRUE;
|
||||
goto restart;
|
||||
}
|
||||
LEAVE (" splits merged=%d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
gboolean
|
||||
xaccScrubMergeTransSubSplits (Transaction *txn)
|
||||
{
|
||||
gboolean rc = FALSE;
|
||||
SplitList *node;
|
||||
|
||||
if (!txn) return FALSE;
|
||||
|
||||
ENTER (" ");
|
||||
restart:
|
||||
for (node=txn->splits; node; node=node->next)
|
||||
{
|
||||
Split *s = node->data;
|
||||
if (!xaccScrubMergeSubSplits(s)) continue;
|
||||
|
||||
rc = TRUE;
|
||||
goto restart;
|
||||
}
|
||||
LEAVE (" splits merged=%d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
gboolean
|
||||
xaccScrubMergeLotSubSplits (GNCLot *lot)
|
||||
{
|
||||
gboolean rc = FALSE;
|
||||
SplitList *node;
|
||||
|
||||
if (!lot) return FALSE;
|
||||
|
||||
ENTER (" ");
|
||||
restart:
|
||||
for (node=gnc_lot_get_split_list(lot); node; node=node->next)
|
||||
{
|
||||
Split *s = node->data;
|
||||
if (!xaccScrubMergeSubSplits(s)) continue;
|
||||
|
||||
rc = TRUE;
|
||||
goto restart;
|
||||
}
|
||||
LEAVE (" splits merged=%d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* =========================== END OF FILE ======================= */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/********************************************************************\
|
||||
* Scrub2.h -- Convert Stock Accounts to use Lots *
|
||||
* Scrub2.h -- Low-level Lot Management Routines. *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
@ -26,11 +26,15 @@
|
||||
* @author Created by Linas Vepstas March 2003
|
||||
* @author Copyright (c) 2003 Linas Vepstas <linas@linas.org>
|
||||
*
|
||||
*
|
||||
* Provides a set of functions and utilities for checking and
|
||||
* repairing ('scrubbing clean') the usage of Lots and lot balances
|
||||
* in stock and commodity accounts. Broken lots are repaired using
|
||||
* a first-in, first-out (FIFO) accounting schedule.
|
||||
* Provides the low-level API for checking and repairing ('scrubbing
|
||||
* clean') the usage of Lots and lot balances in stock and commodity
|
||||
* accounts. Broken lots are repaired using a first-in, first-out
|
||||
* (FIFO) accounting schedule.
|
||||
*
|
||||
* This is a 'low-level' API in the sense that each routine accomplishes
|
||||
* only one particular task needed to clean up a Lot. To clean up a
|
||||
* Lot as a whole, you almost certainly want to use one of the
|
||||
* high-level API routines from the Scrub3.h file.
|
||||
*/
|
||||
|
||||
#ifndef XACC_SCRUB2_H
|
||||
@ -38,7 +42,6 @@
|
||||
|
||||
#include "gnc-engine.h"
|
||||
|
||||
|
||||
/** The xaccAccountAssignLots() routine will walk over all of
|
||||
* the splits in an account, and make sure that each belongs
|
||||
* to a lot. Currently, the default (and only implemented)
|
||||
@ -58,21 +61,6 @@ void xaccAccountAssignLots (Account *acc);
|
||||
*/
|
||||
void xaccLotFill (GNCLot *lot);
|
||||
|
||||
/** The xaccAccountScrubDoubleBalance() routine examines all
|
||||
* of the closed lots in an account, and verifies that the
|
||||
* lots are 'double balanced'. By 'double balance', we mean
|
||||
* that both the sum of the split amounts is zero, and that
|
||||
* the sum of the split values is zero. If a closed lot is
|
||||
* found where the sum of the values is not zero, the lot
|
||||
* is considered to have a 'realized gain or loss' that
|
||||
* hadn't been correctly handled. This routine then creates
|
||||
* a balancing transaction so as to record the realized
|
||||
* gain/loss, adds it to the lot, and adds it to a gain/loss
|
||||
* account. If there is no default gain/loss account, it
|
||||
* creates one.
|
||||
*/
|
||||
void xaccAccountScrubDoubleBalance (Account *acc);
|
||||
|
||||
/** The xaccLotScrubDoubleBalance() routine examines the indicated
|
||||
* lot. If it is open, it does nothing. If it is closed,
|
||||
* it then verifies that the lot is 'double balanced'.
|
||||
@ -88,5 +76,41 @@ void xaccAccountScrubDoubleBalance (Account *acc);
|
||||
*/
|
||||
void xaccLotScrubDoubleBalance (GNCLot *lot);
|
||||
|
||||
/** If a split has been pulled apart to make it fit into two (or more)
|
||||
* lots, then it becomes theoretically possible for each subsplit to
|
||||
* have a distinct price. But this would be wrong: each subsplit should
|
||||
* have the same price, within rounding errors. This routine will
|
||||
* examine the indicated split for sub-splits, and adjust the value
|
||||
* of each so that they all have the same price.
|
||||
*
|
||||
* There is a bit of a problem with the interpretation of 'rounding
|
||||
* errors' because there are pathological corner cases of small
|
||||
* amounts. So this routine is fairly loose, hopefully loose enough
|
||||
* so that the user can manually fine tune without having this routine
|
||||
* clobber thier work.
|
||||
*/
|
||||
void xaccScrubSubSplitPrice (Split *split);
|
||||
|
||||
/** The xaccScrubMergeSubSplits() routine will merge together
|
||||
* all of the splits that were at one time split off from this
|
||||
* split, but are no longer needed to be kept separate. Splits
|
||||
* might be split up if they need to be divided over multiple
|
||||
* lots; they can be merged back together if the lots change.
|
||||
* In particular, two sub-splits may be merged if they are in
|
||||
* the same lot, or in no lot. Note that, by definition, all
|
||||
* subsplits belong to the same transaction.
|
||||
*
|
||||
* The routine returns TRUE if a merger was performed, else
|
||||
* it returns FALSE.
|
||||
*
|
||||
* The xaccScrubMergeTransSubSplits() routine does the same, except
|
||||
* that it does it for all of the splits in the transaction.
|
||||
* The xaccScrubMergeLotSubSplits() routine does the same, except
|
||||
* that it does it for all of the splits in the lot.
|
||||
*/
|
||||
gboolean xaccScrubMergeSubSplits (Split *split);
|
||||
gboolean xaccScrubMergeTransSubSplits (Transaction *txn);
|
||||
gboolean xaccScrubMergeLotSubSplits (GNCLot *lot);
|
||||
|
||||
#endif /* XACC_SCRUB2_H */
|
||||
/** @} */
|
||||
|
@ -43,6 +43,8 @@
|
||||
#include "kvp-util-p.h"
|
||||
#include "policy-p.h"
|
||||
#include "Account.h"
|
||||
#include "AccountP.h"
|
||||
#include "Group.h"
|
||||
#include "Scrub2.h"
|
||||
#include "Scrub3.h"
|
||||
#include "Transaction.h"
|
||||
@ -52,233 +54,6 @@ static short module = MOD_LOT;
|
||||
|
||||
/* ================================================================= */
|
||||
|
||||
static inline gboolean
|
||||
is_subsplit (Split *split)
|
||||
{
|
||||
KvpValue *kval;
|
||||
|
||||
/* generic stop-progress conditions */
|
||||
if (!split) return FALSE;
|
||||
g_return_val_if_fail (split->parent, FALSE);
|
||||
|
||||
/* If there are no sub-splits, then there's nothing to do. */
|
||||
kval = kvp_frame_get_slot (split->kvp_data, "lot-split");
|
||||
if (!kval) return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* ================================================================= */
|
||||
|
||||
void
|
||||
xaccScrubSubSplitPrice (Split *split)
|
||||
{
|
||||
gnc_numeric src_amt, src_val;
|
||||
SplitList *node;
|
||||
|
||||
if (FALSE == is_subsplit (split)) return;
|
||||
|
||||
ENTER (" ");
|
||||
/* Get 'price' of the indicated split */
|
||||
src_amt = xaccSplitGetAmount (split);
|
||||
src_val = xaccSplitGetValue (split);
|
||||
|
||||
/* Loop over splits, adjust each so that it has the same
|
||||
* ratio (i.e. price). Change the value to get things
|
||||
* right; do not change the amount */
|
||||
for (node=split->parent->splits; node; node=node->next)
|
||||
{
|
||||
Split *s = node->data;
|
||||
Transaction *txn = s->parent;
|
||||
gnc_numeric dst_amt, dst_val, target_val;
|
||||
gnc_numeric delta;
|
||||
int scu;
|
||||
|
||||
/* Skip the reference split */
|
||||
if (s == split) continue;
|
||||
|
||||
scu = gnc_commodity_get_fraction (txn->common_currency);
|
||||
|
||||
dst_amt = xaccSplitGetAmount (s);
|
||||
dst_val = xaccSplitGetValue (s);
|
||||
target_val = gnc_numeric_mul (dst_amt, src_val,
|
||||
GNC_DENOM_AUTO, GNC_DENOM_REDUCE);
|
||||
target_val = gnc_numeric_div (target_val, src_amt,
|
||||
scu, GNC_DENOM_EXACT);
|
||||
|
||||
/* If the required price changes are 'small', do nothing.
|
||||
* That is a case that the user will have to deal with
|
||||
* manually. This routine is really intended only for
|
||||
* a gross level of synchronization.
|
||||
*/
|
||||
delta = gnc_numeric_sub_fixed (target_val, dst_val);
|
||||
delta = gnc_numeric_abs (delta);
|
||||
if (3 * delta.num < delta.denom) continue;
|
||||
|
||||
/* If the amount is small, pass on that too */
|
||||
if ((-2 < dst_amt.num) && (dst_amt.num < 2)) continue;
|
||||
|
||||
/* Make the actual adjustment */
|
||||
xaccTransBeginEdit (txn);
|
||||
xaccSplitSetValue (s, target_val);
|
||||
xaccTransCommitEdit (txn);
|
||||
}
|
||||
LEAVE (" ");
|
||||
}
|
||||
|
||||
/* ================================================================= */
|
||||
|
||||
/* Remove the guid of b from a */
|
||||
static void
|
||||
remove_guids (Split *sa, Split *sb)
|
||||
{
|
||||
KvpFrame *ksub;
|
||||
|
||||
/* Find and remove the matching guid's */
|
||||
ksub = gnc_kvp_bag_find_by_guid (sa->kvp_data, "lot-split",
|
||||
"peer_guid", &sb->guid);
|
||||
if (!ksub)
|
||||
{
|
||||
PERR ("merging splits that didn't have correct gemini values!\n"
|
||||
"looking for guid=%s\n"
|
||||
"bag held: %s",
|
||||
guid_to_string (&sb->guid),
|
||||
kvp_frame_to_string (sa->kvp_data));
|
||||
return;
|
||||
}
|
||||
gnc_kvp_bag_remove_frame (sa->kvp_data, "lot-split", ksub);
|
||||
kvp_frame_delete (ksub);
|
||||
}
|
||||
|
||||
/* The 'merge_splits() routine causes the amount & value of sb
|
||||
* to be merged into sa; it then destroys sb. It also performs
|
||||
* some other misc cleanup */
|
||||
|
||||
static void
|
||||
merge_splits (Split *sa, Split *sb)
|
||||
{
|
||||
Account *act;
|
||||
Transaction *txn;
|
||||
gnc_numeric amt, val;
|
||||
|
||||
act = xaccSplitGetAccount (sb);
|
||||
xaccAccountBeginEdit (act);
|
||||
|
||||
txn = sa->parent;
|
||||
xaccTransBeginEdit (txn);
|
||||
|
||||
/* Remove the guid of sb from the 'gemini' of sa */
|
||||
remove_guids (sa, sb);
|
||||
|
||||
/* Add amount of sb into sa, ditto for value. */
|
||||
amt = xaccSplitGetAmount (sa);
|
||||
amt = gnc_numeric_add_fixed (amt, xaccSplitGetAmount (sb));
|
||||
xaccSplitSetAmount (sa, amt);
|
||||
|
||||
val = xaccSplitGetValue (sa);
|
||||
val = gnc_numeric_add_fixed (val, xaccSplitGetValue (sb));
|
||||
xaccSplitSetValue (sa, val);
|
||||
|
||||
/* Set reconcile to no; after this much violence,
|
||||
* no way its reconciled. */
|
||||
xaccSplitSetReconcile (sa, NREC);
|
||||
|
||||
/* If sb has associated gains splits, trash them. */
|
||||
if ((sb->gains_split) &&
|
||||
(sb->gains_split->gains & GAINS_STATUS_GAINS))
|
||||
{
|
||||
Transaction *t = sb->gains_split->parent;
|
||||
xaccTransBeginEdit (t);
|
||||
xaccTransDestroy (t);
|
||||
xaccTransCommitEdit (t);
|
||||
}
|
||||
|
||||
/* Finally, delete sb */
|
||||
xaccSplitDestroy(sb);
|
||||
|
||||
xaccTransCommitEdit (txn);
|
||||
xaccAccountCommitEdit (act);
|
||||
}
|
||||
|
||||
gboolean
|
||||
xaccScrubMergeSubSplits (Split *split)
|
||||
{
|
||||
gboolean rc = FALSE;
|
||||
Transaction *txn;
|
||||
SplitList *node;
|
||||
GNCLot *lot;
|
||||
|
||||
if (FALSE == is_subsplit (split)) return FALSE;
|
||||
|
||||
txn = split->parent;
|
||||
lot = xaccSplitGetLot (split);
|
||||
|
||||
ENTER (" ");
|
||||
restart:
|
||||
for (node=txn->splits; node; node=node->next)
|
||||
{
|
||||
Split *s = node->data;
|
||||
if (xaccSplitGetLot (s) != lot) continue;
|
||||
if (s == split) continue;
|
||||
|
||||
/* OK, this split is in the same lot (and thus same account)
|
||||
* as the indicated split. It must be a subsplit (although
|
||||
* we should double-check the kvp's to be sure). Merge the
|
||||
* two back together again. */
|
||||
merge_splits (split, s);
|
||||
rc = TRUE;
|
||||
goto restart;
|
||||
}
|
||||
LEAVE (" splits merged=%d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
gboolean
|
||||
xaccScrubMergeTransSubSplits (Transaction *txn)
|
||||
{
|
||||
gboolean rc = FALSE;
|
||||
SplitList *node;
|
||||
|
||||
if (!txn) return FALSE;
|
||||
|
||||
ENTER (" ");
|
||||
restart:
|
||||
for (node=txn->splits; node; node=node->next)
|
||||
{
|
||||
Split *s = node->data;
|
||||
if (!xaccScrubMergeSubSplits(s)) continue;
|
||||
|
||||
rc = TRUE;
|
||||
goto restart;
|
||||
}
|
||||
LEAVE (" splits merged=%d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
gboolean
|
||||
xaccScrubMergeLotSubSplits (GNCLot *lot)
|
||||
{
|
||||
gboolean rc = FALSE;
|
||||
SplitList *node;
|
||||
|
||||
if (!lot) return FALSE;
|
||||
|
||||
ENTER (" ");
|
||||
restart:
|
||||
for (node=gnc_lot_get_split_list(lot); node; node=node->next)
|
||||
{
|
||||
Split *s = node->data;
|
||||
if (!xaccScrubMergeSubSplits(s)) continue;
|
||||
|
||||
rc = TRUE;
|
||||
goto restart;
|
||||
}
|
||||
LEAVE (" splits merged=%d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ================================================================= */
|
||||
|
||||
gboolean
|
||||
xaccScrubLot (GNCLot *lot)
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
/********************************************************************\
|
||||
* Scrub3.h -- Constrain Cap Gains to Track Sources of Gains *
|
||||
* Scrub3.h -- High-Level Lot Constraint routines. *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
@ -22,17 +22,13 @@
|
||||
/** @addtogroup Engine
|
||||
@{ */
|
||||
/** @file Scrub3.h
|
||||
* @breif Constrain Cap Gains to Track Sources of Gains
|
||||
* @breif Hiogh-Level API for imposing Lot constraints
|
||||
* @author Created by Linas Vepstas Sept 2003
|
||||
* @author Copyright (c) 2003 Linas Vepstas <linas@linas.org>
|
||||
*
|
||||
* Provides a set of functions and utilities for checking and
|
||||
* repairing ('scrubbing clean') the usage of Cap Gains
|
||||
* transactions in stock and commodity accounts.
|
||||
*
|
||||
* NOTE: Unless you have special needs, the functions you are looking
|
||||
* for and almost certainly want to use are either xaccScrubLot() or
|
||||
* xaccAccountScrubLots().
|
||||
* Provides the high-level API for checking and repairing ('scrubbing
|
||||
* clean') the usage of Lots and Cap Gains transactions in stock and
|
||||
* commodity accounts.
|
||||
*/
|
||||
#ifndef XACC_SCRUB3_H
|
||||
#define XACC_SCRUB3_H
|
||||
@ -73,42 +69,5 @@ void xaccAccountScrubLots (Account *acc);
|
||||
void xaccGroupScrubLots (AccountGroup *grp);
|
||||
void xaccAccountTreeScrubLots (Account *acc);
|
||||
|
||||
|
||||
/** If a split has been pulled apart to make it fit into two (or more)
|
||||
* lots, then it becomes theoretically possible for each subsplit to
|
||||
* have a distinct price. But this would be wrong: each subsplit should
|
||||
* have the same price, within rounding errors. This routine will
|
||||
* examine the indicated split for sub-splits, and adjust the value
|
||||
* of each so that they all have the same price.
|
||||
*
|
||||
* There is a bit of a problem with the interpretation of 'rounding
|
||||
* errors' because there are pathological corner cases of small
|
||||
* amounts. So this routine is fairly loose, hopefully loose enough
|
||||
* so that the user can manually fine tune without having this routine
|
||||
* clobber thier work.
|
||||
*/
|
||||
void xaccScrubSubSplitPrice (Split *split);
|
||||
|
||||
/** The xaccScrubMergeSubSplits() routine will merge together
|
||||
* all of the splits that were at one time split off from this
|
||||
* split, but are no longer needed to be kept separate. Splits
|
||||
* might be split up if they need to be divided over multiple
|
||||
* lots; they can be merged back together if the lots change.
|
||||
* In particular, two sub-splits may be merged if they are in
|
||||
* the same lot, or in no lot. Note that, by definition, all
|
||||
* subsplits belong to the same transaction.
|
||||
*
|
||||
* The routine returns TRUE if a merger was performed, else
|
||||
* it returns FALSE.
|
||||
*
|
||||
* The xaccScrubMergeTransSubSplits() routine does the same, except
|
||||
* that it does it for all of the splits in the transaction.
|
||||
* The xaccScrubMergeLotSubSplits() routine does the same, except
|
||||
* that it does it for all of the splits in the lot.
|
||||
*/
|
||||
gboolean xaccScrubMergeSubSplits (Split *split);
|
||||
gboolean xaccScrubMergeTransSubSplits (Transaction *txn);
|
||||
gboolean xaccScrubMergeLotSubSplits (GNCLot *lot);
|
||||
|
||||
#endif /* XACC_SCRUB3_H */
|
||||
/** @} */
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#include "Account.h"
|
||||
#include "Group.h"
|
||||
#include "Scrub2.h"
|
||||
#include "Scrub3.h"
|
||||
#include "gnc-engine-util.h"
|
||||
#include "gnc-module.h"
|
||||
#include "test-stuff.h"
|
||||
@ -46,7 +46,7 @@ run_test (void)
|
||||
add_random_transactions_to_book (book, 720);
|
||||
|
||||
grp = xaccGetAccountGroup (book);
|
||||
xaccGroupScrubLotsBalance (grp);
|
||||
xaccGroupScrubLots (grp);
|
||||
|
||||
/* --------------------------------------------------------- */
|
||||
/* In the second test, we create an account with unrealized gains,
|
||||
|
Loading…
Reference in New Issue
Block a user