gnucash maint: Multiple changes pushed
John Ralls
jralls at code.gnucash.org
Fri Dec 3 16:46:16 EST 2021
Updated via https://github.com/Gnucash/gnucash/commit/ae7eaad0 (commit)
via https://github.com/Gnucash/gnucash/commit/8ad29fea (commit)
from https://github.com/Gnucash/gnucash/commit/6f09eae0 (commit)
commit ae7eaad018d0482fe2fcb8fb54c92c65f6663238
Merge: 6f09eae08 8ad29feab
Author: John Ralls <jralls at ceridwen.us>
Date: Fri Dec 3 13:44:50 2021 -0800
Merge Chris Good's 'maintBug797678OfxAppend' into maint.
commit 8ad29feaba539f6bd90f558ac76d50671f808820
Author: goodvibes2 <goodchris96 at gmail.com>
Date: Thu Sep 30 15:28:28 2021 +1000
Bug797678 OFX import should append not replace, existing Notes & Desc
Add an "Append" checkbox to the bottom of the "Generic import
transaction matcher" window to the left of the "Reconcile after match"
checkbox.
When ticked, this causes the imported Description/Notes to be appended
to the matched transaction Description/Notes respectively.
The selected ticked/unticked state of the "Append" checkbox is saved in
a key value pair for the import account, so the next import for that
account will automatically default it to the saved state.
As these mods are limited to the code for the matcher window, this
should work for all the imports that use it - ie ofx & csv file imports
(both tested) & aqbanking (cannot test).
diff --git a/gnucash/gtkbuilder/dialog-import.glade b/gnucash/gtkbuilder/dialog-import.glade
index b32a5f842..696a5fa60 100644
--- a/gnucash/gtkbuilder/dialog-import.glade
+++ b/gnucash/gtkbuilder/dialog-import.glade
@@ -960,7 +960,7 @@
</child>
<child>
<object class="GtkCheckButton" id="show_matched_info_button">
- <property name="label" translatable="yes">Show _matched information</property>
+ <property name="label" translatable="yes">Show matched _information</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@@ -973,9 +973,25 @@
<property name="position">2</property>
</packing>
</child>
+ <child>
+ <object class="GtkCheckButton" id="append_desc_notes_button">
+ <property name="label" translatable="yes">A_ppend</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="tooltip_text" translatable="yes">When Updating and Clearing a matched transaction, append the imported Description and Notes to the matched Description and Notes instead of replacing them.</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
<child>
<object class="GtkCheckButton" id="reconcile_after_close_button">
- <property name="label" translatable="yes">Reconcile after match</property>
+ <property name="label" translatable="yes">_Reconcile after match</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="no_show_all">True</property>
@@ -985,7 +1001,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">3</property>
+ <property name="position">4</property>
</packing>
</child>
</object>
diff --git a/gnucash/import-export/import-backend.c b/gnucash/import-export/import-backend.c
index d9f86f6cc..c17487a22 100644
--- a/gnucash/import-export/import-backend.c
+++ b/gnucash/import-export/import-backend.c
@@ -95,6 +95,9 @@ struct _transactioninfo
/* Reference id to link gnc transaction to external object. E.g. aqbanking job id. */
guint32 ref_id;
+
+ /* When updating a matched transaction, append Description and Notes instead of replacing */
+ gboolean append_text;
};
/* Some simple getters and setters for the above data types. */
@@ -240,6 +243,15 @@ gnc_import_TransInfo_set_ref_id (GNCImportTransInfo *info,
}
+void
+gnc_import_TransInfo_set_append_text (GNCImportTransInfo *info,
+ gboolean append_text)
+{
+ g_assert (info);
+ info->append_text = append_text;
+}
+
+
Split *
gnc_import_MatchInfo_get_split (const GNCImportMatchInfo * info)
{
@@ -827,6 +839,77 @@ void split_find_match (GNCImportTransInfo * trans_info,
/***********************************************************************
*/
+/* append the imported transaction description to the matched transaction description */
+static void
+desc_append (Transaction* selected_match_trans, Transaction* imp_trans)
+{
+ gchar* tmp = g_strconcat( xaccTransGetDescription (selected_match_trans),
+ "|",
+ xaccTransGetDescription (imp_trans),
+ NULL);
+ xaccTransSetDescription (selected_match_trans, tmp);
+ g_free (tmp);
+}
+
+/* append the imported transaction notes to the matched transaction notes */
+static void
+notes_append (Transaction* selected_match_trans, Transaction* imp_trans)
+{
+ gchar* tmp = g_strconcat (xaccTransGetNotes (selected_match_trans),
+ "|",
+ xaccTransGetNotes (imp_trans),
+ NULL);
+ xaccTransSetNotes (selected_match_trans, tmp);
+ g_free (tmp);
+}
+
+/* Append or replace transaction description and notes
+ * depending on the Append checkbox
+ */
+static void
+update_desc_and_notes (const GNCImportTransInfo* trans_info)
+{
+ GNCImportMatchInfo* selected_match =
+ gnc_import_TransInfo_get_selected_match (trans_info);
+ Transaction* imp_trans = gnc_import_TransInfo_get_trans (trans_info);
+
+ if (trans_info->append_text)
+ {
+ gchar* desc_imported = g_utf8_normalize (xaccTransGetDescription (
+ imp_trans), -1, G_NORMALIZE_ALL);
+ gchar* desc_matched = g_utf8_normalize (xaccTransGetDescription (
+ selected_match->trans), -1, G_NORMALIZE_ALL);
+ gchar* note_imported = g_utf8_normalize (xaccTransGetNotes (
+ imp_trans), -1, G_NORMALIZE_ALL);
+ gchar* note_matched = g_utf8_normalize (xaccTransGetNotes (
+ selected_match->trans), -1, G_NORMALIZE_ALL);
+
+ // Append if desc_imported not already in desc_matched
+ if (g_utf8_strlen (desc_imported, -1) > g_utf8_strlen (desc_matched, -1) ||
+ !strstr (desc_matched, desc_imported))
+ desc_append (selected_match->trans, imp_trans);
+
+ // Append if note_imported not already in note_matched
+ if (g_utf8_strlen (note_imported, -1) > g_utf8_strlen (note_matched, -1) ||
+ !strstr (note_matched, note_imported))
+ notes_append (selected_match->trans, imp_trans);
+
+ g_free(desc_imported);
+ g_free(desc_matched);
+ g_free(note_imported);
+ g_free(note_matched);
+ }
+ else
+ {
+ // replace the matched transaction description with the imported transaction description
+ xaccTransSetDescription (selected_match->trans,
+ xaccTransGetDescription (imp_trans));
+ // replace the matched transaction notes with the imported transaction notes
+ xaccTransSetNotes (selected_match->trans,
+ xaccTransGetNotes (imp_trans));
+ }
+}
+
/** /brief -- Processes one match
according to its selected action. */
gboolean
@@ -944,13 +1027,7 @@ gnc_import_process_trans_item (GncImportMatchMap *matchmap,
to balance the transaction */
}
- xaccTransSetDescription(selected_match->trans,
- xaccTransGetDescription(
- gnc_import_TransInfo_get_trans(trans_info)));
-
- xaccTransSetNotes(selected_match->trans,
- xaccTransGetNotes(
- gnc_import_TransInfo_get_trans(trans_info)));
+ update_desc_and_notes( trans_info);
if (xaccSplitGetReconcile(selected_match->split) == NREC)
{
diff --git a/gnucash/import-export/import-backend.h b/gnucash/import-export/import-backend.h
index b524d1835..cb9c72663 100644
--- a/gnucash/import-export/import-backend.h
+++ b/gnucash/import-export/import-backend.h
@@ -238,6 +238,11 @@ void
gnc_import_TransInfo_set_ref_id (GNCImportTransInfo *info,
guint32 ref_id);
+/** Set the append_text for this TransInfo. */
+void
+gnc_import_TransInfo_set_append_text (GNCImportTransInfo *info,
+ gboolean append_text);
+
/**@}*/
/** @name Getters/Setters for GNCImportMatchInfo */
diff --git a/gnucash/import-export/import-main-matcher.c b/gnucash/import-export/import-main-matcher.c
index e6c9df361..c0f11ae33 100644
--- a/gnucash/import-export/import-main-matcher.c
+++ b/gnucash/import-export/import-main-matcher.c
@@ -72,6 +72,7 @@ struct _main_matcher_info
GtkTreeViewColumn *memo_column;
GtkWidget *show_account_column;
GtkWidget *show_matched_info;
+ GtkWidget *append_text; // Update+Clear: Append import Desc/Notes to matched Desc/Notes
GtkWidget *reconcile_after_close;
gboolean add_toggled; // flag to indicate that add has been toggled to stop selection
gint id;
@@ -444,7 +445,22 @@ resolve_conflicts (GNCImportMainMatcher *info)
void
gnc_gen_trans_list_show_all (GNCImportMainMatcher *info)
{
+ GNCImportTransInfo* trans_info;
+ Account* account;
+ Split* first_split;
+ GSList* temp_trans_list;
+
g_assert (info);
+
+ // Set initial state of Append checkbox to same as last import for this account.
+ // Get the import account from the first split in first transaction.
+ temp_trans_list = info->temp_trans_list;
+ trans_info = temp_trans_list->data;
+ first_split = gnc_import_TransInfo_get_fsplit (trans_info);
+ account = xaccSplitGetAccount(first_split);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (info->append_text),
+ xaccAccountGetAppendText(account));
+
gnc_gen_trans_list_create_matches (info);
resolve_conflicts (info);
gtk_widget_show_all (GTK_WIDGET(info->main_widget));
@@ -457,6 +473,9 @@ on_matcher_ok_clicked (GtkButton *button, GNCImportMainMatcher *info)
GtkTreeModel *model;
GtkTreeIter iter;
GNCImportTransInfo *trans_info;
+ gboolean append_text = gtk_toggle_button_get_active ((GtkToggleButton*) info->append_text);
+ gboolean first_tran = TRUE;
+ gpointer user_data = info->user_data;
g_assert (info);
@@ -479,6 +498,20 @@ on_matcher_ok_clicked (GtkButton *button, GNCImportMainMatcher *info)
DOWNLOADED_COL_DATA, &trans_info,
-1);
+ // Allow the backend to know if the Append checkbox is ticked or unticked
+ // by propagating info->append_text to every trans_info->append_text
+ gnc_import_TransInfo_set_append_text( trans_info, append_text);
+
+ // When processing the first transaction,
+ // save the state of the Append checkbox to an account kvp so the same state can be
+ // defaulted next time this account is imported.
+ // Get the import account from the first split.
+ if (first_tran)
+ {
+ Split* first_split = gnc_import_TransInfo_get_fsplit (trans_info);
+ xaccAccountSetAppendText (xaccSplitGetAccount(first_split), append_text);
+ first_tran = FALSE;
+ }
// Note: if there's only 1 split (unbalanced) one will be created with the unbalanced account,
// and for that account the defer balance will not be set. So things will be slow.
@@ -1222,7 +1255,9 @@ gnc_gen_trans_common_setup (GNCImportMainMatcher *info,
g_signal_connect (G_OBJECT(info->show_matched_info), "toggled",
G_CALLBACK(show_matched_info_toggled_cb), info);
- // Create the checkbox, but do not show it by default.
+ info->append_text = GTK_WIDGET(gtk_builder_get_object (builder, "append_desc_notes_button"));
+
+ // Create the checkbox, but do not show it unless there are transactions
info->reconcile_after_close = GTK_WIDGET(gtk_builder_get_object (builder, "reconcile_after_close_button"));
show_update = gnc_import_Settings_get_action_update_enabled (info->user_settings);
@@ -1905,6 +1940,13 @@ gnc_gen_trans_list_widget (GNCImportMainMatcher *info)
return info->main_widget;
}
+GtkWidget *
+gnc_gen_trans_list_append_text_widget (GNCImportMainMatcher *info)
+{
+ g_assert (info);
+ return info->append_text;
+}
+
gboolean
query_tooltip_tree_view_cb (GtkWidget *widget, gint x, gint y,
gboolean keyboard_tip,
diff --git a/gnucash/import-export/import-main-matcher.h b/gnucash/import-export/import-main-matcher.h
index 6b20c3d4f..490d54c44 100644
--- a/gnucash/import-export/import-main-matcher.h
+++ b/gnucash/import-export/import-main-matcher.h
@@ -189,6 +189,13 @@ gboolean gnc_gen_trans_list_run (GNCImportMainMatcher *info);
*/
GtkWidget *gnc_gen_trans_list_widget (GNCImportMainMatcher *info);
+/** Returns the append_text widget of this dialog.
+ * @param info A pointer to a the GNCImportMainMatcher structure.
+ * @return A GtkWidget pointer to the append_text widget.
+ */
+GtkWidget *
+gnc_gen_trans_list_append_text_widget (GNCImportMainMatcher *info);
+
/** Checks whether there are no transactions to match.
* @param info A pointer to a the GNCImportMainMatcher structure.
* @return A boolean indicating whether the transaction list is empty.
diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index 03e461d59..ee375d304 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -65,6 +65,7 @@ static const std::string KEY_INCLUDE_CHILDREN("include-children");
static const std::string KEY_POSTPONE("postpone");
static const std::string KEY_LOT_MGMT("lot-mgmt");
static const std::string KEY_ONLINE_ID("online_id");
+static const std::string KEY_IMP_APPEND_TEXT("import-append-text");
static const std::string AB_KEY("hbci");
static const std::string AB_ACCOUNT_ID("account-id");
static const std::string AB_ACCOUNT_UID("account-uid");
@@ -116,6 +117,7 @@ enum
PROP_LOT_NEXT_ID, /* KVP */
PROP_ONLINE_ACCOUNT, /* KVP */
+ PROP_IMP_APPEND_TEXT, /* KVP */
PROP_IS_OPENING_BALANCE, /* KVP */
PROP_OFX_INCOME_ACCOUNT, /* KVP */
PROP_AB_ACCOUNT_ID, /* KVP */
@@ -484,6 +486,9 @@ gnc_account_get_property (GObject *object,
case PROP_ONLINE_ACCOUNT:
qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {KEY_ONLINE_ID});
break;
+ case PROP_IMP_APPEND_TEXT:
+ g_value_set_boolean(value, xaccAccountGetAppendText(account));
+ break;
case PROP_OFX_INCOME_ACCOUNT:
qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {KEY_ASSOC_INCOME_ACCOUNT});
break;
@@ -613,6 +618,9 @@ gnc_account_set_property (GObject *object,
case PROP_ONLINE_ACCOUNT:
qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {KEY_ONLINE_ID});
break;
+ case PROP_IMP_APPEND_TEXT:
+ xaccAccountSetAppendText(account, g_value_get_boolean(value));
+ break;
case PROP_OFX_INCOME_ACCOUNT:
qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {KEY_ASSOC_INCOME_ACCOUNT});
break;
@@ -1062,6 +1070,16 @@ gnc_account_class_init (AccountClass *klass)
NULL,
static_cast<GParamFlags>(G_PARAM_READWRITE)));
+ g_object_class_install_property
+ (gobject_class,
+ PROP_IMP_APPEND_TEXT,
+ g_param_spec_boolean ("import-append-text",
+ "Import Append Text",
+ "Saved state of Append checkbox for setting initial "
+ "value next time this account is imported.",
+ FALSE,
+ static_cast<GParamFlags>(G_PARAM_READWRITE)));
+
g_object_class_install_property(
gobject_class,
PROP_OFX_INCOME_ACCOUNT,
@@ -4228,6 +4246,18 @@ xaccAccountSetPlaceholder (Account *acc, gboolean val)
set_boolean_key(acc, {"placeholder"}, val);
}
+gboolean
+xaccAccountGetAppendText (const Account *acc)
+{
+ return boolean_from_key(acc, {"import-append-text"});
+}
+
+void
+xaccAccountSetAppendText (Account *acc, gboolean val)
+{
+ set_boolean_key(acc, {"import-append-text"}, val);
+}
+
gboolean
xaccAccountGetIsOpeningBalance (const Account *acc)
{
diff --git a/libgnucash/engine/Account.h b/libgnucash/engine/Account.h
index 6822bfd65..19093036c 100644
--- a/libgnucash/engine/Account.h
+++ b/libgnucash/engine/Account.h
@@ -1217,6 +1217,30 @@ gboolean xaccAccountGetPlaceholder (const Account *account);
* @param val The new state for the account's "placeholder" flag. */
void xaccAccountSetPlaceholder (Account *account, gboolean val);
+/** @name Account Append Text flag
+ @{
+*/
+
+/** Get the "import-append-text" flag for an account. This is the saved
+ * state of the Append checkbox in the "Generic import transaction matcher"
+ * used to set the initial state of the Append checkbox next time this
+ * account is imported.
+ *
+ * @param account The account whose flag should be retrieved.
+ *
+ * @return The current state of the account's "import-append-text" flag. */
+gboolean xaccAccountGetAppendText (const Account *account);
+
+/** Set the "import-append-text" flag for an account. This is the saved
+ * state of the Append checkbox in the "Generic import transaction matcher"
+ * used to set the initial state of the Append checkbox next time this
+ * account is imported.
+ *
+ * @param account The account whose flag should be retrieved.
+ *
+ * @param val The new state for the account's "import-append-text" flag. */
+void xaccAccountSetAppendText (Account *account, gboolean val);
+
/** Get the "opening-balance" flag for an account. If this flag is set
* then the account is used for opening balance transactions.
*
Summary of changes:
gnucash/gtkbuilder/dialog-import.glade | 22 ++++++-
gnucash/import-export/import-backend.c | 91 ++++++++++++++++++++++++++---
gnucash/import-export/import-backend.h | 5 ++
gnucash/import-export/import-main-matcher.c | 44 +++++++++++++-
gnucash/import-export/import-main-matcher.h | 7 +++
libgnucash/engine/Account.cpp | 30 ++++++++++
libgnucash/engine/Account.h | 24 ++++++++
7 files changed, 212 insertions(+), 11 deletions(-)
More information about the gnucash-changes
mailing list