r21182 - gnucash/trunk/src - Implement a balance for owners and show it on the owners view page
Geert Janssens
gjanssens at code.gnucash.org
Sat Aug 13 11:33:42 EDT 2011
Author: gjanssens
Date: 2011-08-13 11:33:42 -0400 (Sat, 13 Aug 2011)
New Revision: 21182
Trac: http://svn.gnucash.org/trac/changeset/21182
Modified:
gnucash/trunk/src/app-utils/gnc-ui-util.c
gnucash/trunk/src/app-utils/gnc-ui-util.h
gnucash/trunk/src/engine/gncOwner.c
gnucash/trunk/src/engine/gncOwner.h
gnucash/trunk/src/gnome-utils/gnc-tree-model-owner.c
gnucash/trunk/src/gnome-utils/gnc-tree-model-owner.h
gnucash/trunk/src/gnome-utils/gnc-tree-view-owner.c
Log:
Implement a balance for owners and show it on the owners view page
The Balance column is not visible by default, but can be activated
with the blue arrow in the top-right of the page.
Modified: gnucash/trunk/src/app-utils/gnc-ui-util.c
===================================================================
--- gnucash/trunk/src/app-utils/gnc-ui-util.c 2011-08-13 15:33:27 UTC (rev 21181)
+++ gnucash/trunk/src/app-utils/gnc-ui-util.c 2011-08-13 15:33:42 UTC (rev 21182)
@@ -455,6 +455,94 @@
return balance;
}
+/*
+ * This is a wrapper routine around an gncOwnerGetBalanceInCurrency
+ * function that handles additional needs of the gui.
+ *
+ * @param owner The owner to retrieve data about.
+ * @param negative An indication of whether or not the returned value
+ * is negative. This can be used by the caller to
+ * easily decode whether or not to color the output.
+ * @param commodity The commodity in which the account balance should
+ * be returned. If NULL, the value will be returned in
+ * the commodity of the owner. This is normally used
+ * to specify a currency, which forces the conversion
+ * of things like stock account values from share
+ * values to an amount the requested currency.
+ */
+gnc_numeric
+gnc_ui_owner_get_balance_full (GncOwner *owner,
+ gboolean *negative,
+ const gnc_commodity *commodity)
+{
+ gnc_numeric balance;
+
+ if (!owner)
+ return gnc_numeric_zero ();
+
+ balance = gncOwnerGetBalanceInCurrency (owner, commodity);
+
+ /* reverse sign if needed */
+ if ((gncOwnerGetType (owner) == GNC_OWNER_CUSTOMER))
+ balance = gnc_numeric_neg (balance);
+
+ /* Record whether the balance is negative. */
+ if (negative)
+ *negative = gnc_numeric_negative_p (balance);
+
+ return balance;
+}
+
+
+/**
+ * Wrapper around gnc_ui_owner_get_balance_full that converts
+ * the resulting number to a character string. The number is
+ * formatted according to the specification of the owner currency.
+ * The caller is responsible for g_free'ing the returned memory.
+ *
+ * @param owner The owner to retrieve data about.
+ * @param negative An indication of whether or not the returned value
+ * is negative. This can be used by the caller to
+ * easily decode whether or not to color the output.
+ */
+gchar *
+gnc_ui_owner_get_print_balance (GncOwner *owner,
+ gboolean *negative)
+{
+ gnc_numeric balance;
+ GNCPrintAmountInfo print_info;
+
+ balance = gnc_ui_owner_get_balance_full (owner, negative, NULL);
+ print_info = gnc_commodity_print_info (gncOwnerGetCurrency (owner), TRUE);
+ return g_strdup (xaccPrintAmount (balance, print_info));
+}
+
+/**
+ * Wrapper around gnc_ui_owner_get_balance_full that converts
+ * the resulting number to a character string. The number is
+ * formatted according to the specification of the default reporting
+ * currency.
+ *
+ * @param account The owner to retrieve data about.
+ * @param negative An indication of whether or not the returned value
+ * is negative. This can be used by the caller to
+ * easily decode whether or not to color the output.
+ */
+gchar *
+gnc_ui_owner_get_print_report_balance (GncOwner *owner,
+ gboolean *negative)
+{
+ GNCPrintAmountInfo print_info;
+ gnc_numeric balance;
+ gnc_commodity *report_commodity;
+
+ report_commodity = gnc_default_report_currency ();
+ balance = gnc_ui_owner_get_balance_full (owner, negative,
+ report_commodity);
+ print_info = gnc_commodity_print_info (report_commodity, TRUE);
+ return g_strdup (xaccPrintAmount (balance, print_info));
+}
+
/* Caller is responsible for g_free'ing returned memory */
char *
gnc_ui_account_get_tax_info_string (const Account *account)
Modified: gnucash/trunk/src/app-utils/gnc-ui-util.h
===================================================================
--- gnucash/trunk/src/app-utils/gnc-ui-util.h 2011-08-13 15:33:27 UTC (rev 21181)
+++ gnucash/trunk/src/app-utils/gnc-ui-util.h 2011-08-13 15:33:42 UTC (rev 21182)
@@ -36,6 +36,7 @@
#include <locale.h>
#include "Account.h"
+#include "gncOwner.h"
#include "qof.h"
@@ -175,6 +176,33 @@
gboolean recurse,
gboolean *negative);
+/** Get the balance for the underlying owner object.
+ * The returned value is always positive,
+ * intended to be displayed to a user. However the real sign
+ * of the balance is indicated via the "negative" parameter.
+ */
+gnc_numeric gnc_ui_owner_get_balance_full (GncOwner *owner,
+ gboolean *negative,
+ const gnc_commodity *commodity);
+
+/** Get the balance for the underlying owner object in string format
+ * and the owner's native currency.
+ * The returned value is always positive,
+ * intended to be displayed to a user. However the real sign
+ * of the balance is indicated via the "negative" parameter.
+ */
+gchar * gnc_ui_owner_get_print_balance (GncOwner *owner,
+ gboolean *negative);
+
+/** Get the balance for the underlying owner object in string format
+ * and in the default report currency.
+ * The returned value is always positive,
+ * intended to be displayed to a user. However the real sign
+ * of the balance is indicated via the "negative" parameter.
+ */
+gchar * gnc_ui_owner_get_print_report_balance (GncOwner *owner,
+ gboolean *negative);
+
char *gnc_ui_account_get_tax_info_string (const Account *account);
char *gnc_ui_account_get_tax_info_sub_acct_string (const Account *account);
Modified: gnucash/trunk/src/engine/gncOwner.c
===================================================================
--- gnucash/trunk/src/engine/gncOwner.c 2011-08-13 15:33:27 UTC (rev 21181)
+++ gnucash/trunk/src/engine/gncOwner.c 2011-08-13 15:33:42 UTC (rev 21182)
@@ -1006,6 +1006,69 @@
return (g_list_prepend (NULL, gncOwnerGetCurrency(owner)));
}
+/*********************************************************************/
+/* Owner balance calculation routines */
+
+/*
+ * Given an owner, extract the open balance from the owner and then
+ * convert it to the desired currency.
+ */
+gnc_numeric
+gncOwnerGetBalanceInCurrency (GncOwner *owner,
+ const gnc_commodity *report_currency)
+{
+ gnc_numeric balance = gnc_numeric_zero ();
+ GList *acct_list, *acct_node, *acct_types, *lot_list = NULL, *lot_node;
+ QofBook *book;
+ gnc_commodity *owner_currency;
+ GNCPriceDB *pdb;
+
+ g_return_val_if_fail (owner, gnc_numeric_zero ());
+
+ /* Get account list */
+ book = qof_instance_get_book (qofOwnerGetOwner (owner));
+ acct_list = gnc_account_get_descendants (gnc_book_get_root_account (book));
+ acct_types = gncOwnerGetAccountTypesList (owner);
+ owner_currency = gncOwnerGetCurrency (owner);
+
+ /* For each account */
+ for (acct_node = acct_list; acct_node; acct_node = acct_node->next)
+ {
+ Account *account = acct_node->data;
+
+ /* Check if this account can have lots for the owner, otherwise skip to next */
+ if (g_list_index (acct_types, (gpointer)xaccAccountGetType (account))
+ == -1)
+ continue;
+
+
+ if (!gnc_commodity_equal (owner_currency, xaccAccountGetCommodity (account)))
+ continue;
+
+ /* Get a list of open lots for this owner and account */
+ lot_list = xaccAccountFindOpenLots (account, gnc_lot_match_invoice_owner,
+ owner,
+ (GCompareFunc)gnc_lot_sort_func);
+ /* For each lot */
+ for (lot_node = lot_list; lot_node; lot_node = lot_node->next)
+ {
+ GNCLot *lot = lot_node->data;
+ gnc_numeric lot_balance = gnc_lot_get_balance (lot);
+ balance = gnc_numeric_add (balance, lot_balance,
+ gnc_commodity_get_fraction (owner_currency), GNC_HOW_RND_ROUND_HALF_UP);
+ }
+ }
+
+ pdb = gnc_pricedb_get_db (book);
+
+ if (report_currency)
+ balance = gnc_pricedb_convert_balance_latest_price (
+ pdb, balance, owner_currency, report_currency);
+
+ return balance;
+}
+
+
/* XXX: Yea, this is broken, but it should work fine for Queries.
* We're single-threaded, right?
*/
Modified: gnucash/trunk/src/engine/gncOwner.h
===================================================================
--- gnucash/trunk/src/engine/gncOwner.h 2011-08-13 15:33:27 UTC (rev 21181)
+++ gnucash/trunk/src/engine/gncOwner.h 2011-08-13 15:33:42 UTC (rev 21182)
@@ -192,6 +192,14 @@
/** Returns a GList of currencies associated with the owner */
GList * gncOwnerGetCommoditiesList (const GncOwner *owner);
+
+/** Given an owner, extract the open balance from the owner and then
+ * convert it to the desired currency.
+ */
+gnc_numeric
+gncOwnerGetBalanceInCurrency (GncOwner *owner,
+ const gnc_commodity *report_currency);
+
#define OWNER_TYPE "type"
#define OWNER_TYPE_STRING "type-string" /**< Allows the type to be handled externally. */
#define OWNER_CUSTOMER "customer"
Modified: gnucash/trunk/src/gnome-utils/gnc-tree-model-owner.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-tree-model-owner.c 2011-08-13 15:33:27 UTC (rev 21181)
+++ gnucash/trunk/src/gnome-utils/gnc-tree-model-owner.c 2011-08-13 15:33:42 UTC (rev 21182)
@@ -405,11 +405,9 @@
case GNC_TREE_MODEL_OWNER_COL_EMAIL:
case GNC_TREE_MODEL_OWNER_COL_BALANCE:
case GNC_TREE_MODEL_OWNER_COL_BALANCE_REPORT:
- case GNC_TREE_MODEL_OWNER_COL_BALANCE_PERIOD:
case GNC_TREE_MODEL_OWNER_COL_NOTES:
case GNC_TREE_MODEL_OWNER_COL_COLOR_BALANCE:
- case GNC_TREE_MODEL_OWNER_COL_COLOR_BALANCE_PERIOD:
return G_TYPE_STRING;
case GNC_TREE_MODEL_OWNER_COL_ACTIVE:
@@ -526,43 +524,6 @@
g_value_set_static_string (value, "black");
}
-static gchar *
-gnc_tree_model_owner_compute_period_balance(GncTreeModelOwner *model,
- GncOwner *acct,
- gboolean recurse,
- gboolean *negative)
-{
- GncTreeModelOwnerPrivate *priv;
- time_t t1, t2;
- gnc_numeric b3;
-
- if ( negative )
- *negative = FALSE;
-
- /* FIXME Figure out how to calculate the payment balance for an owner.
- * The code below is from the account tree model and should be
- * adapted for owners.
- priv = GNC_TREE_MODEL_OWNER_GET_PRIVATE(model);
- if (acct == priv->root)
- return g_strdup("");
-
- t1 = gnc_ownering_period_fiscal_start();
- t2 = gnc_ownering_period_fiscal_end();
-
- if (t1 > t2)
- return g_strdup("");
-
- b3 = xaccOwnerGetBalanceChangeForPeriod(acct, t1, t2, recurse);
- if (gnc_reverse_balance (acct))
- b3 = gnc_numeric_neg (b3);
-
- if (negative)
- *negative = gnc_numeric_negative_p(b3);
-
- return g_strdup(xaccPrintAmount(b3, gnc_owner_print_info(acct, TRUE))); */
- return g_strdup("0");
-}
-
static void
gnc_tree_model_owner_get_value (GtkTreeModel *tree_model,
GtkTreeIter *iter,
@@ -674,40 +635,21 @@
case GNC_TREE_MODEL_OWNER_COL_BALANCE:
g_value_init (value, G_TYPE_STRING);
- /* FIXME how to calculate an Owner's balance ?
- string = gnc_ui_owner_get_print_balance(xaccOwnerGetBalanceInCurrency,
- owner, TRUE, &negative);
- g_value_take_string (value, string); */
- g_value_set_static_string (value, "0");
+ string = gnc_ui_owner_get_print_balance(owner, &negative);
+ g_value_take_string (value, string);
break;
+
case GNC_TREE_MODEL_OWNER_COL_BALANCE_REPORT:
g_value_init (value, G_TYPE_STRING);
- /* FIXME how to calculate an Owner's balance ?
- string = gnc_ui_owner_get_print_report_balance(xaccOwnerGetBalanceInCurrency,
- owner, TRUE, &negative);
- g_value_take_string (value, string); */
- g_value_set_static_string (value, "0");
+ string = gnc_ui_owner_get_print_report_balance(owner, &negative);
+ g_value_take_string (value, string);
break;
case GNC_TREE_MODEL_OWNER_COL_COLOR_BALANCE:
g_value_init (value, G_TYPE_STRING);
- /* FIXME how to calculate an Owner's balance ?
- string = gnc_ui_owner_get_print_balance(xaccOwnerGetBalanceInCurrency,
- owner, TRUE, &negative);*/
- negative = FALSE;
+ string = gnc_ui_owner_get_print_balance(owner, &negative);
gnc_tree_model_owner_set_color(model, negative, value);
- /* g_free(string);*/
+ g_free(string);
break;
- case GNC_TREE_MODEL_OWNER_COL_BALANCE_PERIOD:
- g_value_init (value, G_TYPE_STRING);
- string = gnc_tree_model_owner_compute_period_balance(model, owner, FALSE, &negative);
- g_value_take_string (value, string);
- break;
- case GNC_TREE_MODEL_OWNER_COL_COLOR_BALANCE_PERIOD:
- g_value_init (value, G_TYPE_STRING);
- string = gnc_tree_model_owner_compute_period_balance(model, owner, FALSE, &negative);
- gnc_tree_model_owner_set_color(model, negative, value);
- g_free (string);
- break;
case GNC_TREE_MODEL_OWNER_COL_NOTES:
g_value_init (value, G_TYPE_STRING);
Modified: gnucash/trunk/src/gnome-utils/gnc-tree-model-owner.h
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-tree-model-owner.h 2011-08-13 15:33:27 UTC (rev 21181)
+++ gnucash/trunk/src/gnome-utils/gnc-tree-model-owner.h 2011-08-13 15:33:42 UTC (rev 21182)
@@ -67,7 +67,6 @@
GNC_TREE_MODEL_OWNER_COL_EMAIL,
GNC_TREE_MODEL_OWNER_COL_BALANCE,
GNC_TREE_MODEL_OWNER_COL_BALANCE_REPORT,
- GNC_TREE_MODEL_OWNER_COL_BALANCE_PERIOD,
GNC_TREE_MODEL_OWNER_COL_NOTES,
GNC_TREE_MODEL_OWNER_COL_ACTIVE,
@@ -75,7 +74,6 @@
/* internal hidden columns */
GNC_TREE_MODEL_OWNER_COL_COLOR_BALANCE,
- GNC_TREE_MODEL_OWNER_COL_COLOR_BALANCE_PERIOD,
GNC_TREE_MODEL_OWNER_NUM_COLUMNS
} GncTreeModelOwnerColumn;
Modified: gnucash/trunk/src/gnome-utils/gnc-tree-view-owner.c
===================================================================
--- gnucash/trunk/src/gnome-utils/gnc-tree-view-owner.c 2011-08-13 15:33:27 UTC (rev 21181)
+++ gnucash/trunk/src/gnome-utils/gnc-tree-view-owner.c 2011-08-13 15:33:42 UTC (rev 21182)
@@ -315,30 +315,20 @@
}
static gint
-sort_by_xxx_value (xaccGetBalanceInCurrencyFn fn,
- gboolean recurse,
- GtkTreeModel *f_model,
+sort_by_xxx_value (GtkTreeModel *f_model,
GtkTreeIter *f_iter_a,
GtkTreeIter *f_iter_b,
gpointer user_data)
{
- const GncOwner *owner_a, *owner_b;
+ GncOwner *owner_a, *owner_b;
gnc_numeric balance_a, balance_b;
gint result;
/* Find the owners */
- sort_cb_setup (f_model, f_iter_a, f_iter_b, &owner_a, &owner_b);
+ sort_cb_setup (f_model, f_iter_a, f_iter_b, (const GncOwner**)&owner_a, (const GncOwner**)&owner_b);
- /* Get balances */
- /* FIXME I'm not aware of any functions to get an owner's "balance" yet.
- * This should be implemented before this function does anything useful.
- * The code below is copied from the tree-view-account source to serve
- * as an example.
- balance_a = gnc_ui_owner_get_balance_full(fn, owner_a, recurse, NULL, NULL);
- balance_b = gnc_ui_owner_get_balance_full(fn, owner_b, recurse, NULL, NULL);
- */
- balance_a = gnc_numeric_zero();
- balance_b = gnc_numeric_zero();
+ balance_a = gnc_ui_owner_get_balance_full(owner_a, NULL, NULL);
+ balance_b = gnc_ui_owner_get_balance_full(owner_b, NULL, NULL);
result = gnc_numeric_compare(balance_a, balance_b);
if (result != 0)
@@ -352,58 +342,10 @@
GtkTreeIter *f_iter_b,
gpointer user_data)
{
- /* FIXME I'm not aware of any functions to get an owner's "balance" yet.
- * This should be implemented before this function does anything useful.
- * The code below is copied from the tree-view-account source to serve
- * as an example.
- return sort_by_xxx_value (gncOwnerGetBalanceInCurrency, TRUE,
- f_model, f_iter_a, f_iter_b, user_data);
- */
- return sort_by_xxx_value (NULL, TRUE,
- f_model, f_iter_a, f_iter_b, user_data);
+ return sort_by_xxx_value (f_model, f_iter_a, f_iter_b, user_data);
}
-static gint
-sort_by_xxx_period_value (GtkTreeModel *f_model,
- GtkTreeIter *f_iter_a,
- GtkTreeIter *f_iter_b,
- gboolean recurse)
-{
- GncOwner *owner1, *owner2;
- time_t t1, t2;
- gnc_numeric b1, b2;
- gint result;
- sort_cb_setup (f_model, f_iter_a, f_iter_b,
- (const GncOwner **)&owner1, (const GncOwner **)&owner2);
- t1 = gnc_accounting_period_fiscal_start();
- t2 = gnc_accounting_period_fiscal_end();
-
- /* FIXME I'm not aware of any functions to get an owner's "balance" yet.
- * This should be implemented before this function does anything useful.
- * The code below is copied from the tree-view-account source to serve
- * as an example.
- b1 = gncOwnerGetBalanceChangeForPeriod(owner1, t1, t2, recurse);
- b2 = gncOwnerGetBalanceChangeForPeriod(owner2, t1, t2, recurse);
- */
- b1 = gnc_numeric_zero();
- b2 = gnc_numeric_zero();
-
- result = gnc_numeric_compare(b1, b2);
- if (result != 0)
- return result;
- return gncOwnerCompare(owner1, owner2);
-}
-
-static gint
-sort_by_balance_period_value (GtkTreeModel *f_model,
- GtkTreeIter *f_iter_a,
- GtkTreeIter *f_iter_b,
- gpointer user_data)
-{
- return sort_by_xxx_period_value (f_model, f_iter_a, f_iter_b, FALSE);
-}
-
/************************************************************/
/* New View Creation */
/************************************************************/
@@ -520,20 +462,15 @@
GNC_TREE_MODEL_OWNER_COL_COLOR_BALANCE,
GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
sort_by_balance_value);
+
priv->balance_report_column
- = gnc_tree_view_add_numeric_column(view, _("Balance (Report)"), GNC_OWNER_TREE_BALANCE_REPORT_COL,
+ = gnc_tree_view_add_numeric_column(view, _("Balance"), GNC_OWNER_TREE_BALANCE_REPORT_COL,
SAMPLE_OWNER_VALUE,
GNC_TREE_MODEL_OWNER_COL_BALANCE_REPORT,
GNC_TREE_MODEL_OWNER_COL_COLOR_BALANCE,
GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
sort_by_balance_value);
- gnc_tree_view_add_numeric_column(view, _("Balance (Period)"), GNC_OWNER_TREE_BALANCE_PERIOD_COL,
- SAMPLE_OWNER_VALUE,
- GNC_TREE_MODEL_OWNER_COL_BALANCE_PERIOD,
- GNC_TREE_MODEL_OWNER_COL_COLOR_BALANCE_PERIOD,
- GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
- sort_by_balance_period_value);
priv->notes_column
= gnc_tree_view_add_text_column(view, _("Notes"), GNC_OWNER_TREE_NOTES_COL, NULL,
"Sample owner notes.",
More information about the gnucash-changes
mailing list