mirror of
https://github.com/Gnucash/gnucash.git
synced 2024-12-01 21:19:16 -06:00
Patch from Mike Alexander's to handle multiple lot dispositions on the
same day. Needed since the transaction sorting code may sort gains splits after other splits on the same day. Add a new function to find the source split associated with a capital gains split. Also use lot_amount and lot_value consistently instead of opening_amount and opening_value. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@13887 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
c90adde7ba
commit
2f5698d619
@ -1,5 +1,14 @@
|
||||
2006-04-29 David Hampton <hampton@employees.org>
|
||||
|
||||
* src/engine/gnc-lot.c:
|
||||
* src/engine/cap-gains.[ch]: Patch from Mike Alexander's to handle
|
||||
multiple lot dispositions on the same day. Needed since the
|
||||
transaction sorting code may sort gains splits after other splits
|
||||
on the same day. Add a new function to find the source split
|
||||
associated with a capital gains split. Also use lot_amount and
|
||||
lot_value consistently instead of opening_amount and
|
||||
opening_value.
|
||||
|
||||
* src/business/business-gnome/dialog-billterms.c:
|
||||
* src/business/business-gnome/glade/billterms.glade: Eliminate
|
||||
some gtk warning messages. Stop the contents of the Bill Terms
|
||||
|
@ -141,6 +141,8 @@ finder_helper (GNCLot *lot, gpointer user_data)
|
||||
if (0 == (els->numeric_pred) (bal)) return NULL;
|
||||
|
||||
s = gnc_lot_get_earliest_split (lot);
|
||||
if (s == NULL) return NULL;
|
||||
|
||||
trans = s->parent;
|
||||
if (els->currency &&
|
||||
(FALSE == gnc_commodity_equiv (els->currency,
|
||||
@ -653,6 +655,29 @@ xaccSplitGetCapGainsSplit (const Split *split)
|
||||
|
||||
/* ============================================================== */
|
||||
|
||||
Split *
|
||||
xaccSplitGetGainsSourceSplit (const Split *split)
|
||||
{
|
||||
KvpValue *val;
|
||||
GUID *source_guid;
|
||||
Split *source_split;
|
||||
|
||||
if (!split) return NULL;
|
||||
|
||||
val = kvp_frame_get_slot (split->inst.kvp_data, "gains-source");
|
||||
if (!val) return NULL;
|
||||
source_guid = kvp_value_get_guid (val);
|
||||
if (!source_guid) return NULL;
|
||||
|
||||
/* Both splits will be in the same collection, so search there. */
|
||||
source_split = (Split*) qof_collection_lookup_entity (split->inst.entity.collection,
|
||||
source_guid);
|
||||
PINFO ("split=%p has source-split=%p", split, source_split);
|
||||
return source_split;
|
||||
}
|
||||
|
||||
/* ============================================================== */
|
||||
|
||||
void
|
||||
xaccSplitComputeCapGains(Split *split, Account *gain_acc)
|
||||
{
|
||||
@ -783,6 +808,9 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
|
||||
* 'dirty' and the gains really do need to be recomputed.
|
||||
* So start working things. */
|
||||
|
||||
/* Get the amount and value in this lot at the time of this transaction. */
|
||||
gnc_lot_get_balance_before (lot, split, &lot_amount, &lot_value);
|
||||
|
||||
pcy->PolicyGetLotOpening (pcy, lot, &opening_amount, &opening_value,
|
||||
&opening_currency);
|
||||
|
||||
@ -803,7 +831,7 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
|
||||
* XXX This should really be a part of a scrub routine that
|
||||
* cleans up the lot, before we get at it!
|
||||
*/
|
||||
if (0 > gnc_numeric_compare (gnc_numeric_abs(opening_amount),
|
||||
if (0 > gnc_numeric_compare (gnc_numeric_abs(lot_amount),
|
||||
gnc_numeric_abs(split->amount)))
|
||||
{
|
||||
GList *n;
|
||||
@ -815,14 +843,14 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
|
||||
PERR ("Malformed Lot \"%s\"! (too thin!) "
|
||||
"opening amt=%s split amt=%s baln=%s",
|
||||
gnc_lot_get_title (lot),
|
||||
gnc_num_dbg_to_string (opening_amount),
|
||||
gnc_num_dbg_to_string (lot_amount),
|
||||
gnc_num_dbg_to_string (split->amount),
|
||||
gnc_num_dbg_to_string (gnc_lot_get_balance(lot)));
|
||||
return;
|
||||
}
|
||||
if ( (gnc_numeric_negative_p(opening_amount) ||
|
||||
if ( (gnc_numeric_negative_p(lot_amount) ||
|
||||
gnc_numeric_positive_p(split->amount)) &&
|
||||
(gnc_numeric_positive_p(opening_amount) ||
|
||||
(gnc_numeric_positive_p(lot_amount) ||
|
||||
gnc_numeric_negative_p(split->amount)))
|
||||
{
|
||||
GList *n;
|
||||
@ -834,7 +862,7 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
|
||||
PERR ("Malformed Lot \"%s\"! (too fat!) "
|
||||
"opening amt=%s split amt=%s baln=%s",
|
||||
gnc_lot_get_title (lot),
|
||||
gnc_num_dbg_to_string (opening_amount),
|
||||
gnc_num_dbg_to_string (lot_amount),
|
||||
gnc_num_dbg_to_string (split->amount),
|
||||
gnc_num_dbg_to_string (gnc_lot_get_balance(lot)));
|
||||
return;
|
||||
@ -847,7 +875,6 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
|
||||
* cost_basis = purchase_price * current_split_amount
|
||||
* cap_gain = current_split_value - cost_basis
|
||||
*/
|
||||
gnc_lot_get_balance_before (lot, split, &lot_amount, &lot_value);
|
||||
/* Fraction of the lot that this split represents: */
|
||||
frac = gnc_numeric_div (split->amount, lot_amount,
|
||||
GNC_DENOM_AUTO,
|
||||
@ -860,8 +887,8 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
|
||||
value = gnc_numeric_sub (value, split->value,
|
||||
GNC_DENOM_AUTO, GNC_HOW_DENOM_FIXED);
|
||||
PINFO ("Open amt=%s val=%s; split amt=%s val=%s; gains=%s\n",
|
||||
gnc_num_dbg_to_string (opening_amount),
|
||||
gnc_num_dbg_to_string (opening_value),
|
||||
gnc_num_dbg_to_string (lot_amount),
|
||||
gnc_num_dbg_to_string (lot_value),
|
||||
gnc_num_dbg_to_string (split->amount),
|
||||
gnc_num_dbg_to_string (split->value),
|
||||
gnc_num_dbg_to_string (value));
|
||||
@ -872,8 +899,8 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
|
||||
"\tOpen amt=%s val=%s\n\tsplit amt=%s val=%s\n\tgains=%s\n",
|
||||
xaccAccountGetName(split->acc),
|
||||
xaccTransGetDescription(split->parent),
|
||||
gnc_num_dbg_to_string (opening_amount),
|
||||
gnc_num_dbg_to_string (opening_value),
|
||||
gnc_num_dbg_to_string (lot_amount),
|
||||
gnc_num_dbg_to_string (lot_value),
|
||||
gnc_num_dbg_to_string (split->amount),
|
||||
gnc_num_dbg_to_string (split->value),
|
||||
gnc_num_dbg_to_string (value));
|
||||
@ -967,7 +994,6 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
|
||||
|
||||
xaccSplitSetAmount (lot_split, zero);
|
||||
xaccSplitSetValue (lot_split, value);
|
||||
gnc_lot_add_split (lot, lot_split);
|
||||
|
||||
value = gnc_numeric_neg (value);
|
||||
xaccSplitSetAmount (gain_split, value);
|
||||
@ -980,6 +1006,10 @@ xaccSplitComputeCapGains(Split *split, Account *gain_acc)
|
||||
lot_split->gains_split = split;
|
||||
gain_split->gains = GAINS_STATUS_GAINS;
|
||||
gain_split->gains_split = split;
|
||||
|
||||
/* Do this last since it may generate an event that will call us
|
||||
recursively. */
|
||||
gnc_lot_add_split (lot, lot_split);
|
||||
|
||||
xaccTransCommitEdit (trans);
|
||||
}
|
||||
|
@ -150,6 +150,13 @@ void xaccAccountSetDefaultGainAccount (Account *acc, Account *gains_acct);
|
||||
*/
|
||||
Split * xaccSplitGetCapGainsSplit (const Split *);
|
||||
|
||||
/** The xaccSplitGetGainsSourceSplit() routine returns the split
|
||||
* that is the source of the cap gains in this split. It returns
|
||||
* NULL if not found. This routine does nothing more than search
|
||||
* for the split recorded in the KVP key "/gains-source"
|
||||
*/
|
||||
Split * xaccSplitGetGainsSourceSplit (const Split *);
|
||||
|
||||
/** The`xaccSplitAssign() routine will take the indicated
|
||||
* split and, if it doesn't already belong to a lot, it will attempt
|
||||
* to assign it to an appropriate lot.
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "Account.h"
|
||||
#include "gnc-lot.h"
|
||||
#include "gnc-lot-p.h"
|
||||
#include "cap-gains.h"
|
||||
#include "Transaction.h"
|
||||
#include "TransactionP.h"
|
||||
|
||||
@ -236,13 +237,23 @@ gnc_lot_get_balance_before (GNCLot *lot, Split *split,
|
||||
|
||||
if (lot && lot->splits)
|
||||
{
|
||||
Transaction *ta, *tb;
|
||||
Split *target;
|
||||
/* If this is a gains split, find the source of the gains and use
|
||||
its transaction for the comparison. Gains splits are in separate
|
||||
transactions that may sort after non-gains transactions. */
|
||||
target = xaccSplitGetGainsSourceSplit (split);
|
||||
if (target == NULL)
|
||||
target = split;
|
||||
tb = xaccSplitGetParent (target);
|
||||
for (node = lot->splits; node; node = node->next)
|
||||
{
|
||||
Split *s = node->data;
|
||||
Transaction *ta, *tb;
|
||||
ta = xaccSplitGetParent (s);
|
||||
tb = xaccSplitGetParent (split);
|
||||
if ((ta == tb && s != split) ||
|
||||
Split *source = xaccSplitGetGainsSourceSplit (s);
|
||||
if (source == NULL)
|
||||
source = s;
|
||||
ta = xaccSplitGetParent (source);
|
||||
if ((ta == tb && source != target) ||
|
||||
xaccTransOrder (ta, tb) < 0)
|
||||
{
|
||||
gnc_numeric tmpval = xaccSplitGetAmount (s);
|
||||
|
Loading…
Reference in New Issue
Block a user