[Gnucash-changes] r13872 - gnucash/trunk - Mike Alexander's patch to fix lot date calculation, and to include all

David Hampton hampton at cvs.gnucash.org
Fri Apr 28 17:11:02 EDT 2006


Author: hampton
Date: 2006-04-28 17:11:01 -0400 (Fri, 28 Apr 2006)
New Revision: 13872
Trac: http://svn.gnucash.org/trac/changeset/13872

Modified:
   gnucash/trunk/AUTHORS
   gnucash/trunk/ChangeLog
   gnucash/trunk/src/engine/Scrub2.c
   gnucash/trunk/src/engine/Transaction.c
   gnucash/trunk/src/engine/cap-gains.c
   gnucash/trunk/src/engine/gnc-lot.c
   gnucash/trunk/src/engine/gnc-lot.h
   gnucash/trunk/src/gnome/gnc-plugin-page-account-tree.c
   gnucash/trunk/src/gnome/window-reconcile.c
Log:
Mike Alexander's patch to fix lot date calculation, and to include all
splits when computing capital gain's instead of just the opening lot.
Scrub lots when scrubbing everything else.  Some MacOs X fixes.


Modified: gnucash/trunk/AUTHORS
===================================================================
--- gnucash/trunk/AUTHORS	2006-04-28 20:46:55 UTC (rev 13871)
+++ gnucash/trunk/AUTHORS	2006-04-28 21:11:01 UTC (rev 13872)
@@ -91,6 +91,7 @@
 ----------------
 (In alphabetical order)
 
+Mike Alexander <mta at umich.edu> Cap gains, lot and MacOS fixes.
 Andrew Arensburger <arensb at cfar.umd.edu> for FreeBSD & other patches
 Matt Armstrong <matt_armstrong at bigfoot.com> for misc fixes
 A. Alper Atici <alper_atici at yahoo.com> Turkish translation

Modified: gnucash/trunk/ChangeLog
===================================================================
--- gnucash/trunk/ChangeLog	2006-04-28 20:46:55 UTC (rev 13871)
+++ gnucash/trunk/ChangeLog	2006-04-28 21:11:01 UTC (rev 13872)
@@ -1,5 +1,15 @@
 2006-04-28  David Hampton  <hampton at employees.org>
 
+	* src/gnome/window-reconcile.c:
+	* src/gnome/gnc-plugin-page-account-tree.c:
+	* src/engine/gnc-lot.[ch]:
+	* src/engine/Transaction.c:
+	* src/engine/Scrub2.c:
+	* src/engine/cap-gains.c: Mike Alexander's patch to fix lot date
+	calculation, and to include all splits when computing capital
+	gain's instead of just the opening lot.  Scrub lots when scrubbing
+	everything else.  Some MacOs X fixes.
+
 	* src/gnome/gnc-plugin-basic-commands.c: Finishing all pending
 	transactions before new and open commands, not just save commands.
 	Fixes #334090.

Modified: gnucash/trunk/src/engine/Scrub2.c
===================================================================
--- gnucash/trunk/src/engine/Scrub2.c	2006-04-28 20:46:55 UTC (rev 13871)
+++ gnucash/trunk/src/engine/Scrub2.c	2006-04-28 21:11:01 UTC (rev 13872)
@@ -413,6 +413,7 @@
       Split *s = node->data;
       if (xaccSplitGetLot (s) != lot) continue;
       if (s == split) continue;
+      if (s->inst.do_free) continue;
 
       /* OK, this split is in the same lot (and thus same account)
        * as the indicated split.  It must be a subsplit (although

Modified: gnucash/trunk/src/engine/Transaction.c
===================================================================
--- gnucash/trunk/src/engine/Transaction.c	2006-04-28 20:46:55 UTC (rev 13871)
+++ gnucash/trunk/src/engine/Transaction.c	2006-04-28 21:11:01 UTC (rev 13872)
@@ -1014,6 +1014,8 @@
     */
    if (!(trans->inst.do_free) && scrub_data && 
        !qof_book_shutting_down(xaccTransGetBook(trans))) {
+     /* If scrubbing gains recurses through here, don't call it again. */
+     scrub_data = 0; 
      /* The total value of the transaction should sum to zero. 
       * Call the trans scrub routine to fix it.   Indirectly, this 
       * routine also performs a number of other transaction fixes too.
@@ -1021,6 +1023,8 @@
      xaccTransScrubImbalance (trans, NULL, NULL);
      /* Get the cap gains into a consistent state as well. */
      xaccTransScrubGains (trans, NULL);
+     /* Allow scrubbing in transaction commit again */
+     scrub_data = 1;
    }
 
    /* Record the time of last modification */

Modified: gnucash/trunk/src/engine/cap-gains.c
===================================================================
--- gnucash/trunk/src/engine/cap-gains.c	2006-04-28 20:46:55 UTC (rev 13871)
+++ gnucash/trunk/src/engine/cap-gains.c	2006-04-28 21:11:01 UTC (rev 13872)
@@ -86,6 +86,9 @@
 
    if (!acc) return FALSE;
 
