Move some gains-related transaction-scrubbing operations to from

cap-gains.c to Transaction.c.
   Fix a logic error where "split->gains |= ~GAINS_STATUS_ADIRTY" was supposed
   to be "split->gains &= ~GAINS_STATUS_ADIRTY".

   Disable the loop-restart code in xaccTransScrubGainsDate() because I think
   the state changes inside the loop will never cause a previously-skipped 
   Split to be not skipped during another pass.

   Incidental:
      make both xaccTransFindSplitByAccount() arguments 'const'
      Internalize Begin/Commit edit block into xaccTransScrubSplits()


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@13921 57a11ea4-9604-0410-9ed3-97b8803252fd
zzzoldfeatures/register-rewrite
Chris Shoemaker 20 years ago
parent e6f9e20679
commit 40a9ed1925

@ -407,10 +407,8 @@ xaccTransScrubImbalance (Transaction *trans, AccountGroup *root,
ENTER ("()");
/* Must look or orphan splits even if there is no imbalance. */
xaccTransBeginEdit(trans);
/* Must look for orphan splits even if there is no imbalance. */
xaccTransScrubSplits (trans);
xaccTransCommitEdit(trans);
/* If the transaction is balanced, nothing more to do */
imbalance = xaccTransGetImbalance (trans);

@ -1841,16 +1841,102 @@ xaccTransScrubSplits (Transaction *trans)
if (!trans) return;
xaccTransBeginEdit(trans);
/* The split scrub expects the transaction to have a currency! */
currency = xaccTransGetCurrency (trans);
if (!currency)
PERR ("Transaction doesn't have a currency!");
FOR_EACH_SPLIT(trans, xaccSplitScrub(s));
xaccTransCommitEdit(trans);
}
/* ============================================================== */
/** The xaccTransScrubGainsDate() routine is used to keep the posted date
* of gains splits in sync with the posted date of the transaction
* that caused the gains.
*
* The posted date is kept in sync using a lazy-evaluation scheme.
* If xaccTransactionSetDatePosted() is called, the date change is
* accepted, and the split is marked date-dirty. If the posted date
* is queried for (using GetDatePosted()), then the transaction is
* evaluated. If it's a gains-transaction, then its date is copied
* from the source transaction that created the gains.
*/
static void
xaccTransScrubGainsDate (Transaction *trans)
{
SplitList *node;
Timespec ts = {0,0};
//restart_search:
for (node = trans->splits; node; node=node->next) {
Split *s = node->data;
if (!xaccTransStillHasSplit(trans, s)) continue;
xaccSplitDetermineGainStatus(s);
if ((GAINS_STATUS_GAINS & s->gains) &&
s->gains_split &&
((s->gains_split->gains & GAINS_STATUS_DATE_DIRTY) ||
(s->gains & GAINS_STATUS_DATE_DIRTY)))
{
Transaction *source_trans = s->gains_split->parent;
ts = source_trans->date_posted;
s->gains &= ~GAINS_STATUS_DATE_DIRTY;
s->gains_split->gains &= ~GAINS_STATUS_DATE_DIRTY;
xaccTransSetDatePostedTS(trans, &ts);
FOR_EACH_SPLIT(trans, s->gains &= ~GAINS_STATUS_DATE_DIRTY);
//goto restart_search;
}
}
}
/* ============================================================== */
void
xaccTransScrubGains (Transaction *trans, Account *gain_acc)
{
SplitList *node;
ENTER("(trans=%p)", trans);
/* Lock down posted date, its to be synced to the posted date
* for the source of the cap gains. */
xaccTransScrubGainsDate(trans);
/* Fix up the split amount */
restart:
for (node = trans->splits; node; node = node->next) {
Split *s = node->data;
if (!xaccTransStillHasSplit(trans, s)) continue;
xaccSplitDetermineGainStatus(s);
if (s->gains & GAINS_STATUS_ADIRTY) {
gboolean altered = FALSE;
s->gains &= ~GAINS_STATUS_ADIRTY;
if (s->lot)
altered = xaccScrubLot(s->lot);
else
altered = xaccSplitAssign(s);
if (altered) goto restart;
}
}
/* Fix up gains split value */
FOR_EACH_SPLIT(trans,
if ((s->gains & GAINS_STATUS_VDIRTY) ||
(s->gains_split &&
(s->gains_split->gains & GAINS_STATUS_VDIRTY)))
xaccSplitComputeCapGains(s, gain_acc);
);
LEAVE("(trans=%p)", trans);
}
Split *
xaccTransFindSplitByAccount(Transaction *trans, Account *acc)
xaccTransFindSplitByAccount(const Transaction *trans, const Account *acc)
{
if (!trans || !acc) return NULL;
FOR_EACH_SPLIT(trans, if (xaccSplitGetAccount(s) == acc) return s);

@ -194,7 +194,18 @@ gboolean xaccTransIsOpen (const Transaction *trans);
Transaction * xaccTransLookup (const GUID *guid, QofBook *book);
#define xaccTransLookupDirect(g,b) xaccTransLookup(&(g),b)
Split * xaccTransFindSplitByAccount(Transaction *trans, Account *acc);
Split * xaccTransFindSplitByAccount(const Transaction *trans,
const Account *acc);
/** The xaccTransScrubGains() routine performs a number of cleanup
* functions on the indicated transaction, with the end-goal of
* setting up a consistent set of gains/losses for all the splits
* in the transaction. This includes making sure that the lot
* assignments of all the splits are good, and that the lots
* balance appropriately.
*/
void xaccTransScrubGains (Transaction *trans, Account *gain_acc);
/** \warning XXX FIXME
* gnc_book_count_transactions is a utility function,

@ -647,8 +647,9 @@ xaccSplitGetCapGainsSplit (const Split *split)
gains_guid = kvp_value_get_guid (val);
if (!gains_guid) return NULL;
/* Both splits will be in the same collection, so seearch there. */
gains_split = (Split*) qof_collection_lookup_entity (split->inst.entity.collection, gains_guid);
/* Both splits will be in the same collection, so search there. */
gains_split = (Split*) qof_collection_lookup_entity (
split->inst.entity.collection, gains_guid);
PINFO ("split=%p has gains-split=%p", split, gains_split);
return gains_split;
}
@ -703,7 +704,7 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
kvp_frame_get_string (gnc_lot_get_slots (lot), "/title"));
/* Make sure the status flags and pointers are initialized */
if (GAINS_STATUS_UNKNOWN == split->gains) xaccSplitDetermineGainStatus(split);
xaccSplitDetermineGainStatus(split);
/* Not possible to have gains if the transaction currency and
* account commodity are identical. */
@ -1092,106 +1093,4 @@ xaccLotComputeCapGains (GNCLot *lot, Account *gain_acc)
LEAVE("(lot=%p)", lot);
}
/* ============================================================== */
/** The xaccScrubGainsDate() routine is used to keep the posted date
* of gains splis in sync with the posted date of the transaction
* that caused the gains.
*
* The posted date is kept in sync using a lazy-evaluation scheme.
* If xaccTransactionSetDatePosted() is called, the date change is
* accepted, and the split is marked date-dirty. If the posted date
* is queried for (using GetDatePosted()), then the transaction is
* evaluated. If its a gains-transaction, then it's date is copied
* from the source transaction that created the gains.
*/
static void
xaccScrubGainsDate (Transaction *trans)
{
SplitList *node;
Timespec ts = {0,0};
gboolean do_set;
restart_search:
do_set = FALSE;
for (node = trans->splits; node; node=node->next)
{
Split *s = node->data;
if (GAINS_STATUS_UNKNOWN == s->gains) xaccSplitDetermineGainStatus(s);
if ((GAINS_STATUS_GAINS & s->gains) &&
s->gains_split &&
((s->gains_split->gains & GAINS_STATUS_DATE_DIRTY) ||
(s->gains & GAINS_STATUS_DATE_DIRTY)))
{
Transaction *source_trans = s->gains_split->parent;
ts = source_trans->date_posted;
do_set = TRUE;
s->gains &= ~GAINS_STATUS_DATE_DIRTY;
s->gains_split->gains &= ~GAINS_STATUS_DATE_DIRTY;
break;
}
}
if (do_set)
{
xaccTransBeginEdit (trans);
xaccTransSetDatePostedTS(trans, &ts);
xaccTransCommitEdit (trans);
for (node = trans->splits; node; node=node->next)
{
Split *s = node->data;
s->gains &= ~GAINS_STATUS_DATE_DIRTY;
}
goto restart_search;
}
}
/* ============================================================== */
void
xaccTransScrubGains (Transaction *trans, Account *gain_acc)
{
SplitList *node;
ENTER("(trans=%p)", trans);
/* Lock down posted date, its to be synced to the posted date
* for the source of the cap gains. */
xaccScrubGainsDate(trans);
/* Fix up the split amount */
restart:
for (node=trans->splits; node; node=node->next)
{
Split *split = node->data;
if (GAINS_STATUS_UNKNOWN == split->gains)
{
xaccSplitDetermineGainStatus(split);
}
if (split->gains & GAINS_STATUS_ADIRTY)
{
gboolean altered = FALSE;
split->gains |= ~GAINS_STATUS_ADIRTY;
if (split->lot)
altered = xaccScrubLot (split->lot);
else
altered = xaccSplitAssign (split);
if (altered) goto restart;
}
}
/* Fix up gains split value */
for (node=trans->splits; node; node=node->next)
{
Split *split = node->data;
if ((split->gains & GAINS_STATUS_VDIRTY) ||
(split->gains_split &&
(split->gains_split->gains & GAINS_STATUS_VDIRTY)))
{
xaccSplitComputeCapGains (split, gain_acc);
}
}
LEAVE("(trans=%p)", trans);
}
/* =========================== END OF FILE ======================= */

@ -202,15 +202,6 @@ gboolean xaccSplitAssign (Split *split);
*/
Split * xaccSplitAssignToLot (Split *split, GNCLot *lot);
/** The xaccTransScrubGains() routine performs a number of cleanup
* functions on the indicated transaction, with the end-goal of
* setting up a consistent set of gains/losses for all the splits
* in the transaction. This includes making sure that the lot
* assignments of all the splits are good, and that the lots
* balance appropriately.
*/
void xaccTransScrubGains (Transaction *trans, Account *gain_acc);
/** The xaccSplitComputeCapGains() routine computes the cap gains
* or losses for the indicated split. The gains are placed into
* the 'gains_acct'. If the gains_acct is NULL, then the appropriate

Loading…
Cancel
Save