Code refactoring for further aqbanking features.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@15465 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Christian Stimming 2007-01-29 20:58:46 +00:00
parent a34f91e975
commit cb02cab345
4 changed files with 364 additions and 280 deletions

View File

@ -25,7 +25,8 @@
*/ */
#include "config.h" #include "config.h"
#include <glib.h> #include "gnc-file-aqb-import.h"
#include <glib/gi18n.h> #include <glib/gi18n.h>
#include <glib/gstdio.h> #include <glib/gstdio.h>
#include <string.h> #include <string.h>
@ -35,7 +36,6 @@
#include <aqbanking/version.h> #include <aqbanking/version.h>
#include <aqbanking/banking.h> #include <aqbanking/banking.h>
#include <aqbanking/imexporter.h> #include <aqbanking/imexporter.h>
#include <aqbanking/jobsingledebitnote.h>
#include "gnc-ui.h" #include "gnc-ui.h"
#include "qof.h" #include "qof.h"
@ -49,89 +49,10 @@
#include "gnc-hbci-utils.h" #include "gnc-hbci-utils.h"
#include "gnc-hbci-gettrans.h" #include "gnc-hbci-gettrans.h"
#include "hbci-interaction.h" #include "hbci-interaction.h"
#include "dialog-hbcitrans.h"
#include "import-main-matcher.h"
#include "import-account-matcher.h"
#include "gnc-hbci-gettrans.h"
#include "gnc-file-aqb-import.h"
static QofLogModule log_module = GNC_MOD_IMPORT; static QofLogModule log_module = GNC_MOD_IMPORT;
/* Callback declarations */
static const AB_TRANSACTION *
translist_cb (const AB_TRANSACTION *element, void *user_data);
static AB_IMEXPORTER_ACCOUNTINFO *
accountinfolist_cb(AB_IMEXPORTER_ACCOUNTINFO *element, void *user_data);
static gboolean
gnc_hbci_multijob_execute(GtkWidget *parent, AB_BANKING *api,
GList *job_list, GNCInteractor *interactor);
static void multijob_cb (gpointer element, gpointer user_data);
static void delpending_cb (gpointer element, gpointer user_data);
struct import_data
{
Account *gnc_acc;
GNCImportMainMatcher *importer_generic;
AB_BANKING *ab;
AB_ACCOUNT *hbci_account;
GList *job_list;
gboolean execute_transactions;
};
/* If aqbanking is older than 1.9.7, use our own copies of these
foreach functions */
#if ((AQBANKING_VERSION_MAJOR == 1) && \
((AQBANKING_VERSION_MINOR < 9) || \
((AQBANKING_VERSION_MINOR == 9) && \
((AQBANKING_VERSION_PATCHLEVEL < 7)))))
static AB_IMEXPORTER_ACCOUNTINFO *
AB_ImExporterContext_AccountInfoForEach(AB_IMEXPORTER_CONTEXT *iec,
AB_IMEXPORTER_ACCOUNTINFO *
(* func)(AB_IMEXPORTER_ACCOUNTINFO *element,
void *user_data),
void* user_data)
{
AB_IMEXPORTER_ACCOUNTINFO *it;
AB_IMEXPORTER_ACCOUNTINFO *retval;
g_assert(iec);
it = AB_ImExporterContext_GetFirstAccountInfo (iec);
while (it) {
retval = func(it, user_data);
if (retval) {
return retval;
}
it = AB_ImExporterContext_GetNextAccountInfo (iec);
}
return 0;
}
static const AB_TRANSACTION *
AB_ImExporterAccountInfo_TransactionsForEach(AB_IMEXPORTER_ACCOUNTINFO *iea,
const AB_TRANSACTION *
(* func)(const AB_TRANSACTION *element,
void *user_data),
void* user_data)
{
const AB_TRANSACTION *it;
const AB_TRANSACTION *retval;
g_assert(iea);
it = AB_ImExporterAccountInfo_GetFirstTransaction (iea);
while (it) {
retval = func(it, user_data);
if (retval) {
return retval;
}
it = AB_ImExporterAccountInfo_GetNextTransaction (iea);
}
return 0;
}
#endif /* aqbanking < 1.9.7 */
/* See aqbanking-1.6.0beta/src/tools/aqbanking-tool/import.c for hints /* See aqbanking-1.6.0beta/src/tools/aqbanking-tool/import.c for hints
on how to program aqbanking. */ on how to program aqbanking. */
@ -153,7 +74,7 @@ void gnc_file_aqbanking_import (const gchar *aqbanking_importername,
DEBUG("gnc_file_dtaus_import(): Begin...\n"); DEBUG("gnc_file_dtaus_import(): Begin...\n");
default_dir = gnc_get_default_directory(GCONF_SECTION); default_dir = gnc_get_default_directory(GCONF_SECTION);
selected_filename = gnc_file_dialog(_("Select an DTAUS file to process"), selected_filename = gnc_file_dialog(_("Select a file to import"),
NULL, NULL,
default_dir, default_dir,
GNC_FILE_DIALOG_IMPORT); GNC_FILE_DIALOG_IMPORT);
@ -174,6 +95,7 @@ void gnc_file_aqbanking_import (const gchar *aqbanking_importername,
DEBUG("Could not open file %s", selected_filename); DEBUG("Could not open file %s", selected_filename);
return; return;
} }
g_free(selected_filename);
{ {
int result; int result;
@ -258,45 +180,41 @@ void gnc_file_aqbanking_import (const gchar *aqbanking_importername,
{ {
/* Now get all accountinfos */ /* Now get all accountinfos */
struct import_data data;
GNCImportMainMatcher *importer_generic_gui; GNCImportMainMatcher *importer_generic_gui;
GtkWidget *parent = NULL; GtkWidget *parent = NULL;
gboolean successful = FALSE; gboolean successful = FALSE;
GList *ab_job_list;
/* Create importer GUI */ /* Create importer GUI */
importer_generic_gui = gnc_gen_trans_list_new(parent, NULL, TRUE, 14); importer_generic_gui = gnc_gen_trans_list_new(parent, NULL, TRUE, 14);
data.importer_generic = importer_generic_gui;
data.ab = ab;
data.job_list = NULL;
data.execute_transactions = execute_transactions;
/* Iterate through all accounts */ /* Import the transactions from the ctx into gnucash. */
AB_ImExporterContext_AccountInfoForEach(ctx, accountinfolist_cb, &data); ab_job_list = gnc_hbci_import_ctx(ab, ctx, importer_generic_gui,
/* all accounts finished. */ execute_transactions);
/* Finished importing. */
/* that's it */ /* We clean up here. */
g_free(selected_filename); AB_ImExporterContext_free(ctx);
if (execute_transactions) { if (execute_transactions) {
/* and run the gnucash importer. */ /* Wait for the gnucash importer to be finished (it is being
run anyway). */
result = gnc_gen_trans_list_run (importer_generic_gui); result = gnc_gen_trans_list_run (importer_generic_gui);
if (result) if (result)
/* Execute these jobs now. This function already delete()s the /* Execute these jobs now. This function already delete()s the
job. */ job. */
/* no parent so far; otherwise add this: GNCInteractor_reparent (interactor, parent); */ /* no parent so far; otherwise add this: GNCInteractor_reparent (interactor, parent); */
successful = gnc_hbci_multijob_execute (parent, ab, data.job_list, interactor); successful = gnc_hbci_multijob_execute (parent, ab, ab_job_list, interactor);
/* else */ /* else */
/* Delete all jobs from queue in any case. */ /* Delete all jobs from queue in any case. */
g_list_foreach (data.job_list, delpending_cb, ab); gnc_hbci_clearqueue (ab, ab_job_list);
} }
else { else {
successful = TRUE; successful = TRUE;
} }
/* We clean up here. */
AB_ImExporterContext_free(ctx);
if (successful) { if (successful) {
/* If execution was not successful, leave the log window /* If execution was not successful, leave the log window
still intact and open. */ still intact and open. */
@ -308,177 +226,5 @@ void gnc_file_aqbanking_import (const gchar *aqbanking_importername,
} }
} }
static AB_IMEXPORTER_ACCOUNTINFO *
accountinfolist_cb(AB_IMEXPORTER_ACCOUNTINFO *accinfo, void *user_data) {
Account *gnc_acc;
struct import_data *data = user_data;
const char *bank_code =
AB_ImExporterAccountInfo_GetBankCode(accinfo);
const char *account_number =
AB_ImExporterAccountInfo_GetAccountNumber(accinfo);
const char *account_name =
AB_ImExporterAccountInfo_GetAccountName(accinfo);
gchar *online_id = g_strconcat (bank_code, account_number, NULL);
gnc_acc = gnc_import_select_account(NULL,
online_id, 1, account_name, NULL,
ACCT_TYPE_NONE, NULL, NULL);
g_free(online_id);
if (gnc_acc) {
/* Store chosen gnucash account in callback data */
data->gnc_acc = gnc_acc;
if (data->execute_transactions) {
/* Retrieve the aqbanking account that belongs to this gnucash
account */
data->hbci_account = gnc_hbci_get_hbci_acc (data->ab, gnc_acc);
if (data->hbci_account == NULL) {
gnc_error_dialog (NULL, _("No Online Banking account found for this gnucash account. These transactions will not be executed by Online Banking."));
}
}
else {
data->hbci_account = NULL;
}
/* Iterate through all transactions. */
AB_ImExporterAccountInfo_TransactionsForEach (accinfo, translist_cb, data);
/* all transactions finished. */
}
return NULL;
}
static const AB_TRANSACTION *
translist_cb (const AB_TRANSACTION *element, void *user_data) {
AB_JOB *job;
AB_TRANSACTION *trans = (AB_TRANSACTION*)element;
GtkWidget *parent = NULL;
struct import_data *data = user_data;
struct trans_list_data hbci_userdata;
/* This callback in the hbci module will add the imported
transaction to gnucash's importer. */
hbci_userdata.gnc_acc = data->gnc_acc;
hbci_userdata.importer_generic = data->importer_generic;
/* The call will use "trans" only as const* */
gnc_hbci_trans_list_cb((AB_TRANSACTION*) trans, &hbci_userdata);
if (data->hbci_account) {
/* NEW: The imported transaction has been imported into
gnucash. Now also add it as a job to aqbanking. */
AB_Transaction_SetLocalBankCode (trans,
AB_Account_GetBankCode (data->hbci_account));
AB_Transaction_SetLocalAccountNumber (trans, AB_Account_GetAccountNumber (data->hbci_account));
AB_Transaction_SetLocalCountry (trans, "DE");
job =
gnc_hbci_trans_dialog_enqueue(trans, data->ab,
data->hbci_account, SINGLE_DEBITNOTE);
/* Check whether we really got a job */
if (!job) {
/* Oops, no job, probably not supported by bank. */
if (gnc_verify_dialog
(parent,
FALSE,
"%s",
_("The backend found an error during the preparation "
"of the job. It is not possible to execute this job. \n"
"\n"
"Most probable the bank does not support your chosen "
"job or your Online Banking account does not have the permission "
"to execute this job. More error messages might be "
"visible on your console log.\n"
"\n"
"Do you want to enter the job again?"))) {
gnc_error_dialog (parent, "Sorry, not implemented yet.");
}
/* else
break; */
}
data->job_list = g_list_append(data->job_list, job);
}
return NULL;
}
gboolean
gnc_hbci_multijob_execute(GtkWidget *parent, AB_BANKING *api,
GList *job_list, GNCInteractor *interactor)
{
gboolean successful;
g_assert(api);
successful = gnc_AB_BANKING_execute (parent, api, NULL, interactor);
/*printf("dialog-hbcitrans: Ok, result of api_execute was %d.\n",
successful);*/
if (!successful) {
/* AB_BANKING_executeOutbox failed. */
gnc_error_dialog (GNCInteractor_dialog (interactor),
"%s",
_("Executing the Online Banking outbox failed. Please check the log window."));
GNCInteractor_show_nodelete(interactor);
g_list_foreach (job_list, multijob_cb, GNCInteractor_dialog (interactor));
}
/* Watch out! The job *has* to be removed from the queue
here because otherwise it might be executed again. */
/* AB_Banking_DequeueJob(api, job); is done in the calling function. */
return successful;
}
void multijob_cb (gpointer element, gpointer user_data)
{
AB_JOB *job = element;
GtkWidget *parent = user_data;
if ((AB_Job_GetStatus (job) == AB_Job_StatusPending) ||
(AB_Job_GetStatus (job) == AB_Job_StatusError)) {
/* There was some error in this job. */
if (AB_Job_GetType (job) == AB_Job_TypeDebitNote) {
const AB_TRANSACTION *h_trans =
AB_JobSingleDebitNote_GetTransaction (job);
gchar *descr_name = gnc_hbci_descr_tognc (h_trans);
gchar *value =
gnc_AB_VALUE_toReadableString (AB_Transaction_GetValue (h_trans));
gchar *errortext;
errortext =
g_strdup_printf(_("A debit note has been refused by the bank. The refused debit note has the following data:\n"
"Remote bank code: \"%s\"\n"
"Remote account number: \"%s\"\n"
"Description and remote name: \"%s\"\n"
"Value: \"%s\"\n"),
AB_Transaction_GetRemoteBankCode (h_trans),
AB_Transaction_GetRemoteAccountNumber (h_trans),
descr_name,
value);
printf ("%s", errortext);
gnc_error_dialog (parent, "%s", errortext);
g_free (errortext);
g_free (descr_name);
} else {
gnc_error_dialog
(parent, "%s",
_("One of the jobs was sent to the bank successfully, but the "
"bank is refusing to execute the job. Please check "
"the log window for the exact error message of the "
"bank. The line with the error message contains a "
"code number that is greater than 9000.\n"
"\n"
"The job has been removed from the queue."));
/* FIXME: Might make more useful user feedback here. */
}
}
}
void delpending_cb (gpointer element, gpointer user_data)
{
AB_JOB *job = element;
AB_BANKING *ab = user_data;
if (AB_Job_GetStatus (job) == AB_Job_StatusPending)
AB_Banking_DelPendingJob(ab, job);
}
/** @} */ /** @} */

View File

@ -25,17 +25,18 @@
#ifndef DTAUS_IMPORT_H #ifndef DTAUS_IMPORT_H
#define DTAUS_IMPORT_H #define DTAUS_IMPORT_H
/** The gnc_file_dtaus_import() routine will pop up a standard file #include <glib.h>
* selection dialogue asking the user to pick an DTAUS file. If one
* is selected then the DTAUS file is opened and read. Its contents /** This routine will pop up a standard file selection dialog asking
* are merged into the existing session (if any). The current * the user to pick a file to import. This file will be opened and
* session continues to remain open for editing. * read. Its contents will be imported into the current book, using
* the import matcher from import-main-matcher.h.
* *
* @param aqbanking_importername The aqbanking importer module that * @param aqbanking_importername The aqbanking importer module that
* should be used. Possible values: "dtaus", "csv", "swift". * should be used. Possible values: "dtaus", "csv", "swift", or more.
* *
* @param aqbanking_formatname In aqbanking, each importer has one or * @param aqbanking_formatname In aqbanking, each importer has one or
* more possible data formats available that define the actual data * more data formats available which define the actual data
* fields that should be used. In aqbanking, such a different format * fields that should be used. In aqbanking, such a different format
* is called a "profile". * is called a "profile".
* Possible values for swift: "swift-mt940" or "swift-mt942", * Possible values for swift: "swift-mt940" or "swift-mt942",
@ -43,11 +44,13 @@
* $datadir/aqbanking/imexporters and look into the "name" field of * $datadir/aqbanking/imexporters and look into the "name" field of
* the foo.conf files. * the foo.conf files.
* *
* @param execute_transactions If TRUE, import the transactions and * @param exec_as_aqbanking_jobs If TRUE, additionally queue the
* additionally send them as online jobs over aqbanking/HBCI. If * imported transactions as online jobs over aqbanking/HBCI. If FALSE,
* FALSE, simply import the transactions and that's it. * just import the transactions and that's it.
*/ */
void gnc_file_aqbanking_import (const gchar *aqbanking_importername, void gnc_file_aqbanking_import (const gchar *aqbanking_importername,
const gchar *aqbanking_formatname, const gchar *aqbanking_formatname,
gboolean execute_transactions); gboolean exec_as_aqbanking_jobs);
#endif #endif

View File

@ -36,11 +36,18 @@
#include "qof.h" #include "qof.h"
#include "gnc-glib-utils.h" #include "gnc-glib-utils.h"
#include "import-main-matcher.h"
#include "import-account-matcher.h"
#define AQBANKING_NOWARN_DEPRECATED #define AQBANKING_NOWARN_DEPRECATED
#include "gnc-hbci-utils.h" #include "gnc-hbci-utils.h"
#include "hbci-interaction.h" #include "hbci-interaction.h"
#include "gnc-hbci-gettrans.h"
#include "dialog-hbcitrans.h"
#include <aqbanking/version.h> #include <aqbanking/version.h>
#include <aqbanking/jobsingledebitnote.h>
/* static short module = MOD_IMPORT; */ /* static short module = MOD_IMPORT; */
@ -50,6 +57,59 @@ static int gnc_AB_BANKING_refcnt = 0;
static GNCInteractor *gnc_hbci_inter = NULL; static GNCInteractor *gnc_hbci_inter = NULL;
/* If aqbanking is older than 1.9.7, use our own copies of these
foreach functions */
#if ((AQBANKING_VERSION_MAJOR == 1) && \
((AQBANKING_VERSION_MINOR < 9) || \
((AQBANKING_VERSION_MINOR == 9) && \
((AQBANKING_VERSION_PATCHLEVEL < 7)))))
static AB_IMEXPORTER_ACCOUNTINFO *
AB_ImExporterContext_AccountInfoForEach(AB_IMEXPORTER_CONTEXT *iec,
AB_IMEXPORTER_ACCOUNTINFO *
(* func)(AB_IMEXPORTER_ACCOUNTINFO *element,
void *user_data),
void* user_data)
{
AB_IMEXPORTER_ACCOUNTINFO *it;
AB_IMEXPORTER_ACCOUNTINFO *retval;
g_assert(iec);
it = AB_ImExporterContext_GetFirstAccountInfo (iec);
while (it) {
retval = func(it, user_data);
if (retval) {
return retval;
}
it = AB_ImExporterContext_GetNextAccountInfo (iec);
}
return 0;
}
static const AB_TRANSACTION *
AB_ImExporterAccountInfo_TransactionsForEach(AB_IMEXPORTER_ACCOUNTINFO *iea,
const AB_TRANSACTION *
(* func)(const AB_TRANSACTION *element,
void *user_data),
void* user_data)
{
const AB_TRANSACTION *it;
const AB_TRANSACTION *retval;
g_assert(iea);
it = AB_ImExporterAccountInfo_GetFirstTransaction (iea);
while (it) {
retval = func(it, user_data);
if (retval) {
return retval;
}
it = AB_ImExporterAccountInfo_GetNextTransaction (iea);
}
return 0;
}
#endif /* aqbanking < 1.9.7 */
AB_BANKING * gnc_AB_BANKING_new_currentbook (GtkWidget *parent, AB_BANKING * gnc_AB_BANKING_new_currentbook (GtkWidget *parent,
GNCInteractor **inter) GNCInteractor **inter)
{ {
@ -388,6 +448,8 @@ static void gnc_hbci_printresult(HBCI_Outbox *outbox, GNCInteractor *inter)
} }
#endif #endif
/* ------------------------------------------------------- */
static gboolean hbci_Error_isOk(int err) { static gboolean hbci_Error_isOk(int err) {
switch (err) { switch (err) {
case 0: case 0:
@ -462,6 +524,233 @@ gnc_AB_BANKING_execute (GtkWidget *parent, AB_BANKING *api,
} }
} }
static void multijob_cb (gpointer element, gpointer user_data);
gboolean
gnc_hbci_multijob_execute(GtkWidget *parent, AB_BANKING *api,
GList *job_list, GNCInteractor *interactor)
{
gboolean successful;
g_assert(api);
successful = gnc_AB_BANKING_execute (parent, api, NULL, interactor);
/*printf("dialog-hbcitrans: Ok, result of api_execute was %d.\n",
successful);*/
if (!successful) {
/* AB_BANKING_executeOutbox failed. */
gnc_error_dialog (GNCInteractor_dialog (interactor),
"%s",
_("Executing the Online Banking outbox failed. Please check the log window."));
GNCInteractor_show_nodelete(interactor);
g_list_foreach (job_list, multijob_cb, GNCInteractor_dialog (interactor));
}
/* Watch out! The job *has* to be removed from the queue
here because otherwise it might be executed again. */
/* AB_Banking_DequeueJob(api, job); is done in the calling function. */
return successful;
}
void multijob_cb (gpointer element, gpointer user_data)
{
AB_JOB *job = element;
GtkWidget *parent = user_data;
if ((AB_Job_GetStatus (job) == AB_Job_StatusPending) ||
(AB_Job_GetStatus (job) == AB_Job_StatusError)) {
/* There was some error in this job. */
if (AB_Job_GetType (job) == AB_Job_TypeDebitNote) {
const AB_TRANSACTION *h_trans =
AB_JobSingleDebitNote_GetTransaction (job);
gchar *descr_name = gnc_hbci_descr_tognc (h_trans);
gchar *value =
gnc_AB_VALUE_toReadableString (AB_Transaction_GetValue (h_trans));
gchar *errortext;
errortext =
g_strdup_printf(_("A debit note has been refused by the bank. The refused debit note has the following data:\n"
"Remote bank code: \"%s\"\n"
"Remote account number: \"%s\"\n"
"Description and remote name: \"%s\"\n"
"Value: \"%s\"\n"),
AB_Transaction_GetRemoteBankCode (h_trans),
AB_Transaction_GetRemoteAccountNumber (h_trans),
descr_name,
value);
printf ("%s", errortext);
gnc_error_dialog (parent, "%s", errortext);
g_free (errortext);
g_free (descr_name);
} else {
gnc_error_dialog
(parent, "%s",
_("One of the jobs was sent to the bank successfully, but the "
"bank is refusing to execute the job. Please check "
"the log window for the exact error message of the "
"bank. The line with the error message contains a "
"code number that is greater than 9000.\n"
"\n"
"The job has been removed from the queue."));
/* FIXME: Might make more useful user feedback here. */
}
}
}
/* ------------------------------------------------------- */
/* Callback declarations */
static const AB_TRANSACTION *
translist_cb (const AB_TRANSACTION *element, void *user_data);
static AB_IMEXPORTER_ACCOUNTINFO *
accountinfolist_cb(AB_IMEXPORTER_ACCOUNTINFO *element, void *user_data);
struct import_data
{
Account *gnc_acc;
GNCImportMainMatcher *importer_generic;
AB_BANKING *ab;
AB_ACCOUNT *hbci_account;
GList *job_list;
gboolean execute_transactions;
};
GList *
gnc_hbci_import_ctx(AB_BANKING *ab, AB_IMEXPORTER_CONTEXT *ctx,
GNCImportMainMatcher *importer_generic_gui,
gboolean exec_as_aqbanking_jobs)
{
struct import_data data;
data.importer_generic = importer_generic_gui;
data.ab = ab;
data.job_list = NULL;
data.execute_transactions = exec_as_aqbanking_jobs;
/* Iterate through all accounts */
AB_ImExporterContext_AccountInfoForEach(ctx, accountinfolist_cb, &data);
/* All accounts finished. Finished importing. */
return data.job_list;
}
static AB_IMEXPORTER_ACCOUNTINFO *
accountinfolist_cb(AB_IMEXPORTER_ACCOUNTINFO *accinfo, void *user_data) {
Account *gnc_acc;
struct import_data *data = user_data;
const char *bank_code =
AB_ImExporterAccountInfo_GetBankCode(accinfo);
const char *account_number =
AB_ImExporterAccountInfo_GetAccountNumber(accinfo);
const char *account_name =
AB_ImExporterAccountInfo_GetAccountName(accinfo);
gchar *online_id = g_strconcat (bank_code, account_number, NULL);
gnc_acc = gnc_import_select_account(NULL,
online_id, 1, account_name, NULL,
ACCT_TYPE_NONE, NULL, NULL);
g_free(online_id);
if (gnc_acc) {
/* Store chosen gnucash account in callback data */
data->gnc_acc = gnc_acc;
if (data->execute_transactions) {
/* Retrieve the aqbanking account that belongs to this gnucash
account */
data->hbci_account = gnc_hbci_get_hbci_acc (data->ab, gnc_acc);
if (data->hbci_account == NULL) {
gnc_error_dialog (NULL, _("No Online Banking account found for this gnucash account. These transactions will not be executed by Online Banking."));
}
}
else {
data->hbci_account = NULL;
}
/* Iterate through all transactions. */
AB_ImExporterAccountInfo_TransactionsForEach (accinfo, translist_cb, data);
/* all transactions finished. */
}
return NULL;
}
static const AB_TRANSACTION *
translist_cb (const AB_TRANSACTION *element, void *user_data) {
AB_JOB *job;
AB_TRANSACTION *trans = (AB_TRANSACTION*)element;
GtkWidget *parent = NULL;
struct import_data *data = user_data;
struct trans_list_data hbci_userdata;
/* This callback in the hbci module will add the imported
transaction to gnucash's importer. */
hbci_userdata.gnc_acc = data->gnc_acc;
hbci_userdata.importer_generic = data->importer_generic;
/* The call will use "trans" only as const* */
gnc_hbci_trans_list_cb((AB_TRANSACTION*) trans, &hbci_userdata);
if (data->hbci_account) {
/* NEW: The imported transaction has been imported into
gnucash. Now also add it as a job to aqbanking. */
AB_Transaction_SetLocalBankCode (trans,
AB_Account_GetBankCode (data->hbci_account));
AB_Transaction_SetLocalAccountNumber (trans, AB_Account_GetAccountNumber (data->hbci_account));
AB_Transaction_SetLocalCountry (trans, "DE");
job =
gnc_hbci_trans_dialog_enqueue(trans, data->ab,
data->hbci_account, SINGLE_DEBITNOTE);
/* Check whether we really got a job */
if (!job) {
/* Oops, no job, probably not supported by bank. */
if (gnc_verify_dialog
(parent,
FALSE,
"%s",
_("The backend found an error during the preparation "
"of the job. It is not possible to execute this job. \n"
"\n"
"Most probable the bank does not support your chosen "
"job or your Online Banking account does not have the permission "
"to execute this job. More error messages might be "
"visible on your console log.\n"
"\n"
"Do you want to enter the job again?"))) {
gnc_error_dialog (parent, "Sorry, not implemented yet.");
}
/* else
break; */
}
data->job_list = g_list_append(data->job_list, job);
}
return NULL;
}
/* ------------------------------------------------------- */
static void delpending_cb (gpointer element, gpointer user_data);
void
gnc_hbci_clearqueue(AB_BANKING *ab, GList *ab_job_list)
{
g_list_foreach (ab_job_list, delpending_cb, ab);
}
void delpending_cb (gpointer element, gpointer user_data)
{
AB_JOB *job = element;
AB_BANKING *ab = user_data;
if (AB_Job_GetStatus (job) == AB_Job_StatusPending)
AB_Banking_DelPendingJob(ab, job);
}
/* ------------------------------------------------------- */
struct cb_struct { struct cb_struct {
gchar **result; gchar **result;
GIConv gnc_iconv_handler; GIConv gnc_iconv_handler;

View File

@ -27,6 +27,7 @@
#include <aqbanking/banking.h> #include <aqbanking/banking.h>
#include <aqbanking/transaction.h> #include <aqbanking/transaction.h>
#include <aqbanking/account.h> #include <aqbanking/account.h>
#include <aqbanking/imexporter.h>
#include <aqbanking/version.h> #include <aqbanking/version.h>
#if AQBANKING_VERSION_MAJOR > 2 #if AQBANKING_VERSION_MAJOR > 2
# define AB_Value_GetValue AB_Value_GetValueAsDouble # define AB_Value_GetValue AB_Value_GetValueAsDouble
@ -47,6 +48,7 @@
#include "Account.h" #include "Account.h"
#include "Transaction.h" #include "Transaction.h"
#include "gnc-book.h" #include "gnc-book.h"
#include "import-main-matcher.h"
#include "hbci-interaction.h" #include "hbci-interaction.h"
@ -112,6 +114,49 @@ gboolean
gnc_AB_BANKING_execute (GtkWidget *parent, AB_BANKING *api, gnc_AB_BANKING_execute (GtkWidget *parent, AB_BANKING *api,
AB_JOB *job, GNCInteractor *inter); AB_JOB *job, GNCInteractor *inter);
/* Calls AB_Banking_executeQueue() with some supplementary stuff
* around it: set the debugLevel, show the GNCInteractor, and do some
* error checking afterwards by checking each AB_JOB in
* job_list. Returns TRUE upon success or FALSE if the calling dialog
* should abort. parent may be NULL, job_list (a GList of AB_JOBs) may
* be NULL (although in this case no HBCI result codes can be
* checked!), inter may be NULL; api must not be NULL. */
gboolean
gnc_hbci_multijob_execute(GtkWidget *parent, AB_BANKING *api,
GList *job_list, GNCInteractor *inter);
/**
* Imports the account/transaction/balance data of an aqbanking
* "imexporter-context" into the matching gnucash accounts, using the
* given importer_generic_gui.
*
* If exec_as_jobs is TRUE, additionally queue each transaction as a
* new aqbanking online banking job.
*
* @param ab The AB_BANKING api object.
*
* @param ctx The "context" object that holds the actual transactions.
*
* @param importer_generic_gui The dialog which should display the
* to-be-imported transactions.
*
* @param exec_as_aqbanking_jobs If TRUE, additionally queue the
* imported transactions as online jobs over aqbanking/HBCI. If FALSE,
* just import the transactions and that's it.
*
* @return If exec_as_aqbanking_jobs was FALSE, this always returns
* NULL. Otherwise it returns a GList of the AB_JOBs that have been
* queued into aqbanking.
*/
GList *
gnc_hbci_import_ctx(AB_BANKING *ab, AB_IMEXPORTER_CONTEXT *ctx,
GNCImportMainMatcher *importer_generic_gui,
gboolean exec_as_aqbanking_jobs);
/** Clear all the AB_JOBs of the ab_job_list from aqbanking's
* queue. */
void
gnc_hbci_clearqueue(AB_BANKING *ab, GList *ab_job_list);
/* Create the appropriate description field for a Gnucash Transaction /* Create the appropriate description field for a Gnucash Transaction
* by the information given in the AB_TRANSACTION h_trans. The * by the information given in the AB_TRANSACTION h_trans. The
@ -127,6 +172,7 @@ char *gnc_hbci_memo_tognc (const AB_TRANSACTION *h_trans);
* returned string must be g_free'd by the caller. If there was no * returned string must be g_free'd by the caller. If there was no
* purpose, an empty (but allocated) string is returned. */ * purpose, an empty (but allocated) string is returned. */
char *gnc_hbci_getpurpose (const AB_TRANSACTION *h_trans); char *gnc_hbci_getpurpose (const AB_TRANSACTION *h_trans);
/** Return the first customer that can act on the specified account, /** Return the first customer that can act on the specified account,
or NULL if none was found (and an error message is printed on or NULL if none was found (and an error message is printed on
stdout). */ stdout). */