[Gnucash-changes] Chris Shoemaker's (Jul) patch for account-*-balance refactoring and code

Joshua Sled jsled at cvs.gnucash.org
Fri Oct 7 18:40:41 EDT 2005


Log Message:
-----------
Chris Shoemaker's (Jul) patch for account-*-balance refactoring and code format/comment massage.
2005-10-07  Joshua Sled  <jsled at asynchronous.org>

	Patch from Chris Shoemaker <c.shoemaker at cox.net>:
	* src/engine/Account.[ch]: Refactoring of
	account-*-balance(as-of-date) code.
	* src/engine/Account.[ch], src/engine/Group.[ch]:
	Tyop/misspelling correction, formatting cleanup, notes and
	comments.

Tags:
----
gnucash-gnome2-dev

Modified Files:
--------------
    gnucash:
        ChangeLog
    gnucash/src/engine:
        Account.c
        Account.h
        Group.c
        Group.h

Revision Data
-------------
Index: ChangeLog
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/ChangeLog,v
retrieving revision 1.1487.2.313
retrieving revision 1.1487.2.314
diff -LChangeLog -LChangeLog -u -r1.1487.2.313 -r1.1487.2.314
--- ChangeLog
+++ ChangeLog
@@ -1,3 +1,12 @@
+2005-10-07  Joshua Sled  <jsled at asynchronous.org>
+
+	Patch from Chris Shoemaker <c.shoemaker at cox.net>:
+	* src/engine/Account.[ch]: Refactoring of
+	account-*-balance(as-of-date) code.
+	* src/engine/Account.[ch], src/engine/Group.[ch]:
+	Tyop/misspelling correction, formatting cleanup, notes and
+	comments.
+
 2005-10-07  David Hampton  <hampton at employees.org>
 
 	* src/report/report-system/html-style-sheet.scm:
Index: Account.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/Account.c,v
retrieving revision 1.222.4.18
retrieving revision 1.222.4.19
diff -Lsrc/engine/Account.c -Lsrc/engine/Account.c -u -r1.222.4.18 -r1.222.4.19
--- src/engine/Account.c
+++ src/engine/Account.c
@@ -616,6 +616,7 @@
 static gint
 split_sort_func(gconstpointer a, gconstpointer b) {
   /* don't coerce xaccSplitDateOrder so we'll catch changes */
+  /* huh?  what changes? */
   Split *sa = (Split *) a;
   Split *sb = (Split *) b;
   return(xaccSplitDateOrder(sa, sb));
@@ -1045,7 +1046,9 @@
  *                                                                  *
  * Return: int -- non-zero if out of order                          *
 \********************************************************************/
-
+/* CAS: Umm, we say we're checking the split, but we're actually
+   resorting all the splits.  Why not just leave the split out of
+   it? */
 void
 xaccAccountFixSplitDateOrder (Account * acc, Split *split) 
 {
@@ -1667,6 +1670,14 @@
   /* Since transaction post times are stored as a Timespec,
    * convert date into a Timespec as well rather than converting
    * each transaction's Timespec into a time_t.
+   *
+   * FIXME: CAS: I think this comment is a bogus justification for
+   * using xaccTransGetDatePostedTS.  There's no benefit to using
+   * Timespec when the input argument is time_t, and it's hard to
+   * imagine that casting long long to long and comparing two longs is
+   * worse than comparing two long longs every time.  IMO,
+   * xaccAccountGetPresentBalance gets this right, and its algorithm
+   * should be used here.
    */
   ts.tv_sec = date;
   ts.tv_nsec = 0;
@@ -1676,7 +1687,7 @@
   {
     xaccTransGetDatePostedTS( xaccSplitGetParent( (Split *)lp->data ),
                               &trans_ts );
-    if( timespec_cmp( &trans_ts, &ts ) > 0 )
+    if( timespec_cmp( &trans_ts, &ts ) >= 0 )
       found = TRUE;
     else
       lp = lp->next;
@@ -1716,8 +1727,7 @@
   GList *node;
   time_t today;
 
-  if (!account)
-    return gnc_numeric_zero ();
+  g_return_val_if_fail(account, gnc_numeric_zero());
 
   today = gnc_timet_get_today_end();
   for (node = g_list_last (account->splits); node; node = node->prev)
@@ -1757,7 +1767,8 @@
   book = xaccGroupGetBook (xaccAccountGetRoot (account));
   pdb = gnc_pricedb_get_db (book);
 
-  balance = gnc_pricedb_convert_balance_latest_price(pdb, balance, balance_currency, new_currency);
+  balance = gnc_pricedb_convert_balance_latest_price(
+      pdb, balance, balance_currency, new_currency);
 
   return balance;
 }
@@ -1787,7 +1798,8 @@
   ts.tv_sec = date;
   ts.tv_nsec = 0;
 
-  balance = gnc_pricedb_convert_balance_nearest_price(pdb, balance, balance_currency, new_currency, ts);
+  balance = gnc_pricedb_convert_balance_nearest_price(
+      pdb, balance, balance_currency, new_currency, ts);
 
   return balance;
 }
@@ -1807,11 +1819,22 @@
   if (!account || !fn || !report_currency) return gnc_numeric_zero ();
   balance = fn(account);
   balance = xaccAccountConvertBalanceToCurrency(account, balance,
-					     account->commodity,
-					     report_currency);
+                                                account->commodity,
+                                                report_currency);
   return balance;
 }
 