+   if (xaccAccountIsPriced (acc))
+      return TRUE;
+      
    acc_comm = acc->commodity;
 
    for (node=acc->splits; node; node=node->next)
@@ -158,7 +161,7 @@
 static inline GNCLot *
 xaccAccountFindOpenLot (Account *acc, gnc_numeric sign, 
    gnc_commodity *currency,
-   gint64 guess,
+   guint64 guess,
    gboolean (*date_pred)(Timespec, Timespec))
 {
    struct find_lot_s es;
@@ -184,7 +187,7 @@
    ENTER (" sign=%" G_GINT64_FORMAT "/%" G_GINT64_FORMAT, sign.num, sign.denom);
       
    lot = xaccAccountFindOpenLot (acc, sign, currency,
-                   G_GINT64_CONSTANT(2^31) * G_GINT64_CONSTANT(2^31), earliest_pred);
+                   G_MAXUINT64, earliest_pred);
    LEAVE ("found lot=%p %s baln=%s", lot, gnc_lot_get_title (lot),
                gnc_num_dbg_to_string(gnc_lot_get_balance(lot)));
    return lot;
@@ -199,8 +202,7 @@
 	  sign.num, sign.denom);
       
    lot = xaccAccountFindOpenLot (acc, sign, currency,
-                   G_GINT64_CONSTANT(-2^31) * G_GINT64_CONSTANT(2^31),
-		   latest_pred);
+                   0, latest_pred);
    LEAVE ("found lot=%p %s", lot, gnc_lot_get_title (lot));
    return lot;
 }
@@ -588,12 +590,17 @@
    GNCPolicy *pcy;
 
    if (!split) return FALSE;
+   
+   /* If this split already belongs to a lot or the account doesn't 
+    * have lots, we are done. 
+    */
+   if (split->lot) return FALSE;
+   acc = split->acc;
+   if (!xaccAccountHasTrades (acc))
+     return FALSE;
 
    ENTER ("(split=%p)", split);
 
-   /* If this split already belongs to a lot, we are done. */
-   if (split->lot) return FALSE;
-   acc = split->acc;
    pcy = acc->policy;
    xaccAccountBeginEdit (acc);
 
@@ -657,6 +664,7 @@
    gnc_numeric value = zero;
    gnc_numeric frac;
    gnc_numeric opening_amount, opening_value;
+   gnc_numeric lot_amount, lot_value;
    gnc_commodity *opening_currency;
 
    if (!split) return;
@@ -705,9 +713,15 @@
       return;
    }
 
