gnucash maint: Multiple changes pushed
John Ralls
jralls at code.gnucash.org
Thu Sep 16 12:47:23 EDT 2021
Updated via https://github.com/Gnucash/gnucash/commit/1170d7b0 (commit)
via https://github.com/Gnucash/gnucash/commit/34bd7b49 (commit)
via https://github.com/Gnucash/gnucash/commit/248a8504 (commit)
from https://github.com/Gnucash/gnucash/commit/93289006 (commit)
commit 1170d7b0d4630df569bb28727f7fa0aa99fa09f8
Merge: 93289006e 34bd7b49b
Author: John Ralls <jralls at ceridwen.us>
Date: Thu Sep 16 09:31:41 2021 -0700
Merge Jean Laroche's '105334_ofx_multiple_accounts' into maint.
diff --cc gnucash/import-export/ofx/gnc-ofx-import.c
index 2c98665e6,f1116c914..f4433b266
--- a/gnucash/import-export/ofx/gnc-ofx-import.c
+++ b/gnucash/import-export/ofx/gnc-ofx-import.c
@@@ -899,8 -903,8 +903,9 @@@ int ofx_proc_transaction_cb(struct OfxT
/* Send transaction to importer GUI. */
if (xaccTransCountSplits(transaction) > 0)
{
-- DEBUG("%d splits sent to the importer gui", xaccTransCountSplits(transaction));
- gnc_gen_trans_list_add_trans (info->gnc_ofx_importer_gui, transaction);
- info->trans_list = g_list_prepend(info->trans_list,transaction);
++ DEBUG("%d splits sent to the importer gui",
++ xaccTransCountSplits(transaction));
++ info->trans_list = g_list_prepend (info->trans_list, transaction);
}
else
{
@@@ -1098,14 -1102,32 +1103,36 @@@ gnc_ofx_process_next_file (GtkDialog *d
}
}
+ static void
+ gnc_ofx_on_match_click (GtkDialog *dialog, gint response_id, gpointer user_data)
+ {
+ // Record the response of the user. If cancel we won't go to the next file, etc.
- ofx_info* info = (ofx_info*) user_data;
++ ofx_info* info = (ofx_info*)user_data;
+ info->response = response_id;
+ }
- // This callback is called when the user is done matching transactions.
static void
- gnc_ofx_match_done (GtkDialog *dialog, gint response_id, gpointer user_data)
+ gnc_ofx_match_done (GtkDialog *dialog, gpointer user_data)
{
ofx_info* info = (ofx_info*) user_data;
-
- // The the user did not click OK, don't process the rest of the transaction, don't go to the next of xfile.
+
- if (response_id == GTK_RESPONSE_OK && info->run_reconcile && info->statement)
++ /* The the user did not click OK, don't process the rest of the
++ * transaction, don't go to the next of xfile.
++ */
+ if (info->response != GTK_RESPONSE_OK) return;
-
- if (info->trans_list && g_list_length (info->trans_list))
++
++ if (info->trans_list)
+ {
- // Re-run the match dialog if there are transactions remaining in our list (happens if several accounts
- // exist in the same ofx).
++ /* Re-run the match dialog if there are transactions
++ * remaining in our list (happens if several accounts exist
++ * in the same ofx).
++ */
+ info->gnc_ofx_importer_gui = gnc_gen_trans_list_new (GTK_WIDGET (info->parent), NULL, FALSE, 42, FALSE);
+ runMatcher (info, NULL, true);
+ return;
+ }
-
++
+ if (info->run_reconcile && info->statement)
{
// Open a reconcile window.
Account* account = gnc_import_select_account (gnc_gen_trans_list_widget(info->gnc_ofx_importer_gui),
@@@ -1142,6 -1159,70 +1164,71 @@@ reconcile_when_close_toggled_cb (GtkTog
info->run_reconcile = gtk_toggle_button_get_active (togglebutton);
}
+ static void
+ runMatcher(ofx_info* info, char * selected_filename, gboolean go_to_next_file)
+ {
+ GtkWindow *parent = info->parent;
- GList* trans_list;
+ GList* trans_list_remain = NULL;
+ Account* first_account = NULL;
-
- // If we have multiple accounts in the ofx file, we need to process transactions one account at a time,
- // in case there are transfers between accounts.
- trans_list = info->trans_list;
++
++ /* If we have multiple accounts in the ofx file, we need to
++ * process transactions one account at a time, in case there are
++ * transfers between accounts.
++ */
+ info->num_trans_processed = 0;
- for(;trans_list;trans_list=trans_list->next)
++ for(GList* node = info->trans_list; node; node=node->next)
+ {
- Transaction* trans = trans_list->data;
++ Transaction* trans = node->data;
+ Split* split = xaccTransGetSplit (trans, 0);
+ if (first_account == NULL) first_account = xaccSplitGetAccount (split);
+ if (xaccSplitGetAccount (split) == first_account)
+ {
- gnc_gen_trans_list_add_trans (info->gnc_ofx_importer_gui, trans_list->data);
++ gnc_gen_trans_list_add_trans (info->gnc_ofx_importer_gui, trans);
+ info->num_trans_processed ++;
+ }
- else trans_list_remain = g_list_prepend (trans_list_remain, trans_list->data);
++ else trans_list_remain = g_list_prepend (trans_list_remain, trans);
+ }
+ g_list_free (info->trans_list);
- info->trans_list = trans_list_remain;
-
++ info->trans_list = g_list_reverse (trans_list_remain);
++ g_list_free (trans_list_remain);
++
+ // See whether the view has anything in it and warn the user if not.
+ if (gnc_gen_trans_list_empty (info->gnc_ofx_importer_gui))
+ {
+ gnc_gen_trans_list_delete (info->gnc_ofx_importer_gui);
+ if (info->num_trans_processed)
+ {
+ gchar* acct_name = gnc_get_account_name_for_register (first_account);
+ gnc_info_dialog (parent, _("OFX file '%s', imported transactions for account '%s'\n%d transactions processed, no transactions to match"),
+ selected_filename, acct_name, info->num_trans_processed);
+ g_free (acct_name);
+ gnc_ofx_match_done (NULL,info);
+ return;
+ }
+ }
+ else
+ {
+ /* Show the match dialog and connect to the "destroy" signal so we can trigger a reconcile when
+ the user clicks OK when done matching transactions if required. Connecting to response isn't enough
+ because only when the matcher is destroyed do imported transactions get recorded */
+ g_signal_connect (G_OBJECT (gnc_gen_trans_list_widget (info->gnc_ofx_importer_gui)), "destroy",
+ G_CALLBACK (gnc_ofx_match_done), info);
+
+ // Connect to response so we know if the user pressed "cancel".
+ g_signal_connect (G_OBJECT (gnc_gen_trans_list_widget (info->gnc_ofx_importer_gui)), "response",
+ G_CALLBACK (gnc_ofx_on_match_click), info);
+
+ gnc_gen_trans_list_show_all (info->gnc_ofx_importer_gui);
+
+ // Show or hide the check box for reconciling after match, depending on whether a statement was received.
+ gnc_gen_trans_list_show_reconcile_after_close_button (info->gnc_ofx_importer_gui, info->statement != NULL, info->run_reconcile);
+
+ // Finally connect to the reconcile after match check box so we can be notified if the user wants/does not want to reconcile.
+ g_signal_connect (G_OBJECT (gnc_gen_trans_list_get_reconcile_after_close_button (info->gnc_ofx_importer_gui)), "toggled",
+ G_CALLBACK (reconcile_when_close_toggled_cb), info);
+ }
+ }
+
// Aux function to process the OFX file in info->file_list
static void
gnc_file_ofx_import_process_file (ofx_info* info)
commit 34bd7b49b2747c02310443f723b140a4e619c553
Author: jean <27791933+jeanlaroche at users.noreply.github.com>
Date: Thu Sep 9 21:38:47 2021 -0700
Restore previous behavior when the user cancels
diff --git a/gnucash/import-export/ofx/gnc-ofx-import.c b/gnucash/import-export/ofx/gnc-ofx-import.c
index d03c543d5..f1116c914 100644
--- a/gnucash/import-export/ofx/gnc-ofx-import.c
+++ b/gnucash/import-export/ofx/gnc-ofx-import.c
@@ -76,7 +76,8 @@ typedef struct _ofx_info
struct OfxStatementData* statement; // Statement, if any
gboolean run_reconcile; // If TRUE the reconcile window is opened after matching.
GSList* file_list; // List of OFX files to import
- GList* trans_list;
+ GList* trans_list; // We store the processed ofx transactions here
+ gint response; // Response sent by the match gui
} ofx_info ;
static void runMatcher(ofx_info* info, char * selected_filename, gboolean go_to_next_file);
@@ -1101,11 +1102,22 @@ gnc_ofx_process_next_file (GtkDialog *dialog, gpointer user_data)
}
}
+static void
+gnc_ofx_on_match_click (GtkDialog *dialog, gint response_id, gpointer user_data)
+{
+ // Record the response of the user. If cancel we won't go to the next file, etc.
+ ofx_info* info = (ofx_info*) user_data;
+ info->response = response_id;
+}
+
static void
gnc_ofx_match_done (GtkDialog *dialog, gpointer user_data)
{
ofx_info* info = (ofx_info*) user_data;
+ // The the user did not click OK, don't process the rest of the transaction, don't go to the next of xfile.
+ if (info->response != GTK_RESPONSE_OK) return;
+
if (info->trans_list && g_list_length (info->trans_list))
{
// Re-run the match dialog if there are transactions remaining in our list (happens if several accounts
@@ -1191,10 +1203,15 @@ runMatcher(ofx_info* info, char * selected_filename, gboolean go_to_next_file)
else
{
/* Show the match dialog and connect to the "destroy" signal so we can trigger a reconcile when
- the user clicks OK when done matching transactions if required. */
+ the user clicks OK when done matching transactions if required. Connecting to response isn't enough
+ because only when the matcher is destroyed do imported transactions get recorded */
g_signal_connect (G_OBJECT (gnc_gen_trans_list_widget (info->gnc_ofx_importer_gui)), "destroy",
G_CALLBACK (gnc_ofx_match_done), info);
+ // Connect to response so we know if the user pressed "cancel".
+ g_signal_connect (G_OBJECT (gnc_gen_trans_list_widget (info->gnc_ofx_importer_gui)), "response",
+ G_CALLBACK (gnc_ofx_on_match_click), info);
+
gnc_gen_trans_list_show_all (info->gnc_ofx_importer_gui);
// Show or hide the check box for reconciling after match, depending on whether a statement was received.
@@ -1311,6 +1328,7 @@ void gnc_file_ofx_import (GtkWindow *parent)
info->run_reconcile = FALSE;
info->file_list = selected_filenames;
info->trans_list = NULL;
+ info->response = 0;
// Call the aux import function.
gnc_file_ofx_import_process_file (info);
}
commit 248a8504b7b110a8b6a0795d2bad03872d814386
Author: jean <27791933+jeanlaroche at users.noreply.github.com>
Date: Thu Sep 9 10:52:19 2021 -0700
Add code to handle ofx files that include transfers between accounts
diff --git a/gnucash/import-export/ofx/gnc-ofx-import.c b/gnucash/import-export/ofx/gnc-ofx-import.c
index 2c98665e6..d03c543d5 100644
--- a/gnucash/import-export/ofx/gnc-ofx-import.c
+++ b/gnucash/import-export/ofx/gnc-ofx-import.c
@@ -76,8 +76,11 @@ typedef struct _ofx_info
struct OfxStatementData* statement; // Statement, if any
gboolean run_reconcile; // If TRUE the reconcile window is opened after matching.
GSList* file_list; // List of OFX files to import
+ GList* trans_list;
} ofx_info ;
+static void runMatcher(ofx_info* info, char * selected_filename, gboolean go_to_next_file);
+
/*
int ofx_proc_status_cb(struct OfxStatusData data)
{
@@ -900,7 +903,7 @@ int ofx_proc_transaction_cb(struct OfxTransactionData data, void *user_data)
if (xaccTransCountSplits(transaction) > 0)
{
DEBUG("%d splits sent to the importer gui", xaccTransCountSplits(transaction));
- gnc_gen_trans_list_add_trans (info->gnc_ofx_importer_gui, transaction);
+ info->trans_list = g_list_prepend(info->trans_list,transaction);
}
else
{
@@ -1088,7 +1091,7 @@ gnc_ofx_process_next_file (GtkDialog *dialog, gpointer user_data)
info->statement = NULL;
// Done with the previous OFX file, process the next one if any.
- info->file_list = g_slist_delete_link(info->file_list, info->file_list);
+ info->file_list = g_slist_delete_link (info->file_list, info->file_list);
if (info->file_list)
gnc_file_ofx_import_process_file (info);
else
@@ -1098,14 +1101,21 @@ gnc_ofx_process_next_file (GtkDialog *dialog, gpointer user_data)
}
}
-
-// This callback is called when the user is done matching transactions.
static void
-gnc_ofx_match_done (GtkDialog *dialog, gint response_id, gpointer user_data)
+gnc_ofx_match_done (GtkDialog *dialog, gpointer user_data)
{
ofx_info* info = (ofx_info*) user_data;
-
- if (response_id == GTK_RESPONSE_OK && info->run_reconcile && info->statement)
+
+ if (info->trans_list && g_list_length (info->trans_list))
+ {
+ // Re-run the match dialog if there are transactions remaining in our list (happens if several accounts
+ // exist in the same ofx).
+ info->gnc_ofx_importer_gui = gnc_gen_trans_list_new (GTK_WIDGET (info->parent), NULL, FALSE, 42, FALSE);
+ runMatcher (info, NULL, true);
+ return;
+ }
+
+ if (info->run_reconcile && info->statement)
{
// Open a reconcile window.
Account* account = gnc_import_select_account (gnc_gen_trans_list_widget(info->gnc_ofx_importer_gui),
@@ -1121,17 +1131,12 @@ gnc_ofx_match_done (GtkDialog *dialog, gint response_id, gpointer user_data)
info->statement->ledger_balance_date);
// Connect to destroy, at which point we'll process the next OFX file..
- g_signal_connect (G_OBJECT(gnc_ui_reconcile_window_get_window (rec_window)), "destroy",
- G_CALLBACK(gnc_ofx_process_next_file), info);
+ g_signal_connect (G_OBJECT (gnc_ui_reconcile_window_get_window (rec_window)), "destroy",
+ G_CALLBACK (gnc_ofx_process_next_file), info);
+ return;
}
}
- else if (response_id == GTK_RESPONSE_HELP)
- return;
- else
- {
- gtk_widget_hide (GTK_WIDGET(dialog));
- gnc_ofx_process_next_file (dialog, info);
- }
+ gnc_ofx_process_next_file (NULL, info);
}
// This callback is triggered when the user checks or unchecks the reconcile after match
@@ -1142,6 +1147,65 @@ reconcile_when_close_toggled_cb (GtkToggleButton *togglebutton, ofx_info* info)
info->run_reconcile = gtk_toggle_button_get_active (togglebutton);
}
+static void
+runMatcher(ofx_info* info, char * selected_filename, gboolean go_to_next_file)
+{
+ GtkWindow *parent = info->parent;
+ GList* trans_list;
+ GList* trans_list_remain = NULL;
+ Account* first_account = NULL;
+
+ // If we have multiple accounts in the ofx file, we need to process transactions one account at a time,
+ // in case there are transfers between accounts.
+ trans_list = info->trans_list;
+ info->num_trans_processed = 0;
+ for(;trans_list;trans_list=trans_list->next)
+ {
+ Transaction* trans = trans_list->data;
+ Split* split = xaccTransGetSplit (trans, 0);
+ if (first_account == NULL) first_account = xaccSplitGetAccount (split);
+ if (xaccSplitGetAccount (split) == first_account)
+ {
+ gnc_gen_trans_list_add_trans (info->gnc_ofx_importer_gui, trans_list->data);
+ info->num_trans_processed ++;
+ }
+ else trans_list_remain = g_list_prepend (trans_list_remain, trans_list->data);
+ }
+ g_list_free (info->trans_list);
+ info->trans_list = trans_list_remain;
+
+ // See whether the view has anything in it and warn the user if not.
+ if (gnc_gen_trans_list_empty (info->gnc_ofx_importer_gui))
+ {
+ gnc_gen_trans_list_delete (info->gnc_ofx_importer_gui);
+ if (info->num_trans_processed)
+ {
+ gchar* acct_name = gnc_get_account_name_for_register (first_account);
+ gnc_info_dialog (parent, _("OFX file '%s', imported transactions for account '%s'\n%d transactions processed, no transactions to match"),
+ selected_filename, acct_name, info->num_trans_processed);
+ g_free (acct_name);
+ gnc_ofx_match_done (NULL,info);
+ return;
+ }
+ }
+ else
+ {
+ /* Show the match dialog and connect to the "destroy" signal so we can trigger a reconcile when
+ the user clicks OK when done matching transactions if required. */
+ g_signal_connect (G_OBJECT (gnc_gen_trans_list_widget (info->gnc_ofx_importer_gui)), "destroy",
+ G_CALLBACK (gnc_ofx_match_done), info);
+
+ gnc_gen_trans_list_show_all (info->gnc_ofx_importer_gui);
+
+ // Show or hide the check box for reconciling after match, depending on whether a statement was received.
+ gnc_gen_trans_list_show_reconcile_after_close_button (info->gnc_ofx_importer_gui, info->statement != NULL, info->run_reconcile);
+
+ // Finally connect to the reconcile after match check box so we can be notified if the user wants/does not want to reconcile.
+ g_signal_connect (G_OBJECT (gnc_gen_trans_list_get_reconcile_after_close_button (info->gnc_ofx_importer_gui)), "toggled",
+ G_CALLBACK (reconcile_when_close_toggled_cb), info);
+ }
+}
+
// Aux function to process the OFX file in info->file_list
static void
gnc_file_ofx_import_process_file (ofx_info* info)
@@ -1182,33 +1246,7 @@ gnc_file_ofx_import_process_file (ofx_info* info)
// Free the libofx context before recursing to process the next file
libofx_free_context(libofx_context);
-
- // See whether the view has anything in it and warn the user if not.
- if(gnc_gen_trans_list_empty (info->gnc_ofx_importer_gui))
- {
- gnc_gen_trans_list_delete (info->gnc_ofx_importer_gui);
- if(info->num_trans_processed)
- gnc_info_dialog (parent, _("OFX file '%s' imported, %d transactions processed, no transactions to match"),
- selected_filename, info->num_trans_processed);
- // Process the next OFX file if any.
- gnc_ofx_process_next_file (NULL, info);
- }
- else
- {
- /* Show the match dialog and connect to the "response" signal so we can trigger a reconcile when
- the user clicks OK when done matching transactions if required. */
- g_signal_connect (G_OBJECT(gnc_gen_trans_list_widget (info->gnc_ofx_importer_gui)), "response",
- G_CALLBACK (gnc_ofx_match_done), info);
-
- gnc_gen_trans_list_show_all (info->gnc_ofx_importer_gui);
-
- // Show or hide the check box for reconciling after match, depending on whether a statement was received.
- gnc_gen_trans_list_show_reconcile_after_close_button (info->gnc_ofx_importer_gui, info->statement != NULL, info->run_reconcile);
-
- // Finally connect to the reconcile after match check box so we can be notified if the user wants/does not want to reconcile.
- g_signal_connect (G_OBJECT(gnc_gen_trans_list_get_reconcile_after_close_button (info->gnc_ofx_importer_gui)), "toggled",
- G_CALLBACK(reconcile_when_close_toggled_cb), info);
- }
+ runMatcher(info, selected_filename,true);
g_free(selected_filename);
}
@@ -1272,6 +1310,7 @@ void gnc_file_ofx_import (GtkWindow *parent)
info->parent = parent;
info->run_reconcile = FALSE;
info->file_list = selected_filenames;
+ info->trans_list = NULL;
// Call the aux import function.
gnc_file_ofx_import_process_file (info);
}
Summary of changes:
gnucash/import-export/ofx/gnc-ofx-import.c | 147 ++++++++++++++++++++---------
1 file changed, 105 insertions(+), 42 deletions(-)
More information about the gnucash-changes
mailing list