+static gnc_numeric
+xaccAccountGetXxxBalanceAsOfDateInCurrency(Account *account, time_t date,
+                                           xaccGetBalanceAsOfDateFn fn,
+                                           gnc_commodity *report_commodity)
+{
+    g_return_val_if_fail(account && fn && report_commodity,
+                         gnc_numeric_zero());
+    return xaccAccountConvertBalanceToCurrency(
+        account, fn(account, date), account->commodity, report_commodity);
+}
+
 /*
  * Data structure used to pass various arguments into the following fn.
  */
@@ -1820,6 +1843,8 @@
   gnc_commodity *currency;
   gnc_numeric balance;
   xaccGetBalanceFn fn;
+  xaccGetBalanceAsOfDateFn asOfDateFn;
+  time_t date;
 } CurrencyBalance;
 
 
@@ -1842,13 +1867,33 @@
                                  GNC_HOW_RND_ROUND);
   return NULL;
 }
+static gpointer
+xaccAccountBalanceAsOfDateHelper (Account *account, gpointer data)
+{
+    CurrencyBalance *cb = data;
+    gnc_numeric balance;
+
+    g_return_val_if_fail (cb->asOfDateFn && cb->currency, NULL);
+
+    balance = xaccAccountGetXxxBalanceAsOfDateInCurrency (
+        account, cb->date, cb->asOfDateFn, cb->currency);
+    cb->balance = gnc_numeric_add (cb->balance, balance,
+                                   gnc_commodity_get_fraction (cb->currency),
+                                   GNC_HOW_RND_ROUND);
+    return NULL;
+}
+
+
 
 /*
  * Common function that iterates recursively over all accounts below
- * the specified account.  It uses the previous routine to sum up the
- * balances of all its children, and uses the specified function for
- * extracting the balance.  This function may extract the current
- * value, the reconciled value, etc.
+ * the specified account.  It uses xaccAccountBalanceHelper to sum up
+ * the balances of all its children, and uses the specified function
+ * 'fn' for extracting the balance.  This function may extract the
+ * current value, the reconciled value, etc.
+ *
+ * If 'report_commodity' is NULL, just use the account's commodity.
+ * If 'include_children' is FALSE, this function doesn't recurse at all.
  */
 static gnc_numeric
 xaccAccountGetXxxBalanceInCurrencyRecursive (Account *account,
@@ -1862,14 +1907,44 @@
     return gnc_numeric_zero ();
   if (!report_commodity)
     report_commodity = xaccAccountGetCommodity (account);
+
   balance = xaccAccountGetXxxBalanceInCurrency (account, fn, report_commodity);
 
-  /* If needed, sum up the children converting to *this* account's commodity. */
+  /* If needed, sum up the children converting to the *requested*
+     commodity. */
   if (include_children)
   {
-    CurrencyBalance cb = { report_commodity, balance, fn };
+    CurrencyBalance cb = { report_commodity, balance, fn, NULL, 0 };
+
+    xaccGroupForEachAccount (account->children, xaccAccountBalanceHelper,
+                             &cb, TRUE);
+    balance = cb.balance;
+  }
 
-    xaccGroupForEachAccount (account->children, xaccAccountBalanceHelper, &cb, TRUE);
+  return balance;
+}
+
+static gnc_numeric
+xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive (
+    Account *account, time_t date, xaccGetBalanceAsOfDateFn fn,
+    gnc_commodity *report_commodity, gboolean include_children)
+{
+  gnc_numeric balance;
+
+  g_return_val_if_fail(account, gnc_numeric_zero());
+  if (!report_commodity)
+      report_commodity = xaccAccountGetCommodity (account);
+
+  balance = xaccAccountGetXxxBalanceAsOfDateInCurrency(
+      account, date, fn, report_commodity);
+
+  /* If needed, sum up the children converting to the *requested*
+     commodity. */
+  if (include_children) {
+    CurrencyBalance cb = { report_commodity, balance, NULL, fn, date };
+
+    xaccGroupForEachAccount (account->children,
+                             xaccAccountBalanceAsOfDateHelper, &cb, TRUE);
     balance = cb.balance;
   }
 
@@ -1895,9 +1970,9 @@
 					gnc_commodity *report_commodity,
 					gboolean include_children)
 {
-  return
-    xaccAccountGetXxxBalanceInCurrencyRecursive (account, xaccAccountGetClearedBalance,
-						 report_commodity, include_children);
+  return xaccAccountGetXxxBalanceInCurrencyRecursive (
+      account, xaccAccountGetClearedBalance, report_commodity,
+      include_children);
 }
 
 
