mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
compute cost basis correctly
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@1584 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
ec762df4a6
commit
2faa2d40b3
@ -34,6 +34,7 @@
|
|||||||
#include "GroupP.h"
|
#include "GroupP.h"
|
||||||
#include "date.h"
|
#include "date.h"
|
||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
|
#include "Queue.h"
|
||||||
#include "Transaction.h"
|
#include "Transaction.h"
|
||||||
#include "TransactionP.h"
|
#include "TransactionP.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@ -203,7 +204,7 @@ void
|
|||||||
xaccAccountCommitEdit (Account *acc)
|
xaccAccountCommitEdit (Account *acc)
|
||||||
{
|
{
|
||||||
if (!acc) return;
|
if (!acc) return;
|
||||||
acc->changed = 1;
|
acc->changed |= ACC_INVALIDATE_ALL;
|
||||||
acc->open = 0;
|
acc->open = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,7 +264,7 @@ disable for now till we figure out what the right thing is.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* mark the account as having changed */
|
/* mark the account as having changed */
|
||||||
acc -> changed = TRUE;
|
acc -> changed |= ACC_INVALIDATE_ALL;
|
||||||
|
|
||||||
/* if this split belongs to another acount, remove it from
|
/* if this split belongs to another acount, remove it from
|
||||||
* there first. We don't want to ever leave the system
|
* there first. We don't want to ever leave the system
|
||||||
@ -357,7 +358,7 @@ xaccAccountRemoveSplit ( Account *acc, Split *split )
|
|||||||
CHECK (acc);
|
CHECK (acc);
|
||||||
|
|
||||||
/* mark the account as having changed */
|
/* mark the account as having changed */
|
||||||
acc -> changed = TRUE;
|
acc -> changed |= ACC_INVALIDATE_ALL;
|
||||||
|
|
||||||
for( i=0,j=0; j<acc->numSplits; i++,j++ ) {
|
for( i=0,j=0; j<acc->numSplits; i++,j++ ) {
|
||||||
acc->splits[i] = acc->splits[j];
|
acc->splits[i] = acc->splits[j];
|
||||||
@ -416,7 +417,8 @@ xaccAccountRecomputeBalance( Account * acc )
|
|||||||
Split *split, *last_split = NULL;
|
Split *split, *last_split = NULL;
|
||||||
|
|
||||||
if( NULL == acc ) return;
|
if( NULL == acc ) return;
|
||||||
if (FALSE == acc->changed) return;
|
if (0x0 == (ACC_INVALID_BALN & acc->changed)) return;
|
||||||
|
acc->changed &= ~ACC_INVALID_BALN;
|
||||||
|
|
||||||
split = acc->splits[0];
|
split = acc->splits[0];
|
||||||
while (split) {
|
while (split) {
|
||||||
@ -453,7 +455,8 @@ xaccAccountRecomputeBalance( Account * acc )
|
|||||||
split -> cleared_balance = dcleared_balance;
|
split -> cleared_balance = dcleared_balance;
|
||||||
split -> reconciled_balance = dreconciled_balance;
|
split -> reconciled_balance = dreconciled_balance;
|
||||||
}
|
}
|
||||||
split -> cost_basis = dbalance;
|
/* invalidate the cost basis; this has to be computed with other routine */
|
||||||
|
split -> cost_basis = 0.0;
|
||||||
|
|
||||||
last_split = split;
|
last_split = split;
|
||||||
i++;
|
i++;
|
||||||
@ -479,6 +482,46 @@ xaccAccountRecomputeBalance( Account * acc )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************\
|
||||||
|
\********************************************************************/
|
||||||
|
|
||||||
|
void
|
||||||
|
xaccAccountRecomputeCostBasis( Account * acc )
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
double amt = 0.0;
|
||||||
|
Split *split = NULL;
|
||||||
|
Queue *q;
|
||||||
|
|
||||||
|
if( NULL == acc ) return;
|
||||||
|
if (0x0 == (ACC_INVALID_COSTB & acc->changed)) return;
|
||||||
|
acc->changed &= ~ACC_INVALID_COSTB;
|
||||||
|
|
||||||
|
/* create the FIFO queue */
|
||||||
|
q = xaccMallocQueue ();
|
||||||
|
|
||||||
|
/* loop over all splits in this account */
|
||||||
|
split = acc->splits[0];
|
||||||
|
while (split) {
|
||||||
|
|
||||||
|
/* positive amounts are a purchase, negative are a sale.
|
||||||
|
* Use FIFO accounting: purchase to head, sale from tail. */
|
||||||
|
amt = split->damount;
|
||||||
|
if (0.0 < amt) {
|
||||||
|
xaccQueuePushHead (q, split);
|
||||||
|
} else
|
||||||
|
if (0.0 > amt) {
|
||||||
|
xaccQueuePopTailShares (q, amt);
|
||||||
|
}
|
||||||
|
split->cost_basis = xaccQueueGetValue (q);
|
||||||
|
|
||||||
|
i++;
|
||||||
|
split = acc->splits[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
xaccFreeQueue (q);
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
* xaccCheckDateOrder *
|
* xaccCheckDateOrder *
|
||||||
* check this split to see if the date is in correct order *
|
* check this split to see if the date is in correct order *
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
/********************************************************************\
|
/********************************************************************\
|
||||||
* Account.h -- the Account data structure *
|
* Account.h -- the Account data structure *
|
||||||
* Copyright (C) 1997 Robin D. Clark *
|
* Copyright (C) 1997 Robin D. Clark *
|
||||||
* Copyright (C) 1997, 1998 Linas Vepstas *
|
* Copyright (C) 1997, 1998, 1999 Linas Vepstas *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or *
|
* This program is free software; you can redistribute it and/or *
|
||||||
* modify it under the terms of the GNU General Public License as *
|
* modify it under the terms of the GNU General Public License as *
|
||||||
@ -129,8 +129,9 @@ struct _account {
|
|||||||
int numSplits; /* length of splits array below */
|
int numSplits; /* length of splits array below */
|
||||||
Split **splits; /* ptr to array of ptrs to splits */
|
Split **splits; /* ptr to array of ptrs to splits */
|
||||||
|
|
||||||
/* the "changed" flag helps the gui keep track of
|
/* The "changed" flag is used to invalidate cached values in this structure.
|
||||||
* changes to this account */
|
* currently, the balances and the cost basis are cached.
|
||||||
|
*/
|
||||||
short changed;
|
short changed;
|
||||||
|
|
||||||
/* the "open" flag indicates if the account has been
|
/* the "open" flag indicates if the account has been
|
||||||
@ -138,6 +139,11 @@ struct _account {
|
|||||||
short open;
|
short open;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* bitfields for the changed flag */
|
||||||
|
#define ACC_INVALID_BALN 0x1
|
||||||
|
#define ACC_INVALID_COSTB 0x2
|
||||||
|
#define ACC_INVALIDATE_ALL 0x3
|
||||||
|
|
||||||
/* bitflields for the open flag */
|
/* bitflields for the open flag */
|
||||||
#define ACC_BEGIN_EDIT 0x1
|
#define ACC_BEGIN_EDIT 0x1
|
||||||
#define ACC_DEFER_REBALANCE 0x2
|
#define ACC_DEFER_REBALANCE 0x2
|
||||||
@ -160,6 +166,12 @@ void xaccAccountRemoveSplit (Account *, Split *);
|
|||||||
void xaccAccountRecomputeBalance (Account *);
|
void xaccAccountRecomputeBalance (Account *);
|
||||||
void xaccAccountRecomputeBalances (Account **);
|
void xaccAccountRecomputeBalances (Account **);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* recomputes the cost basis
|
||||||
|
*/
|
||||||
|
void xaccAccountRecomputeCostBasis (Account *);
|
||||||
|
|
||||||
|
|
||||||
/** GLOBALS *********************************************************/
|
/** GLOBALS *********************************************************/
|
||||||
|
|
||||||
extern int next_free_unique_account_id;
|
extern int next_free_unique_account_id;
|
||||||
|
@ -203,7 +203,7 @@ xaccConfigGetForceDoubleEntry (void)
|
|||||||
|
|
||||||
#define MARK_SPLIT(split) { \
|
#define MARK_SPLIT(split) { \
|
||||||
Account *acc = (Account *) ((split)->acc); \
|
Account *acc = (Account *) ((split)->acc); \
|
||||||
if (acc) acc->changed = 1; \
|
if (acc) acc->changed |= ACC_INVALIDATE_ALL; \
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -308,6 +308,7 @@ double xaccSplitGetShareBalance (Split *s)
|
|||||||
double xaccSplitGetCostBasis (Split *s)
|
double xaccSplitGetCostBasis (Split *s)
|
||||||
{
|
{
|
||||||
if (!s) return 0.0;
|
if (!s) return 0.0;
|
||||||
|
xaccAccountRecomputeCostBasis (s->acc);
|
||||||
return s->cost_basis;
|
return s->cost_basis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user