gnucash stable: Bug 799734 - mapped OFX income account not listed
Robert Fewell
bobit at code.gnucash.org
Fri Mar 13 06:29:35 EDT 2026
Updated via https://github.com/Gnucash/gnucash/commit/62af7f0d (commit)
from https://github.com/Gnucash/gnucash/commit/8538dcf9 (commit)
commit 62af7f0d6d479dffcaebfcecd4a8af13aa49fc88
Author: Robert Fewell <14uBobIT at gmail.com>
Date: Mon Feb 16 16:50:58 2026 +0000
Bug 799734 - mapped OFX income account not listed
Change the Import Map Editor to look for the KVP slot
"ofx/associated-income-account" so it can be listed. The account
reference stored is a GUID so add a function to retrieve that so the
existing gnc_account_delete_map_entry function can be used to remove it.
diff --git a/gnucash/gnome/dialog-imap-editor.c b/gnucash/gnome/dialog-imap-editor.c
index 581ef2c766..c20d5a7b4d 100644
--- a/gnucash/gnome/dialog-imap-editor.c
+++ b/gnucash/gnome/dialog-imap-editor.c
@@ -703,6 +703,97 @@ get_account_info_nbayes (ImapDialog *imap_dialog, GList *accts)
}
}
+static void
+add_online_entry_to_store (ImapDialog *imap_dialog, GtkTreeIter *toplevel,
+ const gchar *based_on, GncImapInfo *imapInfo)
+{
+ // Add top level entry and pass iter to add_to_store
+ gtk_tree_store_append (GTK_TREE_STORE(imap_dialog->model), toplevel, NULL);
+ add_to_store (imap_dialog, toplevel, based_on, imapInfo);
+
+ imapInfo->map_account = NULL;
+}
+
+static void
+check_online_id (ImapDialog *imap_dialog, GtkTreeIter *toplevel, Account *acc, GncImapInfo *imapInfo)
+{
+ // Check for online_id
+ gchar *head = "online_id";
+ gchar *text = gnc_account_get_map_entry (acc, head, NULL);
+
+ if (!text)
+ return;
+
+ // Save source account
+ imapInfo->source_account = acc;
+ imapInfo->head = head;
+
+ if (text && *text)
+ imapInfo->map_account = imapInfo->source_account;
+
+ imapInfo->match_string = text;
+
+ add_online_entry_to_store (imap_dialog, toplevel, _("Online Id"), imapInfo);
+
+ g_free (text);
+}
+
+static void
+check_hbci (ImapDialog *imap_dialog, GtkTreeIter *toplevel, Account *acc, GncImapInfo *imapInfo)
+{
+ // Check for aqbanking hbci
+ gchar *head = "hbci";
+ gchar *hbci_account_id = gnc_account_get_map_entry (acc, head, "account-id");
+ gchar *hbci_bank_code = gnc_account_get_map_entry (acc, head, "bank-code");
+
+ if (!hbci_account_id || !hbci_bank_code)
+ return;
+
+ gchar *text = g_strconcat (hbci_bank_code, ",", hbci_account_id, NULL);
+
+ // Save source account
+ imapInfo->source_account = acc;
+ imapInfo->head = head;
+
+ if (text && *text)
+ imapInfo->map_account = imapInfo->source_account;
+
+ imapInfo->match_string = text;
+
+ add_online_entry_to_store (imap_dialog, toplevel, _("Online HBCI"), imapInfo);
+
+ g_free (hbci_account_id);
+ g_free (hbci_bank_code);
+ g_free (text);
+}
+
+static void
+check_ofx_account (ImapDialog *imap_dialog, GtkTreeIter *toplevel, Account *acc, GncImapInfo *imapInfo)
+{
+ // Check for ofx income account
+ gchar *head = "ofx/associated-income-account";
+ GncGUID *acct_guid = gnc_account_get_map_guid_entry (acc, head, NULL);
+
+ if (!acct_guid)
+ return;
+
+ gchar *text = guid_to_string (acct_guid);
+
+ // Save source account
+ imapInfo->source_account = acc;
+ imapInfo->head = head;
+
+ if (text && *text)
+ imapInfo->map_account = xaccAccountLookup (acct_guid, gnc_get_current_book ());
+
+ imapInfo->match_string = text;
+
+ add_online_entry_to_store (imap_dialog, toplevel, _("OFX Income Account"), imapInfo);
+
+ guid_free (acct_guid);
+ g_free (text);
+}
+
static void
get_account_info_online (ImapDialog *imap_dialog, GList *accts)
{
@@ -711,65 +802,24 @@ get_account_info_online (ImapDialog *imap_dialog, GList *accts)
GncImapInfo imapInfo;
+ imapInfo.map_account = NULL;
+ imapInfo.source_account = NULL;
+ imapInfo.category = " ";
+ imapInfo.count = " ";
+
/* Go through list of accounts */
for (ptr = accts; ptr; ptr = g_list_next (ptr))
{
- gchar *hbci_account_id = NULL;
- gchar *hbci_bank_code = NULL;
- gchar *text = NULL;
Account *acc = ptr->data;
// Check for online_id
- text = gnc_account_get_map_entry (acc, "online_id", NULL);
-
- if (text != NULL)
- {
- // Save source account
- imapInfo.source_account = acc;
- imapInfo.head = "online_id";
- imapInfo.category = " ";
-
- if (g_strcmp0 (text, "") == 0)
- imapInfo.map_account = NULL;
- else
- imapInfo.map_account = imapInfo.source_account;
-
- imapInfo.match_string = text;
- imapInfo.count = " ";
-
- // Add top level entry and pass iter to add_to_store
- gtk_tree_store_append (GTK_TREE_STORE(imap_dialog->model), &toplevel, NULL);
- add_to_store (imap_dialog, &toplevel, _("Online Id"), &imapInfo);
- }
- g_free (text);
+ check_online_id (imap_dialog, &toplevel, acc, &imapInfo);
// Check for aqbanking hbci
- hbci_account_id = gnc_account_get_map_entry (acc, "hbci", "account-id");
- hbci_bank_code = gnc_account_get_map_entry (acc, "hbci", "bank-code");
- text = g_strconcat (hbci_bank_code, ",", hbci_account_id, NULL);
+ check_hbci (imap_dialog, &toplevel, acc, &imapInfo);
- if ((hbci_account_id != NULL) || (hbci_bank_code != NULL))
- {
- // Save source account
- imapInfo.source_account = acc;
- imapInfo.head = "hbci";
- imapInfo.category = " ";
-
- if (g_strcmp0 (text, "") == 0)
- imapInfo.map_account = NULL;
- else
- imapInfo.map_account = imapInfo.source_account;
-
- imapInfo.match_string = text;
- imapInfo.count = " ";
-
- // Add top level entry and pass iter to add_to_store
- gtk_tree_store_append (GTK_TREE_STORE(imap_dialog->model), &toplevel, NULL);
- add_to_store (imap_dialog, &toplevel, _("Online HBCI"), &imapInfo);
- }
- g_free (hbci_account_id);
- g_free (hbci_bank_code);
- g_free (text);
+ // Check for ofx income account
+ check_ofx_account (imap_dialog, &toplevel, acc, &imapInfo);
}
}
diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index e6ea9f640d..019c613a53 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -2583,6 +2583,13 @@ get_kvp_int64_path (const Account *acc, const Path& path)
return qof_instance_get_path_kvp<int64_t> (QOF_INSTANCE(acc), path);
}
+static GncGUID*
+get_kvp_guid_path (const Account *acc, const Path& path)
+{
+ auto val{qof_instance_get_path_kvp<GncGUID*> (QOF_INSTANCE(acc), path)};
+ return val ? guid_copy(*val) : nullptr;
+}
+
void
xaccAccountSetColor (Account *acc, const char *str)
{
@@ -5688,6 +5695,13 @@ gnc_account_get_map_entry (Account *acc, const char *head, const char *category)
get_kvp_string_path (acc, {head}));
}
+GncGUID *
+gnc_account_get_map_guid_entry (Account *acc, const char *head, const char *category)
+{
+ return category ?
+ get_kvp_guid_path (acc, {head, category}) :
+ get_kvp_guid_path (acc, {head});
+}
void
gnc_account_delete_map_entry (Account *acc, char *head, char *category,
diff --git a/libgnucash/engine/Account.h b/libgnucash/engine/Account.h
index f748588735..0043d6a410 100644
--- a/libgnucash/engine/Account.h
+++ b/libgnucash/engine/Account.h
@@ -1648,6 +1648,11 @@ typedef enum
*/
gchar *gnc_account_get_map_entry (Account *acc, const char *head, const char *category);
+ /** Returns the guid pointed to by head and category for the Account, free
+ * the returned guid
+ */
+ GncGUID *gnc_account_get_map_guid_entry (Account *acc, const char *head, const char *category);
+
/** Delete the entry for Account pointed to by head,category and match_string,
* if empty is TRUE then use delete if empty
*/
diff --git a/libgnucash/engine/test/utest-Account.cpp b/libgnucash/engine/test/utest-Account.cpp
index da8d240b63..fc52032ba1 100644
--- a/libgnucash/engine/test/utest-Account.cpp
+++ b/libgnucash/engine/test/utest-Account.cpp
@@ -1366,6 +1366,30 @@ test_gnc_account_get_map_entry (Fixture *fixture, gconstpointer pData)
xaccAccountDestroy (account);
}
+static void
+test_gnc_account_get_map_guid_entry (Fixture *fixture, gconstpointer pData)
+{
+ Account *account = xaccMallocAccount (gnc_account_get_book (fixture->acct));
+ const GncGUID *account_guid = xaccAccountGetGUID (account);
+
+ xaccAccountBeginEdit (fixture->acct);
+ qof_instance_set (QOF_INSTANCE(fixture->acct), "ofx-income-account", account_guid, nullptr);
+ xaccAccountCommitEdit (fixture->acct);
+
+ GncGUID *guid = gnc_account_get_map_guid_entry (fixture->acct, "ofx/associated-income-account", nullptr);
+ g_assert_true (guid_equal (account_guid, guid));
+ guid_free (guid);
+
+ gnc_account_delete_map_entry (fixture->acct, "ofx/associated-income-account", nullptr, nullptr, false);
+
+ guid = gnc_account_get_map_guid_entry (fixture->acct, "ofx/associated-income-account", nullptr);
+ g_assert_true (!guid);
+ guid_free (guid);
+
+ xaccAccountBeginEdit (account);
+ xaccAccountDestroy (account);
+}
+
static void
test_gnc_account_insert_remove_split (Fixture *fixture, gconstpointer pData)
{
@@ -2869,6 +2893,7 @@ test_suite_account (void)
// GNC_TEST_ADD (suitename, "xaccAccountEqual", Fixture, NULL, setup, test_xaccAccountEqual, teardown );
GNC_TEST_ADD (suitename, "gnc account kvp getters & setters", Fixture, NULL, setup, test_gnc_account_kvp_setters_getters, teardown );
GNC_TEST_ADD (suitename, "test_gnc_account_get_map_entry", Fixture, NULL, setup, test_gnc_account_get_map_entry, teardown );
+ GNC_TEST_ADD (suitename, "test_gnc_account_get_map_guid_entry", Fixture, NULL, setup, test_gnc_account_get_map_guid_entry, teardown );
GNC_TEST_ADD (suitename, "gnc account insert & remove split", Fixture, NULL, setup, test_gnc_account_insert_remove_split, teardown );
GNC_TEST_ADD (suitename, "xaccAccount Insert and Remove Lot", Fixture, &good_data, setup, test_xaccAccountInsertRemoveLot, teardown );
GNC_TEST_ADD (suitename, "xaccAccountRecomputeBalance", Fixture, &some_data, setup, test_xaccAccountRecomputeBalance, teardown );
Summary of changes:
gnucash/gnome/dialog-imap-editor.c | 150 ++++++++++++++++++++-----------
libgnucash/engine/Account.cpp | 14 +++
libgnucash/engine/Account.h | 5 ++
libgnucash/engine/test/utest-Account.cpp | 25 ++++++
4 files changed, 144 insertions(+), 50 deletions(-)
More information about the gnucash-changes
mailing list