@@ -1906,9 +1981,9 @@
 				 gnc_commodity *report_commodity,
 				 gboolean include_children)
 {
-  return
-    xaccAccountGetXxxBalanceInCurrencyRecursive (account, xaccAccountGetReconciledBalance,
-						 report_commodity, include_children);
+  return xaccAccountGetXxxBalanceInCurrencyRecursive (
+      account, xaccAccountGetReconciledBalance, report_commodity,
+      include_children);
 }
 
 gnc_numeric
@@ -1916,19 +1991,29 @@
 					gnc_commodity *report_commodity,
 					gboolean include_children)
 {
-  return
-    xaccAccountGetXxxBalanceInCurrencyRecursive (account, xaccAccountGetPresentBalance,
-						 report_commodity, include_children);
+  return xaccAccountGetXxxBalanceInCurrencyRecursive (
+      account, xaccAccountGetPresentBalance, report_commodity,
+      include_children);
 }
 
 gnc_numeric
-xaccAccountGetProjectedMinimumBalanceInCurrency (Account *account,
-						 gnc_commodity *report_commodity,
-						 gboolean include_children)
-{
-  return
-    xaccAccountGetXxxBalanceInCurrencyRecursive (account, xaccAccountGetProjectedMinimumBalance,
-						 report_commodity, include_children);
+xaccAccountGetProjectedMinimumBalanceInCurrency (
+    Account *account, gnc_commodity *report_commodity,
+    gboolean include_children)
+{
+  return xaccAccountGetXxxBalanceInCurrencyRecursive (
+      account, xaccAccountGetProjectedMinimumBalance, report_commodity,
+      include_children);
+}
+
+gnc_numeric
+xaccAccountGetBalanceAsOfDateInCurrency(
+    Account *account, time_t date, gnc_commodity *report_commodity,
+    gboolean include_children)
+{
+    return xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive (
+        account, date, xaccAccountGetBalanceAsOfDate, report_commodity,
+        include_children);
 }
 
 /********************************************************************\
Index: Group.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/Group.c,v
retrieving revision 1.112.4.10
retrieving revision 1.112.4.11
diff -Lsrc/engine/Group.c -Lsrc/engine/Group.c -u -r1.112.4.10 -r1.112.4.11
--- src/engine/Group.c
+++ src/engine/Group.c
@@ -385,7 +385,7 @@
 }
 
 /********************************************************************\
- * Get all of the accounts, including subaccounts                   *
+ * Recursively get all of the accounts, including subaccounts       *
 \********************************************************************/
 
 static void
@@ -756,7 +756,7 @@
           *
           * Note also, we need to reparent the children to the new book as well.
           */
-         PWARN ("reparenting accounts accross books is not correctly supported\n");
+         PWARN ("reparenting accounts across books is not correctly supported\n");
 
          gnc_engine_gen_event (&acc->inst.entity, GNC_EVENT_DESTROY);
          col = qof_book_get_collection (grp->book, GNC_ID_ACCOUNT);
@@ -1008,7 +1008,6 @@
 
 /********************************************************************\
 \********************************************************************/
-
 void
 xaccSplitsBeginStagedTransactionTraversals (GList *splits)
 {
Index: Group.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/Group.h,v
retrieving revision 1.64.4.7
retrieving revision 1.64.4.8
diff -Lsrc/engine/Group.h -Lsrc/engine/Group.h -u -r1.64.4.7 -r1.64.4.8
--- src/engine/Group.h
+++ src/engine/Group.h
@@ -269,19 +269,22 @@
       you are done with it.
 */
 AccountList *xaccGroupMapAccounts(AccountGroup *grp,
-                             AccountCallback,
-                             gpointer data);
+                                  AccountCallback func,
+                                  gpointer data);
 
 /** The xaccGroupForEachAccount() method will traverse the AccountGroup
  *    tree, calling 'func' on each account.   Traversal will stop when
- *    func returns a non-null value, and the routine wil return with that 
- *    value.  If 'deeply' is FALSE, then only the immediate children of 
+ *    func returns a non-null value, and the routine will return with that
+ *    value.  Therefore, this function will return null iff func returns
+ *    null for every account.
+ *
+ *    If 'deeply' is FALSE, then only the immediate children of
  *    the account will be traversed.  If TRUE, then the whole tree will
  *    be traversed.
  */
 
 gpointer xaccGroupForEachAccount (AccountGroup *grp,
-                                  AccountCallback,
+                                  AccountCallback func,
                                   gpointer data,
                                   gboolean deeply);
 
@@ -386,7 +389,7 @@
 
 int xaccAccountStagedTransactionTraversal(Account *a,
                                           unsigned int stage,
-                                          TransactionCallback,
+                                          TransactionCallback thunk,
                                           void *data);
 
 /** Traverse all of the transactions in the given account group.
@@ -412,12 +415,12 @@
 
    Note that this routine is just a trivial wrapper for 
    
-   xaccGroupBeginStagedTransactionTraversals(grp);
-   xaccGroupStagedTransactionTraversal(grp, 42, cb, data);
+   xaccGroupBeginStagedTransactionTraversals(g);
+   xaccGroupStagedTransactionTraversal(g, 42, proc, data);
  */
 
 int xaccGroupForEachTransaction(AccountGroup *g, 
-                                TransactionCallback, void *data);
+                                TransactionCallback proc, void *data);
 
 /** @} */
 #endif /* XACC_ACCOUNT_GROUP_H */