+   if (safe_strcmp ("stock-split", xaccSplitGetType (split)) == 0)
+   {
+      LEAVE ("Stock split split, returning.");
+      return;
+   }
+   
    if (GAINS_STATUS_GAINS & split->gains)
    {
-		Split *s;
+      Split *s;
       PINFO ("split is a gains recording split, switch over");
       /* If this is the split that records the gains, then work with 
        * the split that generates the gains. 
@@ -730,7 +744,7 @@
          xaccTransDestroy (trans);
 #endif
       }
-		split = s;
+      split = s;
    }
 
    /* Note: if the value of the 'opening' split(s) has changed,
@@ -826,19 +840,23 @@
       return;
    }
 
-   /* The cap gains is the difference between the value of the
-    * opening split, and the current split, pro-rated for an equal
+   /* The cap gains is the difference between the basis prior to the
+    * current split, and the current split, pro-rated for an equal
     * amount of shares. 
-    * i.e. purchase_price = opening_value / opening_amount 
-    * cost_basis = purchase_price * current_amount
-    * cap_gain = current_value - cost_basis 
+    * i.e. purchase_price = lot_value / lot_amount 
+    * cost_basis = purchase_price * current_split_amount
+    * cap_gain = current_split_value - cost_basis 
     */
-   frac = gnc_numeric_div (split->amount, opening_amount, 
+   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, 
                             GNC_HOW_DENOM_REDUCE);
-   value = gnc_numeric_mul (frac, opening_value, 
+   /* Basis for this split: */
+   value = gnc_numeric_mul (frac, lot_value, 
                             gnc_numeric_denom(opening_value), 
                             GNC_HOW_DENOM_EXACT|GNC_HOW_RND_ROUND);
+   /* Capital gain for this split: */
    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",
@@ -1124,7 +1142,10 @@
       {
          gboolean altered = FALSE;
          split->gains |= ~GAINS_STATUS_ADIRTY;
-         if (split->lot) altered = xaccScrubLot (split->lot);
+         if (split->lot) 
+           altered = xaccScrubLot (split->lot);
+         else
+           altered = xaccSplitAssign (split);
          if (altered) goto restart;
       }
    }

Modified: gnucash/trunk/src/engine/gnc-lot.c
===================================================================
--- gnucash/trunk/src/engine/gnc-lot.c	2006-04-28 20:46:55 UTC (rev 13871)
+++ gnucash/trunk/src/engine/gnc-lot.c	2006-04-28 21:11:01 UTC (rev 13872)
@@ -226,6 +226,40 @@
 /* ============================================================= */
 
 void
+gnc_lot_get_balance_before (GNCLot *lot, Split *split,
+                            gnc_numeric *amount, gnc_numeric *value)
+{
+   GList *node;
+   gnc_numeric zero = gnc_numeric_zero();
+   gnc_numeric amt = zero;
+   gnc_numeric val = zero;
+   
+   if (lot && lot->splits)
+   {
+      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) ||
+             xaccTransOrder (ta, tb) < 0)
+         {
+            gnc_numeric tmpval = xaccSplitGetAmount (s);
+            amt = gnc_numeric_add_fixed (amt, tmpval);
+            tmpval = xaccSplitGetValue (s);
+            val = gnc_numeric_add_fixed (val, tmpval);
+         }
+      }
+   }
+
+   *amount = amt;
+   *value = val;
+}
+               
+/* ============================================================= */
+
+void
 gnc_lot_add_split (GNCLot *lot, Split *split)
 {
    Account * acc;
@@ -294,7 +328,7 @@
    Timespec ts;
    Split *earliest = NULL;
 
-   ts.tv_sec = ((long long) LONG_MAX);
+   ts.tv_sec = ((long long) ULONG_MAX);
    ts.tv_nsec = 0;
    if (!lot) return NULL;
 
@@ -323,7 +357,7 @@
    Timespec ts;
    Split *latest = NULL;
 
-   ts.tv_sec = -((long long) LONG_MAX);
+   ts.tv_sec = 0;
    ts.tv_nsec = 0;
    if (!lot) return NULL;
 

Modified: gnucash/trunk/src/engine/gnc-lot.h
===================================================================
--- gnucash/trunk/src/engine/gnc-lot.h	2006-04-28 20:46:55 UTC (rev 13871)
+++ gnucash/trunk/src/engine/gnc-lot.h	2006-04-28 21:11:01 UTC (rev 13872)
@@ -97,6 +97,13 @@
  *    of the account. */
 gnc_numeric gnc_lot_get_balance (GNCLot *);
 
+/** The gnc_lot_get_balance_before routines computes both the balance and
+ *  value in the lot considering only splits in transactions prior to the
+ *  one containing the given split or other splits in the same transaction.
+ *  The first return value is the amount and the second is the value. */
+void gnc_lot_get_balance_before (GNCLot *, Split *,
+                                 gnc_numeric *, gnc_numeric *);
+
 /** The gnc_lot_is_closed() routine returns a boolean flag: is this 
  *    lot closed?  A lot is closed if its balance is zero.  This 
  *    routine is faster than using gnc_lot_get_balance() because

Modified: gnucash/trunk/src/gnome/gnc-plugin-page-account-tree.c
===================================================================
--- gnucash/trunk/src/gnome/gnc-plugin-page-account-tree.c	2006-04-28 20:46:55 UTC (rev 13871)
+++ gnucash/trunk/src/gnome/gnc-plugin-page-account-tree.c	2006-04-28 21:11:01 UTC (rev 13872)
@@ -43,6 +43,7 @@
 #include "gnc-plugin-page-register.h"
 
 #include "Scrub.h"
+#include "Scrub3.h"
 #include "Transaction.h"
 #include "dialog-account.h"
 #include "dialog-transfer.h"
@@ -1198,6 +1199,8 @@
 	xaccAccountScrubOrphans (account);
 	xaccAccountScrubImbalance (account);
 
+	xaccAccountScrubLots (account);
+
 	gnc_resume_gui_refresh ();
 }
 
@@ -1213,6 +1216,8 @@
 	xaccAccountTreeScrubOrphans (account);
 	xaccAccountTreeScrubImbalance (account);
 
+	xaccAccountTreeScrubLots (account);
+
 	gnc_resume_gui_refresh ();
 }
 
@@ -1225,6 +1230,10 @@
 
 	xaccGroupScrubOrphans (group);
 	xaccGroupScrubImbalance (group);
+
+	xaccGroupScrubLots (group);
+
+	gnc_resume_gui_refresh ();
 }
 
 /** @} */

Modified: gnucash/trunk/src/gnome/window-reconcile.c
===================================================================
--- gnucash/trunk/src/gnome/window-reconcile.c	2006-04-28 20:46:55 UTC (rev 13871)
+++ gnucash/trunk/src/gnome/window-reconcile.c	2006-04-28 21:11:01 UTC (rev 13872)
@@ -37,6 +37,7 @@
 #include <glib/gi18n.h>
 
 #include "Scrub.h"
+#include "Scrub3.h"
 #include "dialog-account.h"
 #include "dialog-transfer.h"
 #include "dialog-utils.h"
@@ -1229,6 +1230,8 @@
   xaccAccountTreeScrubOrphans (account);
   xaccAccountTreeScrubImbalance (account);
 
+  xaccAccountTreeScrubLots (account);
+
   gnc_resume_gui_refresh ();
 }
 



More information about the gnucash-changes mailing list