[Gnucash-changes] r13887 - gnucash/trunk - Patch from Mike Alexander's to handle multiple lot dispositions on the

David Hampton hampton at cvs.gnucash.org
Sat Apr 29 23:52:07 EDT 2006


Author: hampton
Date: 2006-04-29 23:52:05 -0400 (Sat, 29 Apr 2006)
New Revision: 13887
Trac: http://svn.gnucash.org/trac/changeset/13887

Modified:
   gnucash/trunk/ChangeLog
   gnucash/trunk/src/engine/cap-gains.c
   gnucash/trunk/src/engine/cap-gains.h
   gnucash/trunk/src/engine/gnc-lot.c
Log:
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.


Modified: gnucash/trunk/ChangeLog
===================================================================
--- gnucash/trunk/ChangeLog	2006-04-30 02:59:58 UTC (rev 13886)
+++ gnucash/trunk/ChangeLog	2006-04-30 03:52:05 UTC (rev 13887)
@@ -1,5 +1,14 @@
 2006-04-29  David Hampton  <hampton at 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

Modified: gnucash/trunk/src/engine/cap-gains.c
===================================================================
--- gnucash/trunk/src/engine/cap-gains.c	2006-04-30 02:59:58 UTC (rev 13886)
+++ gnucash/trunk/src/engine/cap-gains.c	2006-04-30 03:52:05 UTC (rev 13887)
@@ -141,6 +141,8 @@
    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 @@
 
 /* ============================================================== */
 
+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 @@
     * '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 @@
     * 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 @@
       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 @@
       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 @@
     * 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 @@
    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 @@
             "\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 @@
 
       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 @@
       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);
    }

Modified: gnucash/trunk/src/engine/cap-gains.h
===================================================================
--- gnucash/trunk/src/engine/cap-gains.h	2006-04-30 02:59:58 UTC (rev 13886)
+++ gnucash/trunk/src/engine/cap-gains.h	2006-04-30 03:52:05 UTC (rev 13887)
@@ -150,6 +150,13 @@
  */                                       
 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.

Modified: gnucash/trunk/src/engine/gnc-lot.c
===================================================================
--- gnucash/trunk/src/engine/gnc-lot.c	2006-04-30 02:59:58 UTC (rev 13886)
+++ gnucash/trunk/src/engine/gnc-lot.c	2006-04-30 03:52:05 UTC (rev 13887)
@@ -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 @@
    
    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);



More information about the gnucash-changes mailing list