Index: Account.h
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/Account.h,v
retrieving revision 1.110.4.14
retrieving revision 1.110.4.15
diff -Lsrc/engine/Account.h -Lsrc/engine/Account.h -u -r1.110.4.14 -r1.110.4.15
--- src/engine/Account.h
+++ src/engine/Account.h
@@ -49,9 +49,13 @@
 #include "gnc-engine.h"
 
 typedef gnc_numeric (*xaccGetBalanceFn)( Account *account );
-typedef gnc_numeric (*xaccGetBalanceInCurrencyFn) (Account *account,
-						   gnc_commodity *report_commodity,
-						   gboolean include_children);
+
+typedef gnc_numeric (*xaccGetBalanceInCurrencyFn) (
+    Account *account, gnc_commodity *report_commodity,
+    gboolean include_children);
+
+typedef gnc_numeric (*xaccGetBalanceAsOfDateFn) (
+    Account *account, time_t date);
 
 #define GNC_IS_ACCOUNT(obj)  (QOF_CHECK_TYPE((obj), GNC_ID_ACCOUNT))
 #define GNC_ACCOUNT(obj)     (QOF_CHECK_CAST((obj), GNC_ID_ACCOUNT, Account))
@@ -305,7 +309,7 @@
 #define DxaccAccountGetSecurity xaccAccountGetCommodity
 
 /** Return the SCU for the account.  If a non-standard SCU has been
- *   set for the account, that s returned; else the default SCU for 
+ *   set for the account, that is returned; else the default SCU for
  *   the account commodity is returned.
  */
 int  xaccAccountGetCommoditySCU (Account *account);
