[patch 4/4] several changes to Account and Group
c.shoemaker at cox.net
c.shoemaker at cox.net
Fri Jul 22 14:16:32 EDT 2005
- [N.B.] a change to the time comparision from > to >= in
xaccAccountGetBalanceAsOfDate()
- increase use of glib
- line wrap fixes
- introduce xaccAccountGetXxxBalanceAsOfDateInCurrency() as a
natural extension of similar functions
- comment fixups
Account.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++--------------
Account.h | 40 +++++++++++++---
Group.c | 5 --
Group.h | 21 ++++----
4 files changed, 165 insertions(+), 53 deletions(-)
Index: gnucash/src/engine/Account.c
===================================================================
--- gnucash.orig/src/engine/Account.c
+++ gnucash/src/engine/Account.c
@@ -633,6 +633,7 @@ xaccAccountEqual(Account *aa, Account *a
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));
@@ -1062,7 +1063,9 @@ xaccAccountSetStartingBalance(Account *a
* *
* 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)
{
@@ -1684,6 +1687,14 @@ xaccAccountGetBalanceAsOfDate (Account *
/* 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;
@@ -1693,7 +1704,7 @@ xaccAccountGetBalanceAsOfDate (Account *
{
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;
@@ -1733,8 +1744,7 @@ xaccAccountGetPresentBalance (Account *a
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)
@@ -1774,7 +1784,8 @@ xaccAccountConvertBalanceToCurrency(Acco
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;
}
@@ -1804,7 +1815,8 @@ xaccAccountConvertBalanceToCurrencyAsOfD
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;
}
@@ -1824,11 +1836,22 @@ xaccAccountGetXxxBalanceInCurrency (Acco
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.
*/
@@ -1837,6 +1860,8 @@ typedef struct
gnc_commodity *currency;
gnc_numeric balance;
xaccGetBalanceFn fn;
+ xaccGetBalanceAsOfDateFn asOfDateFn;
+ time_t date;
} CurrencyBalance;
@@ -1859,13 +1884,33 @@ xaccAccountBalanceHelper (Account *accou
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,
@@ -1879,14 +1924,44 @@ xaccAccountGetXxxBalanceInCurrencyRecurs
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);
+ xaccGroupForEachAccount (account->children, xaccAccountBalanceHelper,
+ &cb, TRUE);
+ balance = cb.balance;
+ }
+
+ 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;
}
@@ -1899,9 +1974,8 @@ xaccAccountGetBalanceInCurrency (Account
gboolean include_children)
{
gnc_numeric rc;
- rc = xaccAccountGetXxxBalanceInCurrencyRecursive (account,
- xaccAccountGetBalance,
- report_commodity, include_children);
+ rc = xaccAccountGetXxxBalanceInCurrencyRecursive (
+ account, xaccAccountGetBalance, report_commodity, include_children);
PINFO (" baln=%lld/%lld", rc.num, rc.denom);
return rc;
}
@@ -1912,9 +1986,9 @@ xaccAccountGetClearedBalanceInCurrency (
gnc_commodity *report_commodity,
gboolean include_children)
{
- return
- xaccAccountGetXxxBalanceInCurrencyRecursive (account, xaccAccountGetClearedBalance,
- report_commodity, include_children);
+ return xaccAccountGetXxxBalanceInCurrencyRecursive (
+ account, xaccAccountGetClearedBalance, report_commodity,
+ include_children);
}
@@ -1923,9 +1997,9 @@ xaccAccountGetReconciledBalanceInCurrenc
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
@@ -1933,19 +2007,29 @@ xaccAccountGetPresentBalanceInCurrency (
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);
}
gnc_numeric
-xaccAccountGetProjectedMinimumBalanceInCurrency (Account *account,
- gnc_commodity *report_commodity,
- gboolean include_children)
-{
- return
- xaccAccountGetXxxBalanceInCurrencyRecursive (account, xaccAccountGetProjectedMinimumBalance,
- report_commodity, include_children);
+xaccAccountGetBalanceAsOfDateInCurrency(
+ Account *account, time_t date, gnc_commodity *report_commodity,
+ gboolean include_children)
+{
+ return xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive (
+ account, date, xaccAccountGetBalanceAsOfDate, report_commodity,
+ include_children);
}
/********************************************************************\
Index: gnucash/src/engine/Account.h
===================================================================
--- gnucash.orig/src/engine/Account.h
+++ gnucash/src/engine/Account.h
@@ -55,9 +55,13 @@
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))
@@ -311,7 +315,7 @@ gnc_commodity * xaccAccountGetCommodity
#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);
@@ -341,7 +345,7 @@ gboolean xaccAccountGetNonStdSCU (Accou
/** @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);
@@ -352,6 +356,15 @@ gnc_numeric xaccAccountGetProjectedM
/** 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,
@@ -362,6 +375,8 @@ gnc_numeric xaccAccountConvertBalanceToC
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);
@@ -377,6 +392,12 @@ gnc_numeric xaccAccountGetPresentBalance
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.
@@ -411,7 +432,7 @@ Account * xaccAccountGetParentAccou
/** 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())
*
@@ -646,7 +667,12 @@ gboolean xaccAccountGetPlaceholde
/** 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);
/** @} */
Index: gnucash/src/engine/Group.c
===================================================================
--- gnucash.orig/src/engine/Group.c
+++ gnucash/src/engine/Group.c
@@ -394,7 +394,7 @@ xaccGroupGetNumSubAccounts (AccountGroup
}
/********************************************************************\
- * Get all of the accounts, including subaccounts *
+ * Recursively get all of the accounts, including subaccounts *
\********************************************************************/
static void
@@ -765,7 +765,7 @@ xaccGroupInsertAccount (AccountGroup *gr
*
* 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);
@@ -1017,7 +1017,6 @@ xaccGroupGetDepth (AccountGroup *grp)
/********************************************************************\
\********************************************************************/
-
void
xaccSplitsBeginStagedTransactionTraversals (GList *splits)
{
Index: gnucash/src/engine/Group.h
===================================================================
--- gnucash.orig/src/engine/Group.h
+++ gnucash/src/engine/Group.h
@@ -273,19 +273,22 @@ typedef gpointer (*AccountCallback)(Acc
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);
@@ -390,7 +393,7 @@ int xaccGroupStagedTransactionTraversal(
int xaccAccountStagedTransactionTraversal(Account *a,
unsigned int stage,
- TransactionCallback,
+ TransactionCallback thunk,
void *data);
/** Traverse all of the transactions in the given account group.
@@ -416,12 +419,12 @@ int xaccAccountStagedTransactionTraversa
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 */
--
More information about the gnucash-patches
mailing list