mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Move more account properties from the public data structure to a
private data structure, with access to them as properties of the object. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@15921 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
3c9babbcf2
commit
c6a609b8f7
@ -451,6 +451,7 @@ gnc_numeric gnc_numeric_reduce(gnc_numeric in);
|
||||
@{
|
||||
*/
|
||||
GType gnc_numeric_get_type( void );
|
||||
#define GNC_NUMERIC (gnc_numeric_get_type ())
|
||||
|
||||
/** @} */
|
||||
|
||||
|
@ -496,7 +496,11 @@ pgendAccountGetBalance (PGBackend *be, Account *acc, Timespec as_of_date)
|
||||
cleared_baln = gnc_numeric_create (cl_b, deno);
|
||||
reconciled_baln = gnc_numeric_create (rec_b, deno);
|
||||
|
||||
xaccAccountSetStartingBalance (acc, baln, cleared_baln, reconciled_baln);
|
||||
g_object_set(acc,
|
||||
"start-balance", &baln,
|
||||
"start-cleared-balance", &cleared_baln,
|
||||
"start-reconcoled-balance", &reconciled_baln,
|
||||
NULL);
|
||||
|
||||
{
|
||||
char buf[80];
|
||||
|
@ -128,27 +128,28 @@ typedef struct AccountPrivate
|
||||
Account *parent; /* back-pointer to parent */
|
||||
GList *children; /* list of sub-accounts */
|
||||
|
||||
// /* protected data, cached parameters */
|
||||
// gnc_numeric starting_balance;
|
||||
// gnc_numeric starting_cleared_balance;
|
||||
// gnc_numeric starting_reconciled_balance;
|
||||
//
|
||||
// gnc_numeric balance;
|
||||
// gnc_numeric cleared_balance;
|
||||
// gnc_numeric reconciled_balance;
|
||||
/* protected data - should only be set by backends */
|
||||
gnc_numeric starting_balance;
|
||||
gnc_numeric starting_cleared_balance;
|
||||
gnc_numeric starting_reconciled_balance;
|
||||
|
||||
/* cached parameters */
|
||||
gnc_numeric balance;
|
||||
gnc_numeric cleared_balance;
|
||||
gnc_numeric reconciled_balance;
|
||||
|
||||
gboolean balance_dirty; /* balances in splits incorrect */
|
||||
|
||||
/* version number, used for tracking multiuser updates */
|
||||
gint32 version;
|
||||
guint32 version_check; /* data aging timestamp */
|
||||
|
||||
// SplitList *splits; /* list of split pointers */
|
||||
GList *splits; /* list of split pointers */
|
||||
gboolean sort_dirty; /* sort order of splits is bad */
|
||||
|
||||
LotList *lots; /* list of lot pointers */
|
||||
GNCPolicy *policy; /* Cached pointer to policy method */
|
||||
|
||||
// gboolean balance_dirty; /* balances in splits incorrect */
|
||||
// gboolean sort_dirty; /* sort order of splits is bad */
|
||||
|
||||
/* The "mark" flag can be used by the user to mark this account
|
||||
* in any way desired. Handy for specialty traversals of the
|
||||
* account tree. */
|
||||
@ -246,17 +247,17 @@ gnc_account_init(Account* acc)
|
||||
// priv->commodity = NULL;
|
||||
// priv->commodity_scu = 0;
|
||||
// priv->non_standard_scu = FALSE;
|
||||
//
|
||||
// priv->balance = gnc_numeric_zero();
|
||||
// priv->cleared_balance = gnc_numeric_zero();
|
||||
// priv->reconciled_balance = gnc_numeric_zero();
|
||||
//
|
||||
// priv->starting_balance = gnc_numeric_zero();
|
||||
// priv->starting_cleared_balance = gnc_numeric_zero();
|
||||
// priv->starting_reconciled_balance = gnc_numeric_zero();
|
||||
//
|
||||
// priv->balance_dirty = FALSE;
|
||||
// priv->sort_dirty = FALSE;
|
||||
|
||||
priv->balance = gnc_numeric_zero();
|
||||
priv->cleared_balance = gnc_numeric_zero();
|
||||
priv->reconciled_balance = gnc_numeric_zero();
|
||||
priv->starting_balance = gnc_numeric_zero();
|
||||
priv->starting_cleared_balance = gnc_numeric_zero();
|
||||
priv->starting_reconciled_balance = gnc_numeric_zero();
|
||||
priv->balance_dirty = FALSE;
|
||||
|
||||
priv->splits = NULL;
|
||||
priv->sort_dirty = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -304,6 +305,30 @@ gnc_account_get_property (GObject *object,
|
||||
// NEED TO BE CONVERTED TO A G_TYPE_ENUM
|
||||
g_value_set_int(value, priv->type);
|
||||
break;
|
||||
case PROP_SORT_DIRTY:
|
||||
g_value_set_boolean(value, priv->sort_dirty);
|
||||
break;
|
||||
case PROP_BALANCE_DIRTY:
|
||||
g_value_set_boolean(value, priv->balance_dirty);
|
||||
break;
|
||||
case PROP_START_BALANCE:
|
||||
g_value_set_boxed(value, &priv->starting_balance);
|
||||
break;
|
||||
case PROP_START_CLEARED_BALANCE:
|
||||
g_value_set_boxed(value, &priv->starting_cleared_balance);
|
||||
break;
|
||||
case PROP_START_RECONCILED_BALANCE:
|
||||
g_value_set_boxed(value, &priv->starting_reconciled_balance);
|
||||
break;
|
||||
case PROP_END_BALANCE:
|
||||
g_value_set_boxed(value, &priv->balance);
|
||||
break;
|
||||
case PROP_END_CLEARED_BALANCE:
|
||||
g_value_set_boxed(value, &priv->cleared_balance);
|
||||
break;
|
||||
case PROP_END_RECONCILED_BALANCE:
|
||||
g_value_set_boxed(value, &priv->reconciled_balance);
|
||||
break;
|
||||
case PROP_ACCT_VERSION:
|
||||
g_value_set_int(value, priv->version);
|
||||
break;
|
||||
@ -363,6 +388,24 @@ gnc_account_set_property (GObject *object,
|
||||
// NEED TO BE CONVERTED TO A G_TYPE_ENUM
|
||||
xaccAccountSetType(account, g_value_get_int(value));
|
||||
break;
|
||||
case PROP_SORT_DIRTY:
|
||||
gnc_account_set_sort_dirty(account);
|
||||
break;
|
||||
case PROP_BALANCE_DIRTY:
|
||||
gnc_account_set_balance_dirty(account);
|
||||
break;
|
||||
case PROP_START_BALANCE:
|
||||
number = g_value_get_boxed(value);
|
||||
gnc_account_set_start_balance(account, *number);
|
||||
break;
|
||||
case PROP_START_CLEARED_BALANCE:
|
||||
number = g_value_get_boxed(value);
|
||||
gnc_account_set_start_cleared_balance(account, *number);
|
||||
break;
|
||||
case PROP_START_RECONCILED_BALANCE:
|
||||
number = g_value_get_boxed(value);
|
||||
gnc_account_set_start_reconciled_balance(account, *number);
|
||||
break;
|
||||
case PROP_ACCT_VERSION:
|
||||
xaccAccountSetVersion(account, g_value_get_int(value));
|
||||
break;
|
||||
@ -478,6 +521,120 @@ gnc_account_class_init (AccountClass *klass)
|
||||
ACCT_TYPE_BANK,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_BALANCE_DIRTY,
|
||||
g_param_spec_boolean("sort-dirty",
|
||||
"Sort Dirty",
|
||||
"TRUE if the splits in the account needs to be "
|
||||
"resorted. This flag is set by the accounts "
|
||||
"code for certain internal modifications, or "
|
||||
"when external code calls the engine to say a "
|
||||
"split has been modified in a way that may "
|
||||
"affect the sort order of the account. Note: "
|
||||
"This value can only be set to TRUE.",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_BALANCE_DIRTY,
|
||||
g_param_spec_boolean("balance-dirty",
|
||||
"Balance Dirty",
|
||||
"TRUE if the running balances in the account "
|
||||
"needs to be recalculated. This flag is set "
|
||||
"by the accounts code for certain internal "
|
||||
"modifications, or when external code calls "
|
||||
"the engine to say a split has been modified. "
|
||||
"Note: This value can only be set to TRUE.",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_START_BALANCE,
|
||||
g_param_spec_boxed("start-balance",
|
||||
"Starting Balance",
|
||||
"The starting balance for the account. This "
|
||||
"parameter is intended for use with backends that "
|
||||
"do not return the complete list of splits for an "
|
||||
"account, but rather return a partial list. In "
|
||||
"such a case, the backend will typically return "
|
||||
"all of the splits after some certain date, and "
|
||||
"the 'starting balance' will represent the "
|
||||
"summation of the splits up to that date.",
|
||||
GNC_NUMERIC,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_START_CLEARED_BALANCE,
|
||||
g_param_spec_boxed("start-cleared-balance",
|
||||
"Starting Cleared Balance",
|
||||
"The starting cleared balance for the account. "
|
||||
"This parameter is intended for use with backends "
|
||||
"that do not return the complete list of splits "
|
||||
"for an account, but rather return a partial "
|
||||
"list. In such a case, the backend will "
|
||||
"typically return all of the splits after "
|
||||
"some certain date, and the 'starting cleared "
|
||||
"balance' will represent the summation of the "
|
||||
"splits up to that date.",
|
||||
GNC_NUMERIC,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_START_RECONCILED_BALANCE,
|
||||
g_param_spec_boxed("start-reconciled-balance",
|
||||
"Starting Reconciled Balance",
|
||||
"The starting reconciled balance for the "
|
||||
"account. This parameter is intended for use "
|
||||
"with backends that do not return the complete "
|
||||
"list of splits for an account, but rather return "
|
||||
"a partial list. In such a case, the backend "
|
||||
"will typically return all of the splits after "
|
||||
"some certain date, and the 'starting recontiled "
|
||||
"balance' will represent the summation of the "
|
||||
"splits up to that date.",
|
||||
GNC_NUMERIC,
|
||||
G_PARAM_READWRITE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_END_BALANCE,
|
||||
g_param_spec_boxed("end-balance",
|
||||
"Ending Account Balance",
|
||||
"This is the current ending balance for the "
|
||||
"account. It is computed from the sum of the "
|
||||
"starting balance and all splits in the account.",
|
||||
GNC_NUMERIC,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_END_CLEARED_BALANCE,
|
||||
g_param_spec_boxed("end-cleared-balance",
|
||||
"Ending Account Cleared Balance",
|
||||
"This is the current ending cleared balance for "
|
||||
"the account. It is computed from the sum of the "
|
||||
"starting balance and all cleared splits in the "
|
||||
"account.",
|
||||
GNC_NUMERIC,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_END_RECONCILED_BALANCE,
|
||||
g_param_spec_boxed("end-reconciled-balance",
|
||||
"Ending Account Reconciled Balance",
|
||||
"This is the current ending reconciled balance "
|
||||
"for the account. It is computed from the sum of "
|
||||
"the starting balance and all reconciled splits "
|
||||
"in the account.",
|
||||
GNC_NUMERIC,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property
|
||||
(gobject_class,
|
||||
PROP_ACCT_VERSION,
|
||||
@ -557,25 +714,12 @@ xaccInitAccount (Account * acc, QofBook *book)
|
||||
ENTER ("book=%p\n", book);
|
||||
qof_instance_init_data (&acc->inst, GNC_ID_ACCOUNT, book);
|
||||
|
||||
acc->balance = gnc_numeric_zero();
|
||||
acc->cleared_balance = gnc_numeric_zero();
|
||||
acc->reconciled_balance = gnc_numeric_zero();
|
||||
|
||||
acc->starting_balance = gnc_numeric_zero();
|
||||
acc->starting_cleared_balance = gnc_numeric_zero();
|
||||
acc->starting_reconciled_balance = gnc_numeric_zero();
|
||||
|
||||
acc->idata = 0;
|
||||
|
||||
acc->commodity = NULL;
|
||||
acc->commodity_scu = 0;
|
||||
acc->non_standard_scu = FALSE;
|
||||
|
||||
acc->splits = NULL;
|
||||
|
||||
acc->balance_dirty = FALSE;
|
||||
acc->sort_dirty = FALSE;
|
||||
|
||||
LEAVE ("account=%p\n", acc);
|
||||
}
|
||||
|
||||
@ -818,7 +962,7 @@ xaccFreeAccount (Account *acc)
|
||||
/* NB there shouldn't be any splits by now ... they should
|
||||
* have been all been freed by CommitEdit(). We can remove this
|
||||
* check once we know the warning isn't occurring any more. */
|
||||
if (acc->splits)
|
||||
if (priv->splits)
|
||||
{
|
||||
GList *slist;
|
||||
PERR (" instead of calling xaccFreeAccount(), please call \n"
|
||||
@ -826,14 +970,14 @@ xaccFreeAccount (Account *acc)
|
||||
|
||||
acc->inst.editlevel = 0;
|
||||
|
||||
slist = g_list_copy(acc->splits);
|
||||
slist = g_list_copy(priv->splits);
|
||||
for (lp = slist; lp; lp = lp->next) {
|
||||
Split *s = (Split *) lp->data;
|
||||
g_assert(xaccSplitGetAccount(s) == acc);
|
||||
xaccSplitDestroy (s);
|
||||
}
|
||||
g_list_free(slist);
|
||||
g_assert(acc->splits == NULL);
|
||||
g_assert(priv->splits == NULL);
|
||||
}
|
||||
|
||||
CACHE_REPLACE(priv->accountName, NULL);
|
||||
@ -847,16 +991,16 @@ xaccFreeAccount (Account *acc)
|
||||
priv->parent = NULL;
|
||||
priv->children = NULL;
|
||||
|
||||
acc->balance = gnc_numeric_zero();
|
||||
acc->cleared_balance = gnc_numeric_zero();
|
||||
acc->reconciled_balance = gnc_numeric_zero();
|
||||
priv->balance = gnc_numeric_zero();
|
||||
priv->cleared_balance = gnc_numeric_zero();
|
||||
priv->reconciled_balance = gnc_numeric_zero();
|
||||
|
||||
priv->type = ACCT_TYPE_NONE;
|
||||
acc->commodity = NULL;
|
||||
|
||||
priv->version = 0;
|
||||
acc->balance_dirty = FALSE;
|
||||
acc->sort_dirty = FALSE;
|
||||
priv->balance_dirty = FALSE;
|
||||
priv->sort_dirty = FALSE;
|
||||
|
||||
/* qof_instance_release (&acc->inst); */
|
||||
g_object_unref(acc);
|
||||
@ -930,7 +1074,7 @@ xaccAccountCommitEdit (Account *acc)
|
||||
PINFO ("freeing splits for account %p (%s)",
|
||||
acc, priv->accountName ? priv->accountName : "(null)");
|
||||
|
||||
slist = g_list_copy(acc->splits);
|
||||
slist = g_list_copy(priv->splits);
|
||||
for (lp = slist; lp; lp = lp->next)
|
||||
{
|
||||
Split *s = lp->data;
|
||||
@ -942,7 +1086,7 @@ xaccAccountCommitEdit (Account *acc)
|
||||
deleting all the splits in it. The splits will just get
|
||||
recreated and put right back into the same account!
|
||||
|
||||
g_assert(acc->splits == NULL || qof_book_shutting_down(acc->inst.book));
|
||||
g_assert(priv->splits == NULL || qof_book_shutting_down(acc->inst.book));
|
||||
*/
|
||||
|
||||
if (!qof_book_shutting_down(acc->inst.book)) {
|
||||
@ -1143,13 +1287,13 @@ xaccAccountEqual(const Account *aa, const Account *ab, gboolean check_guids)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gnc_numeric_equal (aa->starting_balance, ab->starting_balance))
|
||||
if (!gnc_numeric_equal(priv_aa->starting_balance, priv_ab->starting_balance))
|
||||
{
|
||||
char *str_a;
|
||||
char *str_b;
|
||||
|
||||
str_a = gnc_numeric_to_string (aa->starting_balance);
|
||||
str_b = gnc_numeric_to_string (ab->starting_balance);
|
||||
str_a = gnc_numeric_to_string(priv_aa->starting_balance);
|
||||
str_b = gnc_numeric_to_string(priv_ab->starting_balance);
|
||||
|
||||
PWARN ("starting balances differ: %s vs %s", str_a, str_b);
|
||||
|
||||
@ -1159,14 +1303,14 @@ xaccAccountEqual(const Account *aa, const Account *ab, gboolean check_guids)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gnc_numeric_equal (aa->starting_cleared_balance,
|
||||
ab->starting_cleared_balance))
|
||||
if (!gnc_numeric_equal(priv_aa->starting_cleared_balance,
|
||||
priv_ab->starting_cleared_balance))
|
||||
{
|
||||
char *str_a;
|
||||
char *str_b;
|
||||
|
||||
str_a = gnc_numeric_to_string (aa->starting_cleared_balance);
|
||||
str_b = gnc_numeric_to_string (ab->starting_cleared_balance);
|
||||
str_a = gnc_numeric_to_string(priv_aa->starting_cleared_balance);
|
||||
str_b = gnc_numeric_to_string(priv_ab->starting_cleared_balance);
|
||||
|
||||
PWARN ("starting cleared balances differ: %s vs %s", str_a, str_b);
|
||||
|
||||
@ -1176,14 +1320,14 @@ xaccAccountEqual(const Account *aa, const Account *ab, gboolean check_guids)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gnc_numeric_equal (aa->starting_reconciled_balance,
|
||||
ab->starting_reconciled_balance))
|
||||
if (!gnc_numeric_equal(priv_aa->starting_reconciled_balance,
|
||||
priv_ab->starting_reconciled_balance))
|
||||
{
|
||||
char *str_a;
|
||||
char *str_b;
|
||||
|
||||
str_a = gnc_numeric_to_string (aa->starting_reconciled_balance);
|
||||
str_b = gnc_numeric_to_string (ab->starting_reconciled_balance);
|
||||
str_a = gnc_numeric_to_string(priv_aa->starting_reconciled_balance);
|
||||
str_b = gnc_numeric_to_string(priv_ab->starting_reconciled_balance);
|
||||
|
||||
PWARN ("starting reconciled balances differ: %s vs %s", str_a, str_b);
|
||||
|
||||
@ -1193,13 +1337,13 @@ xaccAccountEqual(const Account *aa, const Account *ab, gboolean check_guids)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gnc_numeric_equal (aa->balance, ab->balance))
|
||||
if (!gnc_numeric_equal(priv_aa->balance, priv_ab->balance))
|
||||
{
|
||||
char *str_a;
|
||||
char *str_b;
|
||||
|
||||
str_a = gnc_numeric_to_string (aa->balance);
|
||||
str_b = gnc_numeric_to_string (ab->balance);
|
||||
str_a = gnc_numeric_to_string(priv_aa->balance);
|
||||
str_b = gnc_numeric_to_string(priv_ab->balance);
|
||||
|
||||
PWARN ("balances differ: %s vs %s", str_a, str_b);
|
||||
|
||||
@ -1209,13 +1353,13 @@ xaccAccountEqual(const Account *aa, const Account *ab, gboolean check_guids)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gnc_numeric_equal (aa->cleared_balance, ab->cleared_balance))
|
||||
if (!gnc_numeric_equal(priv_aa->cleared_balance, priv_ab->cleared_balance))
|
||||
{
|
||||
char *str_a;
|
||||
char *str_b;
|
||||
|
||||
str_a = gnc_numeric_to_string (aa->cleared_balance);
|
||||
str_b = gnc_numeric_to_string (ab->cleared_balance);
|
||||
str_a = gnc_numeric_to_string(priv_aa->cleared_balance);
|
||||
str_b = gnc_numeric_to_string(priv_ab->cleared_balance);
|
||||
|
||||
PWARN ("cleared balances differ: %s vs %s", str_a, str_b);
|
||||
|
||||
@ -1225,13 +1369,13 @@ xaccAccountEqual(const Account *aa, const Account *ab, gboolean check_guids)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!gnc_numeric_equal (aa->reconciled_balance, ab->reconciled_balance))
|
||||
if (!gnc_numeric_equal(priv_aa->reconciled_balance, priv_ab->reconciled_balance))
|
||||
{
|
||||
char *str_a;
|
||||
char *str_b;
|
||||
|
||||
str_a = gnc_numeric_to_string (aa->reconciled_balance);
|
||||
str_b = gnc_numeric_to_string (ab->reconciled_balance);
|
||||
str_a = gnc_numeric_to_string(priv_aa->reconciled_balance);
|
||||
str_b = gnc_numeric_to_string(priv_ab->reconciled_balance);
|
||||
|
||||
PWARN ("reconciled balances differ: %s vs %s", str_a, str_b);
|
||||
|
||||
@ -1244,8 +1388,8 @@ xaccAccountEqual(const Account *aa, const Account *ab, gboolean check_guids)
|
||||
/* no parent; always compare downwards. */
|
||||
|
||||
{
|
||||
GList *la = aa->splits;
|
||||
GList *lb = ab->splits;
|
||||
GList *la = priv_aa->splits;
|
||||
GList *lb = priv_ab->splits;
|
||||
|
||||
if ((la && !lb) || (!la && lb))
|
||||
{
|
||||
@ -1290,14 +1434,137 @@ xaccAccountEqual(const Account *aa, const Account *ab, gboolean check_guids)
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
gboolean
|
||||
gnc_account_get_sort_dirty (Account *acc)
|
||||
{
|
||||
g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
|
||||
return GET_PRIVATE(acc)->sort_dirty;
|
||||
}
|
||||
|
||||
void
|
||||
gnc_account_set_sort_dirty (Account *acc)
|
||||
{
|
||||
AccountPrivate *priv;
|
||||
|
||||
g_return_if_fail(GNC_IS_ACCOUNT(acc));
|
||||
|
||||
if (acc->inst.do_free)
|
||||
return;
|
||||
|
||||
priv = GET_PRIVATE(acc);
|
||||
priv->sort_dirty = TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gnc_account_get_balance_dirty (Account *acc)
|
||||
{
|
||||
g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
|
||||
return GET_PRIVATE(acc)->balance_dirty;
|
||||
}
|
||||
|
||||
void
|
||||
gnc_account_set_balance_dirty (Account *acc)
|
||||
{
|
||||
AccountPrivate *priv;
|
||||
|
||||
g_return_if_fail(GNC_IS_ACCOUNT(acc));
|
||||
|
||||
if (acc->inst.do_free)
|
||||
return;
|
||||
|
||||
priv = GET_PRIVATE(acc);
|
||||
priv->balance_dirty = TRUE;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
gboolean
|
||||
gnc_account_find_split (Account *acc, Split *s)
|
||||
{
|
||||
AccountPrivate *priv;
|
||||
GList *node;
|
||||
|
||||
g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
|
||||
g_return_val_if_fail(GNC_IS_SPLIT(s), FALSE);
|
||||
|
||||
priv = GET_PRIVATE(acc);
|
||||
node = g_list_find(priv->splits, s);
|
||||
return node ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gnc_account_insert_split (Account *acc, Split *s)
|
||||
{
|
||||
AccountPrivate *priv;
|
||||
GList *node;
|
||||
|
||||
g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
|
||||
g_return_val_if_fail(GNC_IS_SPLIT(s), FALSE);
|
||||
|
||||
priv = GET_PRIVATE(acc);
|
||||
node = g_list_find(priv->splits, s);
|
||||
if (node)
|
||||
return FALSE;
|
||||
|
||||
if (acc->inst.editlevel == 0) {
|
||||
priv->splits = g_list_insert_sorted(priv->splits, s,
|
||||
(GCompareFunc)xaccSplitOrder);
|
||||
} else {
|
||||
priv->splits = g_list_prepend(priv->splits, s);
|
||||
priv->sort_dirty = TRUE;
|
||||
}
|
||||
|
||||
//FIXME: find better event
|
||||
qof_event_gen (&acc->inst, QOF_EVENT_MODIFY, NULL);
|
||||
/* Also send an event based on the account */
|
||||
qof_event_gen(&acc->inst, GNC_EVENT_ITEM_ADDED, s);
|
||||
|
||||
priv->balance_dirty = TRUE;
|
||||
// DRH: Should the below be added? It is present in the delete path.
|
||||
// xaccAccountRecomputeBalance(acc);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gnc_account_remove_split (Account *acc, Split *s)
|
||||
{
|
||||
AccountPrivate *priv;
|
||||
GList *node;
|
||||
|
||||
g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
|
||||
g_return_val_if_fail(GNC_IS_SPLIT(s), FALSE);
|
||||
|
||||
priv = GET_PRIVATE(acc);
|
||||
node = g_list_find(priv->splits, s);
|
||||
if (NULL == node)
|
||||
return FALSE;
|
||||
|
||||
priv->splits = g_list_delete_link(priv->splits, node);
|
||||
//FIXME: find better event type
|
||||
qof_event_gen(&acc->inst, QOF_EVENT_MODIFY, NULL);
|
||||
// And send the account-based event, too
|
||||
qof_event_gen(&acc->inst, GNC_EVENT_ITEM_REMOVED, s);
|
||||
|
||||
priv->balance_dirty = TRUE;
|
||||
xaccAccountRecomputeBalance(acc);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
xaccAccountSortSplits (Account *acc, gboolean force)
|
||||
{
|
||||
if (!acc || !acc->sort_dirty || (!force && acc->inst.editlevel > 0)) return;
|
||||
AccountPrivate *priv;
|
||||
|
||||
acc->splits = g_list_sort(acc->splits, (GCompareFunc)xaccSplitOrder);
|
||||
acc->sort_dirty = FALSE;
|
||||
acc->balance_dirty = TRUE;
|
||||
g_return_if_fail(GNC_IS_ACCOUNT(acc));
|
||||
|
||||
priv = GET_PRIVATE(acc);
|
||||
if (!priv->sort_dirty || (!force && acc->inst.editlevel > 0))
|
||||
return;
|
||||
priv->splits = g_list_sort(priv->splits, (GCompareFunc)xaccSplitOrder);
|
||||
priv->sort_dirty = FALSE;
|
||||
priv->balance_dirty = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1494,7 +1761,7 @@ xaccAccountMoveAllSplits (Account *accfrom, Account *accto)
|
||||
/* optimizations */
|
||||
from_priv = GET_PRIVATE(accfrom);
|
||||
to_priv = GET_PRIVATE(accto);
|
||||
if (!accfrom->splits || accfrom == accto)
|
||||
if (!from_priv->splits || accfrom == accto)
|
||||
return;
|
||||
|
||||
/* check for book mix-up */
|
||||
@ -1504,27 +1771,27 @@ xaccAccountMoveAllSplits (Account *accfrom, Account *accto)
|
||||
xaccAccountBeginEdit(accfrom);
|
||||
xaccAccountBeginEdit(accto);
|
||||
/* Begin editing both accounts and all transactions in accfrom. */
|
||||
g_list_foreach(accfrom->splits, (GFunc)xaccPreSplitMove, NULL);
|
||||
g_list_foreach(from_priv->splits, (GFunc)xaccPreSplitMove, NULL);
|
||||
|
||||
/* Concatenate accfrom's lists of splits and lots to accto's lists. */
|
||||
//accto->splits = g_list_concat(accto->splits, accfrom->splits);
|
||||
//to_priv->splits = g_list_concat(to_priv->splits, from_priv->splits);
|
||||
//to_priv->lots = g_list_concat(to_priv->lots, from_priv->lots);
|
||||
|
||||
/* Set appropriate flags. */
|
||||
//accfrom->balance_dirty = TRUE;
|
||||
//accfrom->sort_dirty = FALSE;
|
||||
//accto->balance_dirty = TRUE;
|
||||
//accto->sort_dirty = TRUE;
|
||||
//from_priv->balance_dirty = TRUE;
|
||||
//from_priv->sort_dirty = FALSE;
|
||||
//to_priv->balance_dirty = TRUE;
|
||||
//to_priv->sort_dirty = TRUE;
|
||||
|
||||
/*
|
||||
* Change each split's account back pointer to accto.
|
||||
* Convert each split's amount to accto's commodity.
|
||||
* Commit to editing each transaction.
|
||||
*/
|
||||
g_list_foreach(accfrom->splits, (GFunc)xaccPostSplitMove, (gpointer)accto);
|
||||
g_list_foreach(from_priv->splits, (GFunc)xaccPostSplitMove, (gpointer)accto);
|
||||
|
||||
/* Finally empty accfrom. */
|
||||
g_assert(accfrom->splits == NULL);
|
||||
g_assert(from_priv->splits == NULL);
|
||||
g_assert(from_priv->lots == NULL);
|
||||
xaccAccountCommitEdit(accfrom);
|
||||
xaccAccountCommitEdit(accto);
|
||||
@ -1575,17 +1842,17 @@ xaccAccountRecomputeBalance (Account * acc)
|
||||
|
||||
priv = GET_PRIVATE(acc);
|
||||
if (acc->inst.editlevel > 0) return;
|
||||
if (!acc->balance_dirty) return;
|
||||
if (!priv->balance_dirty) return;
|
||||
if (acc->inst.do_free) return;
|
||||
if (qof_book_shutting_down(acc->inst.book)) return;
|
||||
|
||||
balance = acc->starting_balance;
|
||||
cleared_balance = acc->starting_cleared_balance;
|
||||
reconciled_balance = acc->starting_reconciled_balance;
|
||||
balance = priv->starting_balance;
|
||||
cleared_balance = priv->starting_cleared_balance;
|
||||
reconciled_balance = priv->starting_reconciled_balance;
|
||||
|
||||
PINFO ("acct=%s starting baln=%" G_GINT64_FORMAT "/%" G_GINT64_FORMAT,
|
||||
priv->accountName, balance.num, balance.denom);
|
||||
for(lp = acc->splits; lp; lp = lp->next)
|
||||
for(lp = priv->splits; lp; lp = lp->next)
|
||||
{
|
||||
Split *split = (Split *) lp->data;
|
||||
gnc_numeric amt = xaccSplitGetAmount (split);
|
||||
@ -1611,30 +1878,10 @@ xaccAccountRecomputeBalance (Account * acc)
|
||||
last_split = split;
|
||||
}
|
||||
|
||||
acc->balance = balance;
|
||||
acc->cleared_balance = cleared_balance;
|
||||
acc->reconciled_balance = reconciled_balance;
|
||||
|
||||
acc->balance_dirty = FALSE;
|
||||
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
void
|
||||
xaccAccountSetStartingBalance(Account *acc,
|
||||
const gnc_numeric start_baln,
|
||||
const gnc_numeric start_cleared_baln,
|
||||
const gnc_numeric start_reconciled_baln)
|
||||
{
|
||||
if (!acc) return;
|
||||
|
||||
acc->starting_balance = start_baln;
|
||||
acc->starting_cleared_balance = start_cleared_baln;
|
||||
acc->starting_reconciled_balance = start_reconciled_baln;
|
||||
|
||||
acc->balance_dirty = TRUE;
|
||||
priv->balance = balance;
|
||||
priv->cleared_balance = cleared_balance;
|
||||
priv->reconciled_balance = reconciled_balance;
|
||||
priv->balance_dirty = FALSE;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
@ -1741,7 +1988,7 @@ xaccAccountSetType (Account *acc, GNCAccountType tip)
|
||||
|
||||
xaccAccountBeginEdit(acc);
|
||||
priv->type = tip;
|
||||
acc->balance_dirty = TRUE; /* new type may affect balance computation */
|
||||
priv->balance_dirty = TRUE; /* new type may affect balance computation */
|
||||
mark_account(acc);
|
||||
xaccAccountCommitEdit(acc);
|
||||
}
|
||||
@ -1841,9 +2088,11 @@ xaccAccountSetNotes (Account *acc, const char *str)
|
||||
void
|
||||
xaccAccountSetCommodity (Account * acc, gnc_commodity * com)
|
||||
{
|
||||
AccountPrivate *priv;
|
||||
GList *lp;
|
||||
if (!acc || !com || com == acc->commodity) return;
|
||||
|
||||
priv = GET_PRIVATE(acc);
|
||||
xaccAccountBeginEdit(acc);
|
||||
|
||||
acc->commodity = com;
|
||||
@ -1851,7 +2100,7 @@ xaccAccountSetCommodity (Account * acc, gnc_commodity * com)
|
||||
acc->non_standard_scu = FALSE;
|
||||
|
||||
/* iterate over splits */
|
||||
for (lp = acc->splits; lp; lp = lp->next)
|
||||
for (lp = priv->splits; lp; lp = lp->next)
|
||||
{
|
||||
Split *s = (Split *) lp->data;
|
||||
Transaction *trans = xaccSplitGetParent (s);
|
||||
@ -1861,8 +2110,8 @@ xaccAccountSetCommodity (Account * acc, gnc_commodity * com)
|
||||
xaccTransCommitEdit (trans);
|
||||
}
|
||||
|
||||
acc->sort_dirty = TRUE; /* Not needed. */
|
||||
acc->balance_dirty = TRUE;
|
||||
priv->sort_dirty = TRUE; /* Not needed. */
|
||||
priv->balance_dirty = TRUE;
|
||||
mark_account (acc);
|
||||
|
||||
if (gnc_commodity_is_iso(com)) {
|
||||
@ -2531,27 +2780,96 @@ xaccAccountGetCommodity (const Account *acc)
|
||||
return acc ? acc->commodity : NULL;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
gnc_numeric
|
||||
gnc_account_get_start_balance (Account *acc)
|
||||
{
|
||||
g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
|
||||
|
||||
return GET_PRIVATE(acc)->starting_balance;
|
||||
}
|
||||
|
||||
void
|
||||
gnc_account_set_start_balance (Account *acc, const gnc_numeric start_baln)
|
||||
{
|
||||
AccountPrivate *priv;
|
||||
|
||||
g_return_if_fail(GNC_IS_ACCOUNT(acc));
|
||||
|
||||
priv = GET_PRIVATE(acc);
|
||||
priv->starting_balance = start_baln;
|
||||
priv->balance_dirty = TRUE;
|
||||
}
|
||||
|
||||
gnc_numeric
|
||||
gnc_account_get_start_cleared_balance (Account *acc)
|
||||
{
|
||||
g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
|
||||
|
||||
return GET_PRIVATE(acc)->starting_cleared_balance;
|
||||
}
|
||||
|
||||
void
|
||||
gnc_account_set_start_cleared_balance (Account *acc,
|
||||
const gnc_numeric start_baln)
|
||||
{
|
||||
AccountPrivate *priv;
|
||||
|
||||
g_return_if_fail(GNC_IS_ACCOUNT(acc));
|
||||
|
||||
priv = GET_PRIVATE(acc);
|
||||
priv->starting_balance = start_baln;
|
||||
priv->balance_dirty = TRUE;
|
||||
}
|
||||
|
||||
gnc_numeric
|
||||
gnc_account_get_start_reconciled_balance (Account *acc)
|
||||
{
|
||||
g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
|
||||
|
||||
return GET_PRIVATE(acc)->starting_reconciled_balance;
|
||||
}
|
||||
|
||||
void
|
||||
gnc_account_set_start_reconciled_balance (Account *acc,
|
||||
const gnc_numeric start_baln)
|
||||
{
|
||||
AccountPrivate *priv;
|
||||
|
||||
g_return_if_fail(GNC_IS_ACCOUNT(acc));
|
||||
|
||||
priv = GET_PRIVATE(acc);
|
||||
priv->starting_balance = start_baln;
|
||||
priv->balance_dirty = TRUE;
|
||||
}
|
||||
|
||||
gnc_numeric
|
||||
xaccAccountGetBalance (const Account *acc)
|
||||
{
|
||||
return acc ? acc->balance : gnc_numeric_zero();
|
||||
g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
|
||||
return GET_PRIVATE(acc)->balance;
|
||||
}
|
||||
|
||||
gnc_numeric
|
||||
xaccAccountGetClearedBalance (const Account *acc)
|
||||
{
|
||||
return acc ? acc->cleared_balance : gnc_numeric_zero();
|
||||
g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
|
||||
return GET_PRIVATE(acc)->cleared_balance;
|
||||
}
|
||||
|
||||
gnc_numeric
|
||||
xaccAccountGetReconciledBalance (const Account *acc)
|
||||
{
|
||||
return acc ? acc->reconciled_balance : gnc_numeric_zero();
|
||||
g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
|
||||
return GET_PRIVATE(acc)->reconciled_balance;
|
||||
}
|
||||
|
||||
gnc_numeric
|
||||
xaccAccountGetProjectedMinimumBalance (const Account *acc)
|
||||
{
|
||||
AccountPrivate *priv;
|
||||
GList *node;
|
||||
time_t today;
|
||||
gnc_numeric lowest = gnc_numeric_zero ();
|
||||
@ -2559,8 +2877,9 @@ xaccAccountGetProjectedMinimumBalance (const Account *acc)
|
||||
|
||||
if (!acc) return gnc_numeric_zero ();
|
||||
|
||||
priv = GET_PRIVATE(acc);
|
||||
today = gnc_timet_get_today_end();
|
||||
for (node = g_list_last (acc->splits); node; node = node->prev)
|
||||
for (node = g_list_last(priv->splits); node; node = node->prev)
|
||||
{
|
||||
Split *split = node->data;
|
||||
|
||||
@ -2592,6 +2911,7 @@ xaccAccountGetBalanceAsOfDate (Account *acc, time_t date)
|
||||
* xaccAccountForEachTransaction by using gpointer return
|
||||
* values rather than gints.
|
||||
*/
|
||||
AccountPrivate *priv;
|
||||
GList *lp;
|
||||
Timespec ts, trans_ts;
|
||||
gboolean found = FALSE;
|
||||
@ -2602,7 +2922,8 @@ xaccAccountGetBalanceAsOfDate (Account *acc, time_t date)
|
||||
xaccAccountSortSplits (acc, TRUE); /* just in case, normally a noop */
|
||||
xaccAccountRecomputeBalance (acc); /* just in case, normally a noop */
|
||||
|
||||
balance = acc->balance;
|
||||
priv = GET_PRIVATE(acc);
|
||||
balance = priv->balance;
|
||||
|
||||
/* Since transaction post times are stored as a Timespec,
|
||||
* convert date into a Timespec as well rather than converting
|
||||
@ -2619,7 +2940,7 @@ xaccAccountGetBalanceAsOfDate (Account *acc, time_t date)
|
||||
ts.tv_sec = date;
|
||||
ts.tv_nsec = 0;
|
||||
|
||||
lp = acc->splits;
|
||||
lp = priv->splits;
|
||||
while( lp && !found )
|
||||
{
|
||||
xaccTransGetDatePostedTS( xaccSplitGetParent( (Split *)lp->data ),
|
||||
@ -2661,13 +2982,15 @@ xaccAccountGetBalanceAsOfDate (Account *acc, time_t date)
|
||||
gnc_numeric
|
||||
xaccAccountGetPresentBalance (const Account *acc)
|
||||
{
|
||||
AccountPrivate *priv;
|
||||
GList *node;
|
||||
time_t today;
|
||||
|
||||
g_return_val_if_fail(acc, gnc_numeric_zero());
|
||||
|
||||
priv = GET_PRIVATE(acc);
|
||||
today = gnc_timet_get_today_end();
|
||||
for (node = g_list_last (acc->splits); node; node = node->prev)
|
||||
for (node = g_list_last(priv->splits); node; node = node->prev)
|
||||
{
|
||||
Split *split = node->data;
|
||||
|
||||
@ -2961,11 +3284,20 @@ xaccAccountGetBalanceChangeForPeriod (Account *acc, time_t t1, time_t t2, gboole
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
/* THIS API NEEDS TO CHANGE.
|
||||
*
|
||||
* This code exposes the internal structure of the account object to
|
||||
* external callers by returning the actual list used by the object.
|
||||
* It should instead return a copy of the split list that the caller
|
||||
* is required to free. That change would provide the freedom of
|
||||
* allowing the internal organization to change data structures if
|
||||
* necessary for whatever reason, while leaving the external API
|
||||
* unchanged. */
|
||||
SplitList *
|
||||
xaccAccountGetSplitList (const Account *acc)
|
||||
{
|
||||
g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL);
|
||||
return acc->splits;
|
||||
return GET_PRIVATE(acc)->splits;
|
||||
}
|
||||
|
||||
LotList *
|
||||
@ -3755,6 +4087,7 @@ static void
|
||||
finder_help_function(const Account *acc, const char *description,
|
||||
Split **split, Transaction **trans )
|
||||
{
|
||||
AccountPrivate *priv;
|
||||
GList *slp;
|
||||
|
||||
/* First, make sure we set the data to NULL BEFORE we start */
|
||||
@ -3767,7 +4100,8 @@ finder_help_function(const Account *acc, const char *description,
|
||||
/* Why is this loop iterated backwards ?? Presumably because the split
|
||||
* list is in date order, and the most recent matches should be
|
||||
* returned!? */
|
||||
for (slp = g_list_last (acc->splits); slp; slp = slp->prev) {
|
||||
priv = GET_PRIVATE(acc);
|
||||
for (slp = g_list_last(priv->splits); slp; slp = slp->prev) {
|
||||
Split *lsplit = slp->data;
|
||||
Transaction *ltrans = xaccSplitGetParent(lsplit);
|
||||
|
||||
@ -3933,8 +4267,8 @@ gnc_account_merge_children (Account *parent)
|
||||
gnc_account_merge_children (acc_a);
|
||||
|
||||
/* consolidate transactions */
|
||||
while (acc_b->splits)
|
||||
xaccSplitSetAccount (acc_b->splits->data, acc_a);
|
||||
while (priv_b->splits)
|
||||
xaccSplitSetAccount (priv_b->splits->data, acc_a);
|
||||
|
||||
/* move back one before removal. next iteration around the loop
|
||||
* will get the node after node_b */
|
||||
@ -3971,8 +4305,12 @@ xaccSplitsBeginStagedTransactionTraversals (GList *splits)
|
||||
void
|
||||
xaccAccountBeginStagedTransactionTraversals (const Account *account)
|
||||
{
|
||||
if (account)
|
||||
xaccSplitsBeginStagedTransactionTraversals (account->splits);
|
||||
AccountPrivate *priv;
|
||||
|
||||
if (!account)
|
||||
return;
|
||||
priv = GET_PRIVATE(account);
|
||||
xaccSplitsBeginStagedTransactionTraversals(priv->splits);
|
||||
}
|
||||
|
||||
gboolean
|
||||
@ -4005,7 +4343,8 @@ static void do_one_split (Split *s, gpointer data)
|
||||
|
||||
static void do_one_account (Account *account, gpointer data)
|
||||
{
|
||||
g_list_foreach(account->splits, (GFunc)do_one_split, NULL);
|
||||
AccountPrivate *priv = GET_PRIVATE(account);
|
||||
g_list_foreach(priv->splits, (GFunc)do_one_split, NULL);
|
||||
}
|
||||
|
||||
/* Replacement for xaccGroupBeginStagedTransactionTraversals */
|
||||
@ -4025,6 +4364,7 @@ xaccAccountStagedTransactionTraversal (const Account *acc,
|
||||
TransactionCallback thunk,
|
||||
void *cb_data)
|
||||
{
|
||||
AccountPrivate *priv;
|
||||
GList *split_p;
|
||||
Transaction *trans;
|
||||
Split *s;
|
||||
@ -4032,7 +4372,8 @@ xaccAccountStagedTransactionTraversal (const Account *acc,
|
||||
|
||||
if (!acc) return 0;
|
||||
|
||||
for(split_p = acc->splits; split_p; split_p = g_list_next(split_p)) {
|
||||
priv = GET_PRIVATE(acc);
|
||||
for(split_p = priv->splits; split_p; split_p = g_list_next(split_p)) {
|
||||
s = split_p->data;
|
||||
trans = s->parent;
|
||||
if (trans && (trans->marker < stage)) {
|
||||
@ -4070,7 +4411,7 @@ gnc_account_tree_staged_transaction_traversal (const Account *acc,
|
||||
}
|
||||
|
||||
/* Now this account */
|
||||
for(split_p = acc->splits; split_p; split_p = g_list_next(split_p)) {
|
||||
for(split_p = priv->splits; split_p; split_p = g_list_next(split_p)) {
|
||||
s = split_p->data;
|
||||
trans = s->parent;
|
||||
if (trans && (trans->marker < stage)) {
|
||||
|
@ -275,6 +275,80 @@ GNCAccountType xaccAccountGetType (const Account *account);
|
||||
/** Is the account a stock, mutual fund or currency? */
|
||||
gboolean xaccAccountIsPriced(const Account *acc);
|
||||
|
||||
/** This function will set the starting commodity balance for this
|
||||
* account. This routine is intended for use with backends that do
|
||||
* not return the complete list of splits for an account, but rather
|
||||
* return a partial list. In such a case, the backend will typically
|
||||
* return all of the splits after some certain date, and the
|
||||
* 'starting balance' will represent the summation of the splits up
|
||||
* to that date. */
|
||||
void gnc_account_set_start_balance (Account *acc,
|
||||
const gnc_numeric start_baln);
|
||||
|
||||
/** This function will set the starting cleared commodity balance for
|
||||
* this account. This routine is intended for use with backends that
|
||||
* do not return the complete list of splits for an account, but
|
||||
* rather return a partial list. In such a case, the backend will
|
||||
* typically return all of the splits after some certain date, and
|
||||
* the 'starting balance' will represent the summation of the splits
|
||||
* up to that date. */
|
||||
void gnc_account_set_start_cleared_balance (Account *acc,
|
||||
const gnc_numeric start_baln);
|
||||
|
||||
/** This function will set the starting reconciled commodity balance
|
||||
* for this account. This routine is intended for use with backends
|
||||
* that do not return the complete list of splits for an account, but
|
||||
* rather return a partial list. In such a case, the backend will
|
||||
* typically return all of the splits after some certain date, and
|
||||
* the 'starting balance' will represent the summation of the splits
|
||||
* up to that date. */
|
||||
void gnc_account_set_start_reconciled_balance (Account *acc,
|
||||
const gnc_numeric start_baln);
|
||||
|
||||
/** Tell the account that the running balances may be incorrect and
|
||||
* need to be recomputed.
|
||||
*
|
||||
* @param acc Set the flag on this account. */
|
||||
void gnc_account_set_balance_dirty (Account *acc);
|
||||
|
||||
/** Tell the account believes that the splits may be incorrectly
|
||||
* sorted and need to be resorted.
|
||||
*
|
||||
* @param acc Set the flag on this account. */
|
||||
void gnc_account_set_sort_dirty (Account *acc);
|
||||
|
||||
/** Find the given split in an account.
|
||||
*
|
||||
* @param acc The account whose splits are to be searched.
|
||||
*
|
||||
* @param s The split to be found.
|
||||
*
|
||||
* @result TRUE is the split is found in the accounts list of splits.
|
||||
* FALSE otherwise. */
|
||||
gboolean gnc_account_find_split (Account *acc, Split *s);
|
||||
|
||||
/** Insert the given split from an account.
|
||||
*
|
||||
* @param acc The account to which the split should be added.
|
||||
*
|
||||
* @param s The split to be added.
|
||||
*
|
||||
* @result TRUE is the split is successfully added to the set of
|
||||
* splits in the account. FALSE if the addition fails for any reason
|
||||
* (including that the split is already in the account). */
|
||||
gboolean gnc_account_insert_split (Account *acc, Split *s);
|
||||
|
||||
/** Remove the given split from an account.
|
||||
*
|
||||
* @param acc The account from which the split should be removed.
|
||||
*
|
||||
* @param s The split to be removed.
|
||||
*
|
||||
* @result TRUE is the split is successfully removed from the set of
|
||||
* splits in the account. FALSE if the removal fails for any
|
||||
* reason. */
|
||||
gboolean gnc_account_remove_split (Account *acc, Split *s);
|
||||
|
||||
/** Get the account's name */
|
||||
const char * xaccAccountGetName (const Account *account);
|
||||
/** Get the account's accounting code */
|
||||
@ -292,6 +366,45 @@ GNCPolicy *gnc_account_get_policy (Account *account);
|
||||
gint32 xaccAccountGetVersion (const Account* acc);
|
||||
/** Get the account version_check number */
|
||||
guint32 gnc_account_get_version_check (const Account *acc);
|
||||
/** Retrieve the starting commodity balance for this account. */
|
||||
gnc_numeric gnc_account_get_start_balance (Account *acc);
|
||||
|
||||
/** Retrieve the starting cleared commodity balance for this
|
||||
* account. */
|
||||
gnc_numeric gnc_account_get_start_cleared_balance (Account *acc);
|
||||
|
||||
/** Retrieve the starting reconciled commodity balance for this
|
||||
* account. */
|
||||
gnc_numeric gnc_account_get_start_reconciled_balance (Account *acc);
|
||||
|
||||
/** Get an indication of whether the account believes that the running
|
||||
* balances may be incorrect and need to be recomputed.
|
||||
*
|
||||
* @param acc Retrieve the flag on this account.
|
||||
*
|
||||
* @return TRUE if the running account balances need to be recomputed.
|
||||
* FALSE if they are correct. */
|
||||
gboolean gnc_account_get_balance_dirty (Account *acc);
|
||||
|
||||
/** Get an indication of whether the account believes that the splits
|
||||
* may be incorrectly sorted and need to be resorted.
|
||||
*
|
||||
* @param acc Retrieve the flag on this account.
|
||||
*
|
||||
* @return TRUE if the splits in the account need to be resorted.
|
||||
* FALSE if the sort order is correct. */
|
||||
gboolean gnc_account_get_sort_dirty (Account *acc);
|
||||
|
||||
/** The following recompute the partial balances (stored with the
|
||||
* transaction) and the total balance, for this account
|
||||
*/
|
||||
void xaccAccountRecomputeBalance (Account *);
|
||||
|
||||
/** The xaccAccountSortSplits() routine will resort the account's
|
||||
* splits if the sort is dirty. If 'force' is true, the account
|
||||
* is sorted even if the editlevel is not zero.
|
||||
*/
|
||||
void xaccAccountSortSplits (Account *acc, gboolean force);
|
||||
|
||||
/** The xaccAccountGetFullName routine returns the fully qualified name
|
||||
* of the account using the given separator char. The name must be
|
||||
@ -864,7 +977,11 @@ guint32 xaccAccountTypesValid(void);
|
||||
* data structure: do not delete it when done; treat it as a read-only
|
||||
* structure. Note that some routines (such as xaccAccountRemoveSplit())
|
||||
* modify this list directly, and could leave you with a corrupted
|
||||
* pointer. */
|
||||
* pointer.
|
||||
* @note This should be changed so that the returned value is a copy
|
||||
* of the list. No other part of the code should have access to the
|
||||
* internal data structure used by this object.
|
||||
*/
|
||||
SplitList* xaccAccountGetSplitList (const Account *account);
|
||||
|
||||
/** The xaccAccountMoveAllSplits() routine reassigns each of the splits
|
||||
|
@ -65,58 +65,16 @@ struct account_s
|
||||
int commodity_scu;
|
||||
gboolean non_standard_scu;
|
||||
|
||||
/* protected data, cached parameters */
|
||||
gnc_numeric starting_balance;
|
||||
gnc_numeric starting_cleared_balance;
|
||||
gnc_numeric starting_reconciled_balance;
|
||||
|
||||
gnc_numeric balance;
|
||||
gnc_numeric cleared_balance;
|
||||
gnc_numeric reconciled_balance;
|
||||
|
||||
SplitList *splits; /* list of split pointers */
|
||||
|
||||
gboolean balance_dirty; /* balances in splits incorrect */
|
||||
gboolean sort_dirty; /* sort order of splits is bad */
|
||||
|
||||
/* -------------------------------------------------------------- */
|
||||
/* Backend private expansion data */
|
||||
guint32 idata; /* used by the sql backend for kvp management */
|
||||
};
|
||||
|
||||
/* The xaccAccountSortSplits() routine will resort the account's
|
||||
* splits if the sort is dirty. If 'force' is true, the account
|
||||
* is sorted even if the editlevel is not zero.
|
||||
*/
|
||||
void xaccAccountSortSplits (Account *acc, gboolean force);
|
||||
|
||||
/* The following recompute the partial balances (stored with the
|
||||
* transaction) and the total balance, for this account
|
||||
*/
|
||||
void xaccAccountRecomputeBalance (Account *);
|
||||
|
||||
/* Set the account's GUID. This should only be done when reading
|
||||
* an account from a datafile, or some other external source. Never
|
||||
* call this on an existing account! */
|
||||
void xaccAccountSetGUID (Account *account, const GUID *guid);
|
||||
|
||||
/* The xaccAccountSetStartingBalance() routine will set the starting
|
||||
* commodity balance for this account. This routine is intended for
|
||||
* use with backends that do not return the complete list of splits
|
||||
* for an account, but rather return a partial list. In such a case,
|
||||
* the backend will typically return all of the splits after some
|
||||
* certain date, and the 'starting balance' will represent the summation
|
||||
* of the splits up to that date.
|
||||
*
|
||||
* This routine is in the private .h file because only backends are
|
||||
* allowed to set the starting balance. This is *not* a user interface
|
||||
* function.
|
||||
*/
|
||||
void xaccAccountSetStartingBalance(Account *account,
|
||||
const gnc_numeric start_baln,
|
||||
const gnc_numeric start_cleared_baln,
|
||||
const gnc_numeric start_reconciled_baln);
|
||||
|
||||
/* Register Accounts with the engine */
|
||||
gboolean xaccAccountRegister (void);
|
||||
|
||||
|
@ -112,8 +112,7 @@ gnc_book_insert_trans_clobber (QofBook *book, Transaction *trans)
|
||||
else
|
||||
{
|
||||
xaccAccountInsertSplit (twin, s);
|
||||
twin->balance_dirty = TRUE;
|
||||
twin->sort_dirty = TRUE;
|
||||
g_object_set(twin, "sort-dirty", TRUE, "balance-dirty", TRUE, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,8 +178,7 @@ gnc_book_insert_trans (QofBook *book, Transaction *trans)
|
||||
if (s->acc != twin)
|
||||
{
|
||||
xaccAccountInsertSplit (twin, s);
|
||||
twin->balance_dirty = TRUE;
|
||||
twin->sort_dirty = TRUE;
|
||||
g_object_set(twin, "sort-dirty", TRUE, "balance-dirty", TRUE, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ static QofLogModule log_module = GNC_MOD_LOT;
|
||||
void
|
||||
xaccAccountAssignLots (Account *acc)
|
||||
{
|
||||
SplitList *node;
|
||||
SplitList *splits, *node;
|
||||
|
||||
if (!acc) return;
|
||||
|
||||
@ -65,7 +65,8 @@ xaccAccountAssignLots (Account *acc)
|
||||
xaccAccountBeginEdit (acc);
|
||||
|
||||
restart_loop:
|
||||
for (node=acc->splits; node; node=node->next)
|
||||
splits = xaccAccountGetSplitList(acc);
|
||||
for (node=splits; node; node=node->next)
|
||||
{
|
||||
Split * split = node->data;
|
||||
|
||||
|
@ -296,17 +296,11 @@ xaccFreeSplit (Split *split)
|
||||
g_object_unref(split);
|
||||
}
|
||||
|
||||
static void mark_acc(Account *acc)
|
||||
{
|
||||
if (acc && !acc->inst.do_free) {
|
||||
acc->balance_dirty = TRUE;
|
||||
acc->sort_dirty = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void mark_split (Split *s)
|
||||
{
|
||||
mark_acc(s->acc);
|
||||
if (s->acc) {
|
||||
g_object_set(s->acc, "sort-dirty", TRUE, "balance-dirty", TRUE, NULL);
|
||||
}
|
||||
|
||||
/* set dirty flag on lot too. */
|
||||
if (s->lot) s->lot->is_closed = -1;
|
||||
@ -526,41 +520,21 @@ xaccSplitCommitEdit(Split *s)
|
||||
|
||||
/* Possibly remove the split from the original account... */
|
||||
if (orig_acc && (orig_acc != acc || s->inst.do_free)) {
|
||||
GList *node = g_list_find (orig_acc->splits, s);
|
||||
if (node) {
|
||||
orig_acc->splits = g_list_delete_link (orig_acc->splits, node);
|
||||
//FIXME: find better event type
|
||||
qof_event_gen (&orig_acc->inst, QOF_EVENT_MODIFY, NULL);
|
||||
// And send the account-based event, too
|
||||
qof_event_gen(&orig_acc->inst, GNC_EVENT_ITEM_REMOVED, s);
|
||||
} else PERR("Account lost track of moved or deleted split.");
|
||||
orig_acc->balance_dirty = TRUE;
|
||||
xaccAccountRecomputeBalance(orig_acc);
|
||||
if (!gnc_account_remove_split(orig_acc, s)) {
|
||||
PERR("Account lost track of moved or deleted split.");
|
||||
}
|
||||
}
|
||||
|
||||
/* ... and insert it into the new account if needed */
|
||||
if (orig_acc != s->acc && !s->inst.do_free) {
|
||||
if (!g_list_find(acc->splits, s)) {
|
||||
if (acc->inst.editlevel == 0) {
|
||||
acc->splits = g_list_insert_sorted(
|
||||
acc->splits, s, (GCompareFunc)xaccSplitOrder);
|
||||
} else {
|
||||
acc->splits = g_list_prepend(acc->splits, s);
|
||||
acc->sort_dirty = TRUE;
|
||||
}
|
||||
|
||||
if (acc && (orig_acc != acc) && !s->inst.do_free) {
|
||||
if (gnc_account_insert_split(acc, s)) {
|
||||
/* If the split's lot belonged to some other account, we
|
||||
leave it so. */
|
||||
if (s->lot && (NULL == s->lot->account))
|
||||
xaccAccountInsertLot (acc, s->lot);
|
||||
|
||||
//FIXME: find better event
|
||||
qof_event_gen (&acc->inst, QOF_EVENT_MODIFY, NULL);
|
||||
|
||||
/* Also send an event based on the account */
|
||||
qof_event_gen(&acc->inst, GNC_EVENT_ITEM_ADDED, s);
|
||||
} else PERR("Account grabbed split prematurely.");
|
||||
acc->balance_dirty = TRUE;
|
||||
} else {
|
||||
PERR("Account grabbed split prematurely.");
|
||||
}
|
||||
xaccSplitSetAmount(s, xaccSplitGetAmount(s));
|
||||
}
|
||||
|
||||
@ -585,8 +559,10 @@ xaccSplitCommitEdit(Split *s)
|
||||
/* This is because Splits don't call qof_commit_edit(). */
|
||||
qof_instance_set_dirty(QOF_INSTANCE(s->parent));
|
||||
|
||||
mark_acc(acc);
|
||||
xaccAccountRecomputeBalance(acc);
|
||||
if (acc) {
|
||||
g_object_set(acc, "sort-dirty", TRUE, "balance-dirty", TRUE, NULL);
|
||||
xaccAccountRecomputeBalance(acc);
|
||||
}
|
||||
if (s->inst.do_free)
|
||||
xaccFreeSplit(s);
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ gboolean
|
||||
xaccAccountHasTrades (Account *acc)
|
||||
{
|
||||
gnc_commodity *acc_comm;
|
||||
SplitList *node;
|
||||
SplitList *splits, *node;
|
||||
|
||||
if (!acc) return FALSE;
|
||||
|
||||
@ -88,7 +88,8 @@ xaccAccountHasTrades (Account *acc)
|
||||
|
||||
acc_comm = acc->commodity;
|
||||
|
||||
for (node=acc->splits; node; node=node->next)
|
||||
splits = xaccAccountGetSplitList(acc);
|
||||
for (node=splits; node; node=node->next)
|
||||
{
|
||||
Split *s = node->data;
|
||||
Transaction *t = s->parent;
|
||||
|
@ -31,6 +31,7 @@ TESTS = \
|
||||
test-object \
|
||||
test-commodities \
|
||||
test-create-account \
|
||||
test-account-object \
|
||||
test-group-vs-book \
|
||||
test-lots \
|
||||
test-period \
|
||||
@ -66,6 +67,7 @@ check_PROGRAMS = \
|
||||
test-freq-spec \
|
||||
test-recurrence \
|
||||
test-guid \
|
||||
test-account-object \
|
||||
test-group-vs-book \
|
||||
test-load-engine \
|
||||
test-period \
|
||||
|
102
src/engine/test/test-account-object.c
Normal file
102
src/engine/test/test-account-object.c
Normal file
@ -0,0 +1,102 @@
|
||||
/***************************************************************************
|
||||
* test-account-object.c
|
||||
*
|
||||
* Copyright (C) 2007 David Hampton <hampton@employees.org>
|
||||
****************************************************************************/
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*/
|
||||
/**
|
||||
* @file test-account-object.c
|
||||
* @brief Minimal test of reading/writing account parameters
|
||||
* @author David Hampton <hampton@employees.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <unistd.h>
|
||||
#include <glib.h>
|
||||
#include "qof.h"
|
||||
#include "Account.h"
|
||||
#include "cashobjects.h"
|
||||
#include "test-stuff.h"
|
||||
#include "test-engine-stuff.h"
|
||||
|
||||
static void
|
||||
run_test (void)
|
||||
{
|
||||
QofSession *sess;
|
||||
QofBook *book;
|
||||
Account *acc;
|
||||
gnc_numeric *start, *end, end2, delta, zero, five;
|
||||
|
||||
sess = get_random_session ();
|
||||
book = qof_session_get_book (sess);
|
||||
do_test ((NULL != book), "create random data");
|
||||
acc = get_random_account(book);
|
||||
|
||||
/*****/
|
||||
|
||||
g_object_get(acc, "start-balance", &start, "end-balance", &end, NULL);
|
||||
end2 = xaccAccountGetBalance(acc);
|
||||
delta = gnc_numeric_sub(*end, *start, GNC_DENOM_AUTO, GNC_HOW_DENOM_FIXED);
|
||||
|
||||
do_test (gnc_numeric_zero_p(*start), "start balance is zero");
|
||||
do_test (gnc_numeric_zero_p(*end), "end balance is zero");
|
||||
do_test (gnc_numeric_zero_p(delta), "delta is zero");
|
||||
do_test (gnc_numeric_zero_p(end2), "end2 balance is zero");
|
||||
|
||||
/*****/
|
||||
|
||||
five = gnc_numeric_create(5, 1);
|
||||
g_object_set(acc, "start-balance", &five, NULL);
|
||||
xaccAccountRecomputeBalance(acc);
|
||||
g_object_get(acc, "start-balance", &start, "end-balance", &end, NULL);
|
||||
end2 = xaccAccountGetBalance(acc);
|
||||
|
||||
delta = gnc_numeric_sub(*end, five, GNC_DENOM_AUTO, GNC_HOW_DENOM_FIXED);
|
||||
do_test (gnc_numeric_zero_p(delta), "end balance matches");
|
||||
delta = gnc_numeric_sub(end2, five, GNC_DENOM_AUTO, GNC_HOW_DENOM_FIXED);
|
||||
do_test (gnc_numeric_zero_p(delta), "end2 balance matches");
|
||||
|
||||
/*****/
|
||||
|
||||
qof_session_end (sess);
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
gint i;
|
||||
|
||||
qof_init();
|
||||
if (!cashobjects_register())
|
||||
exit(1);
|
||||
|
||||
/* Any tests that cause an error or warning to be printed
|
||||
* automatically fail! */
|
||||
g_log_set_always_fatal( G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING );
|
||||
/* Set up a reproducible test-case */
|
||||
srand(0);
|
||||
|
||||
/* Run the tests */
|
||||
run_test ();
|
||||
|
||||
print_test_results();
|
||||
|
||||
qof_close();
|
||||
return get_rv();
|
||||
}
|
Loading…
Reference in New Issue
Block a user