mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
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:
parent
a34f91e975
commit
cb02cab345
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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). */
|
||||||
|
Loading…
Reference in New Issue
Block a user