[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