Refactor gnc_file_aqbanking_import.

Cleaning out cruft and extracting functions to improve readability.
This commit is contained in:
John Ralls 2022-10-22 10:30:25 -07:00
parent 283490965c
commit 909d857c76

View File

@ -61,42 +61,22 @@ typedef GWEN_SYNCIO GWEN_IO_LAYER;
/* This static indicates the debugging module that this .o belongs to. */
static QofLogModule log_module = GNC_MOD_IMPORT;
void
gnc_file_aqbanking_import(GtkWindow *parent,
static AB_IMEXPORTER_CONTEXT*
named_import_get_context (GtkWindow *parent, AB_BANKING *api,
const gchar *aqbanking_importername,
const gchar *aqbanking_profilename,
gboolean execute_transactions)
const gchar *aqbanking_profilename)
{
gchar *default_dir;
gchar *selected_filename = NULL;
gint dtaus_fd = -1;
AB_BANKING *api = NULL;
gboolean online = FALSE;
GncGWENGui *gui = NULL;
GWEN_DB_NODE *db_profiles = NULL;
GWEN_DB_NODE *db_profile;
AB_IMEXPORTER_CONTEXT *context = NULL;
GWEN_IO_LAYER *io = NULL;
GncABImExContextImport *ieci = NULL;
GNC_AB_JOB_LIST2 *job_list = NULL;
GNC_AB_JOB_LIST2_ITERATOR *jit;
GNC_AB_JOB *job;
GNC_AB_JOB_STATUS job_status;
gboolean successful = TRUE;
int num_jobs = 0;
int num_jobs_failed = 0;
int max_failures = 5;
GString *errstr = NULL;
AB_IMEXPORTER_CONTEXT *context;
int success;
/* Select a file */
default_dir = gnc_get_default_directory(GNC_PREFS_GROUP_AQBANKING);
selected_filename = gnc_file_dialog(parent, _("Select a file to import"),
NULL, default_dir,
GNC_FILE_DIALOG_IMPORT);
char *default_dir = gnc_get_default_directory(GNC_PREFS_GROUP_AQBANKING);
char *selected_filename =
gnc_file_dialog(parent, _("Select a file to import"),
NULL, default_dir, GNC_FILE_DIALOG_IMPORT);
g_free(default_dir);
if (!selected_filename)
goto cleanup;
return NULL;
DEBUG("filename: %s", selected_filename);
/* Remember the directory as the default */
@ -104,23 +84,178 @@ gnc_file_aqbanking_import(GtkWindow *parent,
gnc_set_default_directory(GNC_PREFS_GROUP_AQBANKING, default_dir);
g_free(default_dir);
/* Create a context to store the results */
context = AB_ImExporterContext_new();
success =
AB_Banking_ImportFromFileLoadProfile(api, aqbanking_importername,
context, aqbanking_profilename,
NULL, selected_filename);
g_free (selected_filename);
if (success < 0)
{
AB_ImExporterContext_free(context);
g_warning("gnc_file_aqbanking_import: Error on import");
return NULL;
}
return context;
}
static void
report_failure (GtkWindow* parent, int num_jobs,
int num_jobs_failed, GString* errstr)
{
g_warning("%s", errstr->str);
gnc_error_dialog(parent,
_("An error occurred while executing jobs: %d of %d failed. "
"Please check the log window or gnucash.trace for the exact "
"error message.\n\n%s")
, num_jobs_failed, num_jobs, errstr->str);
}
static void
report_no_jobs (GtkWindow *parent)
{
gnc_info_dialog(parent,
_("No jobs to be sent.")
);
}
static void
report_success (GtkWindow *parent, int num_jobs)
{
gnc_info_dialog(parent, ngettext
("The job was executed successfully, but as a precaution "
"please check the log window for potential errors.",
"All %d jobs were executed successfully, but as a precaution "
"please check the log window for potential errors.",
num_jobs), num_jobs);
}
static gboolean
check_job_status (GNC_AB_JOB_LIST2 *job_list, AB_BANKING *api, int *num_jobs,
int *num_jobs_failed, GString **errstr)
{
static const int max_failures = 5;
gboolean successful = TRUE;
GNC_AB_JOB_LIST2_ITERATOR *jit;
jit = AB_Transaction_List2_First(job_list);
AB_Transaction_List2_freeAll(job_list);
if (jit)
{
for (GNC_AB_JOB *job = AB_Transaction_List2Iterator_Data(jit);
job != NULL;
job = AB_Transaction_List2Iterator_Next(jit))
{
GNC_AB_JOB_STATUS job_status;
*num_jobs += 1;
job_status = AB_Transaction_GetStatus(job);
if (job_status != AB_Transaction_StatusAccepted &&
job_status != AB_Transaction_StatusPending)
{
successful = FALSE;
*num_jobs_failed += 1;
if (*num_jobs_failed <= max_failures)
{
gchar *fmt_str =_("Job %d status %d - %s\n");
if (*num_jobs_failed == 1)
{
*errstr = g_string_new("Failed jobs:\n");
}
g_string_append_printf(*errstr, fmt_str, *num_jobs,
job_status,
AB_Transaction_Status_toString(job_status));
}
else
{
if (*num_jobs_failed == (max_failures + 1) )
{
/* indicate that additional failures exist */
g_string_append(*errstr, _("...\n"));
}
}
}
} /* while */
AB_Transaction_List2Iterator_free(jit);
}
return successful;
}
static void
do_execute_transactions (GtkWindow *parent, AB_BANKING *api,
GncABImExContextImport *ieci)
{
GString *errstr = NULL;
if (!gnc_ab_ieci_run_matcher(ieci))
{
return;
}
else
{
int num_jobs = 0;
int num_jobs_failed = 0;
/* Extract the list of jobs */
GNC_AB_JOB_LIST2 *job_list = gnc_ab_ieci_get_job_list(ieci);
/* Create a context to store possible results */
AB_IMEXPORTER_CONTEXT *execution_context =
AB_ImExporterContext_new();
/* Execute the jobs */
AB_Banking_SendCommands(api, job_list, execution_context);
AB_ImExporterContext_free(execution_context);
/* Ignore the return value of AB_Banking_ExecuteJobs(), as the job's
* status always describes better whether the job was actually
* transferred to and accepted by the bank. See also
* https://lists.gnucash.org/pipermail/gnucash-de/2008-September/006389.html
* So we must go through all jobs and check AB_Job_GetStatus(job)
* to give the appropriate feedback if any of the jobs didn't
* work.
*/
if (check_job_status (job_list, api, &num_jobs,
&num_jobs_failed, &errstr))
{
if (num_jobs == 0)
report_no_jobs (parent);
else
report_success (parent, num_jobs);
}
else
{
report_failure (parent, num_jobs, num_jobs_failed, errstr);
}
if (errstr)
g_string_free(errstr, TRUE);
}
}
void
gnc_file_aqbanking_import(GtkWindow *parent,
const gchar *aqbanking_importername,
const gchar *aqbanking_profilename,
gboolean execute_transactions)
{
gint dtaus_fd = -1;
AB_BANKING *api = NULL;
AB_IMEXPORTER_CONTEXT *context = NULL;
GncABImExContextImport *ieci = NULL;
/* Get the API */
api = gnc_AB_BANKING_new();
if (!api)
{
g_warning("gnc_file_aqbanking_import: Couldn't get AqBanking API");
goto cleanup;
return;
}
/* Create a context to store the results */
context = AB_ImExporterContext_new();
if (AB_Banking_ImportFromFileLoadProfile(api, aqbanking_importername,
context, aqbanking_profilename,
NULL, selected_filename) < 0)
context = named_import_get_context (parent, api, aqbanking_importername,
aqbanking_profilename);
if (!context)
{
g_warning("gnc_file_aqbanking_import: Error on import");
goto cleanup;
gnc_AB_BANKING_fini(api);
return;
}
/* Before importing the results, if this is a new book, let user specify
@ -135,122 +270,9 @@ gnc_file_aqbanking_import(GtkWindow *parent,
GTK_WIDGET(parent));
if (execute_transactions)
{
if (gnc_ab_ieci_run_matcher(ieci))
{
AB_IMEXPORTER_CONTEXT *execution_context;
do_execute_transactions (parent, api, ieci);
/* Extract the list of jobs */
job_list = gnc_ab_ieci_get_job_list(ieci);
/* Create a context to store possible results */
execution_context = AB_ImExporterContext_new();
/* Get a GUI object */
gui = gnc_GWEN_Gui_get(NULL);
if (!gui)
{
g_warning("gnc_file_aqbanking_import: Couldn't initialize Gwenhywfar GUI");
goto cleanup;
}
/* And execute the jobs */
AB_Banking_SendCommands(api, job_list, execution_context);
/* Ignore the return value of AB_Banking_ExecuteJobs(), as the job's
* status always describes better whether the job was actually
* transferred to and accepted by the bank. See also
* https://lists.gnucash.org/pipermail/gnucash-de/2008-September/006389.html
*/
/* So we must go through all jobs and check AB_Job_GetStatus(job)
* to give the appropriate feedback if any of the jobs didn't
* work. */
jit = AB_Transaction_List2_First(job_list);
if (jit)
{
job = AB_Transaction_List2Iterator_Data(jit);
while (job)
{
num_jobs += 1;
job_status = AB_Transaction_GetStatus(job);
if (job_status != AB_Transaction_StatusAccepted &&
job_status != AB_Transaction_StatusPending)
{
successful = FALSE;
num_jobs_failed += 1;
if (num_jobs_failed <= max_failures)
{
gchar *fmt_str =_("Job %d status %d - %s\n");
if (num_jobs_failed == 1)
{
errstr = g_string_new("Failed jobs:\n");
}
g_string_append_printf(errstr, fmt_str, num_jobs,
job_status,
AB_Transaction_Status_toString(job_status));
}
else
{
if (num_jobs_failed == (max_failures + 1) )
{
/* indicate that additional failures exist */
g_string_append(errstr, _("...\n"));
}
}
}
job = AB_Transaction_List2Iterator_Next(jit);
} /* while */
AB_Transaction_List2Iterator_free(jit);
}
if (!successful)
{
g_warning("%s", errstr->str);
gnc_error_dialog(parent,
_("An error occurred while executing jobs: %d of %d failed. "
"Please check the log window or gnucash.trace for the exact "
"error message.\n\n%s")
, num_jobs_failed, num_jobs, errstr->str);
}
else
{
if (num_jobs == 0)
{
gnc_info_dialog(parent,
_("No jobs to be sent.")
);
}
else
{
gnc_info_dialog(parent, ngettext
("The job was executed successfully, but as a precaution "
"please check the log window for potential errors.",
"All %d jobs were executed successfully, but as a precaution "
"please check the log window for potential errors.",
num_jobs), num_jobs);
}
}
AB_ImExporterContext_free(execution_context);
}
}
cleanup:
if (job_list)
AB_Transaction_List2_freeAll(job_list);
if (ieci)
g_free(ieci);
if (context)
AB_ImExporterContext_free(context);
if (gui)
gnc_GWEN_Gui_release(gui);
if (api)
gnc_AB_BANKING_fini(api);
if (selected_filename)
g_free(selected_filename);
if (errstr)
g_string_free(errstr, TRUE);
g_free(ieci);
AB_ImExporterContext_free(context);
gnc_AB_BANKING_fini(api);
}