@@ -335,7 +339,7 @@
 /** @name Account Balance
  @{
 */
-/** Get the current balance of the account */
+/** Get the current balance of the account, which may include future splits */
 gnc_numeric     xaccAccountGetBalance (Account *account);
 /** Get the current balance of the account, only including cleared transactions */
 gnc_numeric     xaccAccountGetClearedBalance (Account *account);
@@ -346,6 +350,15 @@
 /** Get the balance of the account as of the date specified */
 gnc_numeric     xaccAccountGetBalanceAsOfDate (Account *account, time_t date);
 
+/* These two functions convert a given balance from one commodity to
+   another.  The account argument is only used to get the Book, and
+   may have nothing to do with the supplied balance.  Likewise, the
+   date argument is only used for commodity conversion and may have
+   nothing to do with supplied balance.
+
+   Since they really have nothing to do with Accounts, there's
+   probably some better place for them, but where?  gnc-commodity.h?
+*/
 gnc_numeric xaccAccountConvertBalanceToCurrency(Account *account, /* for book */
 						gnc_numeric balance,
 						gnc_commodity *balance_currency,
@@ -356,6 +369,8 @@
 							gnc_commodity *new_currency,
 							time_t date);
 
+/* These functions get some type of balance in the desired commodity.
+   'report_commodity' may be NULL to use the account's commodity. */
 gnc_numeric xaccAccountGetBalanceInCurrency (Account *account,
 					     gnc_commodity *report_commodity,
 					     gboolean include_children);
@@ -371,6 +386,12 @@
 gnc_numeric xaccAccountGetProjectedMinimumBalanceInCurrency (Account *account,
 							     gnc_commodity *report_commodity,
 							     gboolean include_children);
+
+/* This function gets the balance as of the given date in the desired
+   commodity. */
+gnc_numeric xaccAccountGetBalanceAsOfDateInCurrency(
+    Account *account, time_t date, gnc_commodity *report_commodity,
+    gboolean include_children);
 /** @} */
 
 /** @name Account Children and Parents. 
@@ -405,7 +426,7 @@
 
 /** This routine returns a flat list of all of the accounts
  * that are descendents of this account.  This includes not
- * only the the children, but the cheldren of the children, etc.
+ * only the the children, but the children of the children, etc.
  * This routine is equivalent to the nested calls
  * xaccGroupGetSubAccounts (xaccAccountGetChildren())
  *
@@ -640,7 +661,12 @@
 /** DOCUMENT ME! */
 void            xaccAccountSetPlaceholder (Account *account,
                                            gboolean option);
-/** DOCUMENT ME! */
+
+/** Returns PLACEHOLDER_NONE if account is NULL or neither account nor
+ *  any descendent of account is a placeholder.  If account is a
+ *  placeholder, returns PLACEHOLDER_THIS.  Otherwise, if any
+ *  descendant of account is a placeholder, return PLACEHOLDER_CHILD.
+ */
 GNCPlaceholderType xaccAccountGetDescendantPlaceholder (Account *account);
 /** @} */
 


More information about the gnucash-changes mailing list