mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Bug 603379 - Prevent changing some Account Options if it has transactions - followup
Relax the account type change restrictions again. In the new implementation account types can't be changed for an account with splits: - if the change woud force a commodity change (to/from normal accounts from/to stock related accounts) - for immutable accounts At the time of this commit the following account types are considered immutable: - Accounts Receivable - Accounts Payable - Trading accounts
This commit is contained in:
parent
4032d33b48
commit
c80dad742e
@ -4029,6 +4029,46 @@ xaccAccountGetTypeStr(GNCAccountType type)
|
||||
/********************************************************************\
|
||||
\********************************************************************/
|
||||
|
||||
guint32
|
||||
xaccAccountTypesCompatibleWith (GNCAccountType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ACCT_TYPE_BANK:
|
||||
case ACCT_TYPE_CASH:
|
||||
case ACCT_TYPE_ASSET:
|
||||
case ACCT_TYPE_CREDIT:
|
||||
case ACCT_TYPE_LIABILITY:
|
||||
case ACCT_TYPE_INCOME:
|
||||
case ACCT_TYPE_EXPENSE:
|
||||
case ACCT_TYPE_EQUITY:
|
||||
return
|
||||
(1 << ACCT_TYPE_BANK) |
|
||||
(1 << ACCT_TYPE_CASH) |
|
||||
(1 << ACCT_TYPE_ASSET) |
|
||||
(1 << ACCT_TYPE_CREDIT) |
|
||||
(1 << ACCT_TYPE_LIABILITY) |
|
||||
(1 << ACCT_TYPE_INCOME) |
|
||||
(1 << ACCT_TYPE_EXPENSE) |
|
||||
(1 << ACCT_TYPE_EQUITY);
|
||||
case ACCT_TYPE_STOCK:
|
||||
case ACCT_TYPE_MUTUAL:
|
||||
case ACCT_TYPE_CURRENCY:
|
||||
return
|
||||
(1 << ACCT_TYPE_STOCK) |
|
||||
(1 << ACCT_TYPE_MUTUAL) |
|
||||
(1 << ACCT_TYPE_CURRENCY);
|
||||
case ACCT_TYPE_RECEIVABLE:
|
||||
return (1 << ACCT_TYPE_RECEIVABLE);
|
||||
case ACCT_TYPE_PAYABLE:
|
||||
return (1 << ACCT_TYPE_PAYABLE);
|
||||
case ACCT_TYPE_TRADING:
|
||||
return (1 << ACCT_TYPE_TRADING);
|
||||
default:
|
||||
PERR("bad account type: %d", type);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
guint32
|
||||
xaccParentAccountTypesCompatibleWith (GNCAccountType type)
|
||||
{
|
||||
|
@ -926,6 +926,11 @@ GNCAccountType xaccAccountStringToEnum (const char* str);
|
||||
* to the local language. */
|
||||
const char * xaccAccountGetTypeStr (GNCAccountType type);
|
||||
|
||||
/** Return the bitmask of account types compatible with a given type.
|
||||
* That is, you could switch to any of the account types in the compatible
|
||||
* list without unwanted side-effects. */
|
||||
guint32 xaccAccountTypesCompatibleWith (GNCAccountType type);
|
||||
|
||||
/** Return the bitmask of parent account types compatible with a given type. */
|
||||
guint32 xaccParentAccountTypesCompatibleWith (GNCAccountType type);
|
||||
|
||||
|
@ -2189,6 +2189,7 @@ test_xaccAccountType_Stuff (void)
|
||||
}
|
||||
/* xaccParentAccountTypesCompatibleWith
|
||||
* xaccAccountTypesCompatible
|
||||
* xaccAccountTypesCompatibleWith
|
||||
guint32
|
||||
xaccParentAccountTypesCompatibleWith (GNCAccountType type)// C: 5 in 3 */
|
||||
static void
|
||||
@ -2210,6 +2211,20 @@ test_xaccAccountType_Compatibility (void)
|
||||
(1 << ACCT_TYPE_ROOT));
|
||||
guint32 equity_compat = ((1 << ACCT_TYPE_EQUITY) | (1 << ACCT_TYPE_ROOT));
|
||||
guint32 trading_compat = ((1 << ACCT_TYPE_TRADING) | (1 << ACCT_TYPE_ROOT));
|
||||
guint32 currency_compat = ((1 << ACCT_TYPE_BANK) |
|
||||
(1 << ACCT_TYPE_CASH) |
|
||||
(1 << ACCT_TYPE_ASSET) |
|
||||
(1 << ACCT_TYPE_CREDIT) |
|
||||
(1 << ACCT_TYPE_LIABILITY) |
|
||||
(1 << ACCT_TYPE_INCOME) |
|
||||
(1 << ACCT_TYPE_EXPENSE) |
|
||||
(1 << ACCT_TYPE_EQUITY));
|
||||
guint32 stock_compat = ((1 << ACCT_TYPE_STOCK) |
|
||||
(1 << ACCT_TYPE_MUTUAL) |
|
||||
(1 << ACCT_TYPE_CURRENCY));
|
||||
guint32 immutable_ar_compat = (1 << ACCT_TYPE_RECEIVABLE);
|
||||
guint32 immutable_ap_compat = (1 << ACCT_TYPE_PAYABLE);
|
||||
guint32 immutable_trading_compat = (1 << ACCT_TYPE_TRADING);
|
||||
guint32 compat;
|
||||
GNCAccountType type;
|
||||
gchar *msg1 = g_strdup_printf ("[xaccParentAccountTypesCompatibleWith()] bad account type: %d", ACCT_TYPE_ROOT);
|
||||
@ -2252,6 +2267,19 @@ test_xaccAccountType_Compatibility (void)
|
||||
g_assert (xaccAccountTypesCompatible (type, child));
|
||||
else
|
||||
g_assert (!xaccAccountTypesCompatible (type, child));
|
||||
|
||||
compat = xaccAccountTypesCompatibleWith (type);
|
||||
if (type <= ACCT_TYPE_LIABILITY ||
|
||||
(type >= ACCT_TYPE_INCOME && type <= ACCT_TYPE_EQUITY))
|
||||
g_assert_cmpint (compat, == , currency_compat);
|
||||
else if (type >= ACCT_TYPE_STOCK && type <= ACCT_TYPE_CURRENCY)
|
||||
g_assert_cmpint (compat, == , stock_compat);
|
||||
else if (type == ACCT_TYPE_RECEIVABLE)
|
||||
g_assert_cmpint (compat, == , immutable_ar_compat);
|
||||
else if (type == ACCT_TYPE_PAYABLE)
|
||||
g_assert_cmpint (compat, == , immutable_ap_compat);
|
||||
else if (type == ACCT_TYPE_TRADING)
|
||||
g_assert_cmpint (compat, == , immutable_trading_compat);
|
||||
}
|
||||
|
||||
loghandler = g_log_set_handler (logdomain, loglevel,
|
||||
|
@ -1120,17 +1120,18 @@ gnc_account_type_changed_cb (GtkTreeSelection *selection, gpointer data)
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_account_type_view_create (AccountWindow *aw)
|
||||
gnc_account_type_view_create (AccountWindow *aw, guint32 compat_types)
|
||||
{
|
||||
GtkTreeModel *model;
|
||||
GtkTreeSelection *selection;
|
||||
GtkCellRenderer *renderer;
|
||||
GtkTreeView *view;
|
||||
|
||||
aw->valid_types &= compat_types;
|
||||
if (aw->valid_types == 0)
|
||||
{
|
||||
/* no type restrictions, choose aw->type */
|
||||
aw->valid_types = xaccAccountTypesValid () | (1 << aw->type);
|
||||
aw->valid_types = compat_types | (1 << aw->type);
|
||||
aw->preferred_account_type = aw->type;
|
||||
}
|
||||
else if ((aw->valid_types & (1 << aw->type)) != 0)
|
||||
@ -1309,6 +1310,7 @@ gnc_account_window_create(AccountWindow *aw)
|
||||
GtkBuilder *builder;
|
||||
GtkTreeSelection *selection;
|
||||
const gchar *tt = _("This Account contains Transactions.\nChanging this option is not possible.");
|
||||
guint32 compat_types = xaccAccountTypesValid ();
|
||||
|
||||
ENTER("aw %p, modal %d", aw, aw->modal);
|
||||
builder = gtk_builder_new();
|
||||
@ -1413,23 +1415,23 @@ gnc_account_window_create(AccountWindow *aw)
|
||||
|
||||
/* This goes at the end so the select callback has good data. */
|
||||
aw->type_view = GTK_WIDGET(gtk_builder_get_object (builder, "type_view"));
|
||||
gnc_account_type_view_create (aw);
|
||||
|
||||
// If the account has transactions, prevent changes by displaying a label and tooltip
|
||||
// If the account has transactions, reduce the available account types
|
||||
// to change the current account type to based on the following
|
||||
// restrictions:
|
||||
// - the new account type should not force a change of commodity
|
||||
// - the old/new type is not an immutable type. Types are marked as
|
||||
// immutable if gnucash depends on details that would be lost/missing
|
||||
// if changing from/to such a type. At the time of this writing the
|
||||
// immutable types are AR, AP and trading types.
|
||||
if (xaccAccountCountSplits (aw_get_account (aw), FALSE) > 0)
|
||||
{
|
||||
GNCAccountType atype = xaccAccountGetType (aw_get_account (aw));
|
||||
GtkWidget *label = gtk_label_new (xaccAccountGetTypeStr (atype));
|
||||
GtkWidget *vbox = GTK_WIDGET(gtk_builder_get_object (builder, "type_vbox"));
|
||||
GtkWidget *parent_widget = gtk_widget_get_parent (GTK_WIDGET(aw->type_view));
|
||||
|
||||
g_object_ref (G_OBJECT(aw->type_view));
|
||||
gtk_container_remove (GTK_CONTAINER(vbox), parent_widget);
|
||||
gtk_widget_set_tooltip_text (label, tt);
|
||||
gtk_box_pack_start (GTK_BOX(vbox), label, FALSE, FALSE, 0);
|
||||
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
||||
gtk_widget_show (label);
|
||||
compat_types = xaccAccountTypesCompatibleWith (atype);
|
||||
if (!compat_types)
|
||||
compat_types = xaccAccountTypesValid ();
|
||||
}
|
||||
gnc_account_type_view_create (aw, compat_types);
|
||||
|
||||
gnc_restore_window_size (GNC_PREFS_GROUP, GTK_WINDOW(aw->dialog));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user