Bug 771667 - Change reconciled splits warning

This patch displays two distinct warnings when changing protected
fields of a transaction that contains reconciled splits. If the fields
date, num and description are changed, then the warning list the
accounts that have reconciled splits and also advises that they will be
unreconciled after editing the transaction. If the fields account,
transfer, debit or credit are changed then the warning advises that the
split will be unreconciled after editing the transaction.

There is still just one warning preference as it is all to do with
fields protected by reconciliation.
This commit is contained in:
Robert Fewell 2017-11-29 12:24:53 +00:00
parent 30f7f2fcf7
commit f25c065b20
4 changed files with 125 additions and 23 deletions

View File

@ -512,6 +512,10 @@ gnc_split_register_move_cursor (VirtualLocation *p_new_virt_loc,
info->cursor_hint_cursor_class = new_class;
}
/* change from split row to trans row */
if (old_class != new_class)
info->change_confirmed = FALSE;
if (old_split != new_split)
{
info->change_confirmed = FALSE;
@ -1569,6 +1573,13 @@ transaction_changed_confirm(VirtualLocation *p_new_virt_loc,
Split *trans_split;
CursorClass new_class;
/* Clear unreconcile split list */
if (reg->unrecn_splits != NULL)
{
g_list_free (reg->unrecn_splits);
reg->unrecn_splits = NULL;
}
new_split = gnc_split_register_get_split (reg, virt_loc->vcell_loc);
trans_split = gnc_split_register_get_trans_split (reg,
virt_loc->vcell_loc,

View File

@ -1993,7 +1993,9 @@ gnc_split_register_confirm (VirtualLocation virt_loc, gpointer user_data)
Split *split;
char recn;
const char *cell_name;
gboolean change_ok;
gboolean protected_split_cell, protected_trans_cell;
const gchar *title = NULL;
const gchar *message = NULL;
/* This assumes we reset the flag whenever we change splits.
* This happens in gnc_split_register_move_cursor(). */
@ -2007,6 +2009,10 @@ gnc_split_register_confirm (VirtualLocation virt_loc, gpointer user_data)
trans = xaccSplitGetParent (split);
if (xaccTransWarnReadOnly(trans))
return FALSE;
if (!xaccTransHasReconciledSplits (trans))
return TRUE;
if (gnc_table_layout_get_cell_changed (reg->table->layout, RECN_CELL, FALSE))
recn = gnc_recn_cell_get_flag
((RecnCell *) gnc_table_layout_get_cell (reg->table->layout, RECN_CELL));
@ -2016,30 +2022,66 @@ gnc_split_register_confirm (VirtualLocation virt_loc, gpointer user_data)
/* What Cell are we in */
cell_name = gnc_table_get_cell_name (reg->table, virt_loc);
/* These cells can be changed */
change_ok = (g_strcmp0(cell_name, "notes") == 0) || (g_strcmp0(cell_name, "memo") == 0) || (g_strcmp0(cell_name, "action") == 0);
/* if we change a transfer cell, we want the other split */
if (g_strcmp0(cell_name, "transfer") == 0)
recn = xaccSplitGetReconcile (xaccSplitGetOtherSplit (split));
if ((recn == YREC || xaccTransHasReconciledSplits (trans)) && !change_ok)
/* These cells can not be changed */
protected_split_cell = (g_strcmp0(cell_name, "account") == 0) || (g_strcmp0(cell_name, "transfer") == 0) || (g_strcmp0(cell_name, "debit") == 0) || (g_strcmp0(cell_name, "credit") == 0);
protected_trans_cell = (g_strcmp0(cell_name, "date") == 0) || (g_strcmp0(cell_name, "num") == 0) || (g_strcmp0(cell_name, "description") == 0);
PINFO ("Protected transaction cell %d, Protected split cell %d, Cell is %s", protected_trans_cell, protected_split_cell, cell_name);
if (protected_trans_cell)
{
GList *node;
gchar *acc_list = NULL;
gchar *message_format;
for (node = xaccTransGetSplitList (trans); node; node = node->next)
{
Split *split = node->data;
if (xaccSplitGetReconcile (split) == YREC)
{
Account *acc = xaccSplitGetAccount (split);
gchar *name = gnc_account_get_full_name (acc);
if (acc_list == NULL)
acc_list = g_strconcat ("\n", name, NULL);
else
{
gchar *acc_list_copy = g_strdup(acc_list);
g_free (acc_list);
acc_list = g_strconcat (acc_list_copy, "\n", name, NULL);
g_free (acc_list_copy);
}
g_free (name);
}
}
title = _("Change Transaction containing a reconciled split?");
message_format =
_("You are about to change a protected transaction field as it contains reconciled splits in the following accounts... \n%s"
"\n\nAfter transaction editing is completed, all reconciled splits will be unreconcile and "
"this might make future reconciliation difficult! Continue with this change?");
message = g_strdup_printf (message_format, acc_list);
g_free (acc_list);
}
if (protected_split_cell)
{
title = _("Change reconciled split?");
message =
_("You are about to change a protected field of a reconciled split. "
"After transaction editing is completed, this split will be unreconciled "
"and this might make future reconciliation difficult! Continue with this change?");
}
if ((recn == YREC && protected_split_cell) || protected_trans_cell)
{
GtkWidget *dialog, *window;
gint response;
const gchar *title;
const gchar *message;
if(recn == YREC)
{
title = _("Change reconciled split?");
message =
_("You are about to change a reconciled split. Doing so might make "
"future reconciliation difficult! Continue with this change?");
}
else
{
title = _("Change split linked to a reconciled split?");
message =
_("You are about to change a split that is linked to a reconciled split. "
"Doing so might make future reconciliation difficult! Continue with this change?");
}
/* Does the user want to be warned? */
window = gnc_split_register_get_parent(reg);
@ -2051,16 +2093,36 @@ gnc_split_register_confirm (VirtualLocation virt_loc, gpointer user_data)
"%s", title);
gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
"%s", message);
gtk_dialog_add_button(GTK_DIALOG(dialog), _("Chan_ge Split"),
if (protected_split_cell)
gtk_dialog_add_button(GTK_DIALOG(dialog), _("Chan_ge Split"),
GTK_RESPONSE_YES);
else
gtk_dialog_add_button(GTK_DIALOG(dialog), _("Chan_ge Transaction"),
GTK_RESPONSE_YES);
response = gnc_dialog_run(GTK_DIALOG(dialog), GNC_PREF_WARN_REG_RECD_SPLIT_MOD);
gtk_widget_destroy(dialog);
if (response != GTK_RESPONSE_YES)
return FALSE;
// Response is Change, so record the splits
if (recn == YREC && protected_split_cell)
{
if (g_list_index (reg->unrecn_splits, split) == -1)
reg->unrecn_splits = g_list_append (reg->unrecn_splits, split);
}
if (protected_trans_cell)
{
if (reg->unrecn_splits != NULL)
g_list_free (reg->unrecn_splits);
reg->unrecn_splits = g_list_copy (xaccTransGetSplitList (trans));
}
PINFO ("Unreconcile split list length is %d", g_list_length(reg->unrecn_splits));
info->change_confirmed = TRUE;
}
return TRUE;
}

View File

@ -1814,6 +1814,25 @@ gnc_split_register_save (SplitRegister *reg, gboolean do_commit)
xaccTransCommitEdit (trans);
}
/* If there are splits in the unreconcile list and we are committing
* we need to unreconcile them */
if (do_commit && (reg->unrecn_splits != NULL))
{
GList *node;
PINFO ("Unreconcile %d splits of reconciled transaction", g_list_length (reg->unrecn_splits));
for (node = reg->unrecn_splits; node; node = node->next)
{
Split *split = node->data;
if (xaccSplitGetReconcile (split) == YREC)
xaccSplitSetReconcile (split, NREC);
}
g_list_free (reg->unrecn_splits);
reg->unrecn_splits = NULL;
}
gnc_table_clear_current_cursor_changes (reg->table);
gnc_resume_gui_refresh ();
@ -2715,6 +2734,8 @@ gnc_split_register_init (SplitRegister *reg,
reg->sr_info = NULL;
reg->unrecn_splits = NULL;
reg->type = type;
reg->style = style;
reg->use_double_line = use_double_line;
@ -2855,6 +2876,12 @@ gnc_split_register_destroy_info (SplitRegister *reg)
if (reg == NULL)
return;
if (reg->unrecn_splits != NULL)
{
g_list_free (reg->unrecn_splits);
reg->unrecn_splits = NULL;
}
info = reg->sr_info;
if (!info)
return;

View File

@ -252,6 +252,8 @@ struct split_register
gboolean is_template;
gboolean do_auto_complete; /**< whether to use auto-completion */
SplitList *unrecn_splits; /**< list of splits to unreconcile after transaction edit */
SRInfo * sr_info; /**< private data; outsiders should not access this */
};