Merge John Ralls's 'aqb-file-import' into master.

This commit is contained in:
John Ralls
2022-10-29 17:29:06 -07:00
27 changed files with 749 additions and 1118 deletions

View File

@@ -2,9 +2,9 @@ name: ci-tests
on: [push, pull_request]
permissions: {}
jobs:
ci_tests_ubuntu-18:
runs-on: ubuntu-18.04
name: Ubuntu-18.04 CI Tests
ci_tests_ubuntu-22:
runs-on: ubuntu-22.04
name: Ubuntu-22.04 CI Tests
env:
TZ: America/Los_Angeles
steps:
@@ -12,7 +12,7 @@ jobs:
uses: actions/checkout@v2
- run: sudo apt-get update
- name: Install additional dependencies
run: sudo apt-get install -y cmake libxslt-dev xsltproc ninja-build libboost-all-dev libgtk-3-dev guile-2.2-dev libgwengui-gtk3-dev libaqbanking-dev libofx-dev libdbi-dev libdbd-sqlite3 libwebkit2gtk-4.0-dev googletest
run: sudo apt-get install -y gettext cmake libxslt-dev xsltproc ninja-build libboost-all-dev libgtk-3-dev guile-2.2-dev libgwengui-gtk3-dev libaqbanking-dev libofx-dev libdbi-dev libdbd-sqlite3 libwebkit2gtk-4.0-dev googletest
- name: Install language packs.
run: sudo apt-get --reinstall install -y language-pack-en language-pack-fr
- run: |
@@ -38,44 +38,3 @@ jobs:
with:
name: TestLog
path: ${{ github.workspace }}/build/Testing/Temporary/LastTest.log
ci_tests_ubuntu-20:
runs-on: ubuntu-20.04
name: Ubuntu-20.04 CI Tests
env:
TZ: America/Los_Angeles
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install apt utils
run: sudo apt-get install -y --no-install-recommends apt-utils
- name: Update apt
run: |
sudo sed -i -e 's/^# deb-src/deb-src/' /etc/apt/sources.list
sudo apt-get update -y
- name: Install additional dependencies
run: |
sudo apt-get build-dep -y gnucash
sudo apt-get install ninja-build guile-3.0-dev libboost-program-options-dev
- name: Install language packs.
run: sudo apt-get --reinstall install -y language-pack-en language-pack-fr
- run: |
echo "ROOT_DIR=$GITHUB_WORKSPACE/.." >> $GITHUB_ENV
- name: Create Directories
run: |
pwd
mkdir $ROOT_DIR/inst
mkdir build
- name: Configure GnuCash
run: |
cd build
cmake -G Ninja -DWITH_PYTHON=ON -DCMAKE_INSTALL_PREFIX=$ROOT_DIR/inst $GITHUB_WORKSPACE
- name: Build and Test GnuCash
run: |
cd build
ninja
ninja check
- uses: actions/upload-artifact@v2
if: failure()
with:
name: TestLog
path: ${{ github.workspace }}/build/Testing/Temporary/LastTest.log

View File

@@ -18,7 +18,7 @@ jobs:
uses: carlosperate/download-file-action@v1.0.3
id: dependencies
with:
file-url: 'https://downloads.sourceforge.net/gnucash/Dependencies/gnucash-4.x-mac-dependencies.tar.xz'
file-url: 'https://downloads.sourceforge.net/gnucash/Dependencies/gnucash-4.900-mac-dependencies.tar.xz'
file-name: gnucash-dependencies.tar.xz
- name: download googletest
uses: carlosperate/download-file-action@v1.0.3

View File

@@ -48,7 +48,7 @@ include (TestBigEndian)
# SQL, put -D WITH_SQL=OFF on the command line.
option (WITH_SQL "Build this project with SQL (libdbi) support" ON)
option (WITH_AQBANKING "Build this project with aqbanking (online banking) support" ON)
option (WITH_AQBANKING "Build this project with aqbanking (online banking and a variety of file import formats) support" ON)
option (WITH_GNUCASH "Build all of GnuCash, not just the library" ON)
option (WITH_OFX "compile with ofx support (needs LibOFX)" ON)
option (WITH_PYTHON "enable python plugin and bindings" OFF)
@@ -358,8 +358,8 @@ find_guile_dirs()
# ############################################################
if (WITH_AQBANKING)
pkg_check_modules (GWENHYWFAR REQUIRED gwenhywfar>=4.20)
pkg_check_modules (AQBANKING REQUIRED aqbanking>=5.7.8)
pkg_check_modules (GWENHYWFAR REQUIRED gwenhywfar>=5.8.0)
pkg_check_modules (AQBANKING REQUIRED aqbanking>=6.4.0)
set(CMAKE_REQUIRED_INCLUDES "${AQBANKING_INCLUDE_DIRS}"
"${GWENHYWFAR_INCLUDE_DIRS}")
set(CMAKE_REQUIRED_LIBRARIES "${AQBANKING_LD_FLAGS}")

View File

@@ -93,9 +93,8 @@ Libraries/Deps
optional
--------
aqbanking 5.7.8 online banking; Note that 6.1.0
gwenhywfar 4.20.0 or higher is needed for German
FinTS.
aqbanking 6.4.0 online banking and SWIFT
gwenhywfar 5.8.0 file imports.
python 3.6.0 python bindings; headers
required, not just binaries.

View File

@@ -6,6 +6,7 @@ add_subdirectory(test)
set (aqbanking_SOURCES
dialog-ab-trans.c
dialog-ab-daterange.c
dialog-ab-select-imexporter.c
assistant-ab-initial.c
gnc-ab-getbalance.c
gnc-ab-gettrans.c
@@ -25,6 +26,7 @@ set_source_files_properties (${aqbanking_SOURCES} PROPERTIES OBJECT_DEPENDS ${CO
set (aqbanking_noinst_HEADERS
dialog-ab-trans.h
dialog-ab-daterange.h
dialog-ab-select-imexporter.h
assistant-ab-initial.h
gnc-ab-getbalance.h
gnc-ab-gettrans.h

View File

@@ -40,10 +40,8 @@
#include "gnc-ab-utils.h" /* For version macros */
#include <aqbanking/banking.h>
#ifdef AQBANKING6
#include <aqbanking/types/account_spec.h>
#include <gwenhywfar/gui.h>
#endif
#include <glib.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>
@@ -65,9 +63,6 @@
#include "gnc-session.h"
#include "import-account-matcher.h"
#include "import-utilities.h"
#ifndef AQBANKING6
# include <aqbanking/dlg_setup.h>
#endif
/* This static indicates the debugging module that this .o belongs to. */
static QofLogModule log_module = GNC_MOD_ASSISTANT;
@@ -92,10 +87,8 @@ void aai_page_prepare (GtkAssistant *assistant, gpointer user_data);
void aai_button_clicked_cb(GtkButton *button, gpointer user_data);
void aai_match_delete_button_clicked_cb(GtkButton *button, gpointer user_data);
#ifdef AQBANKING6
static guint aai_ab_account_hash(gconstpointer v);
static gboolean aai_ab_account_equal(gconstpointer v1, gconstpointer v2);
#endif
void aai_match_page_prepare (GtkAssistant *assistant, gpointer user_data);
static gboolean banking_has_accounts(AB_BANKING *banking);
@@ -207,9 +200,6 @@ aai_destroy_cb(GtkWidget *object, gpointer user_data)
if (info->gnc_hash)
{
#ifndef AQBANKING6
AB_Banking_OnlineFini(info->api);
#endif
g_hash_table_destroy(info->gnc_hash);
info->gnc_hash = NULL;
}
@@ -268,16 +258,7 @@ aai_button_clicked_cb(GtkButton *button, gpointer user_data)
}
{
#ifdef AQBANKING6
GWEN_DIALOG *dlg = AB_Banking_CreateSetupDialog(banking);
#else
GWEN_DIALOG *dlg = AB_SetupDialog_new(banking);
if (AB_Banking_OnlineInit(banking) != 0)
{
PERR("Got error on AB_Banking_OnlineInit!");
}
#endif
if (!dlg)
{
PERR("Could not lookup Setup Dialog of aqbanking!");
@@ -292,12 +273,6 @@ aai_button_clicked_cb(GtkButton *button, gpointer user_data)
}
GWEN_Dialog_free(dlg);
}
#ifndef AQBANKING6
if (AB_Banking_OnlineFini(banking) != 0)
{
PERR("Got error on AB_Banking_OnlineFini!");
}
#endif
}
/* Enable the Assistant Buttons if we accounts */
@@ -369,7 +344,6 @@ aai_match_delete_button_clicked_cb(GtkButton *button, gpointer user_data)
}
}
#ifdef AQBANKING6
static guint
aai_ab_account_hash (gconstpointer v)
{
@@ -393,7 +367,6 @@ aai_ab_account_equal (gconstpointer v1, gconstpointer v2)
return uid1 == uid2;
}
}
#endif
static void
insert_acc_into_revhash_cb(gpointer ab_acc, gpointer gnc_acc, gpointer revhash)
@@ -424,17 +397,9 @@ aai_match_page_prepare (GtkAssistant *assistant, gpointer user_data)
/* Do not run this twice */
if (!info->match_page_prepared)
{
#ifndef AQBANKING6
/* Load aqbanking accounts */
AB_Banking_OnlineInit(info->api);
#endif
/* Determine current mapping */
root = gnc_book_get_root_account(gnc_get_current_book());
#ifdef AQBANKING6
info->gnc_hash = g_hash_table_new(&aai_ab_account_hash, &aai_ab_account_equal);
#else
info->gnc_hash = g_hash_table_new(&g_direct_hash, &g_direct_equal);
#endif
data.api = info->api;
data.hash = info->gnc_hash;
gnc_account_foreach_descendant(root, (AccountCb) hash_from_kvp_acc_cb, &data);
@@ -479,24 +444,11 @@ banking_has_accounts(AB_BANKING *banking)
g_return_val_if_fail(banking, FALSE);
#ifdef AQBANKING6
if (AB_Banking_GetAccountSpecList (banking, &accl) >= 0 &&
accl && AB_AccountSpec_List_GetCount (accl))
result = TRUE;
if (accl)
AB_AccountSpec_List_free (accl);
#else
AB_Banking_OnlineInit(banking);
accl = AB_Banking_GetAccounts(banking);
if (accl && (AB_Account_List2_GetSize(accl) > 0))
result = TRUE;
if (accl)
AB_Account_List2_free(accl);
AB_Banking_OnlineFini(banking);
#endif
return result;
}
@@ -521,17 +473,9 @@ ab_account_longname(const GNC_AB_ACCOUNT_SPEC *ab_acc)
g_return_val_if_fail(ab_acc, NULL);
#ifdef AQBANKING6
bankcode = AB_AccountSpec_GetBankCode(ab_acc);
subAccountId = AB_AccountSpec_GetSubAccountNumber(ab_acc);
account_number = AB_AccountSpec_GetAccountNumber (ab_acc);
#else
ab_bankname = AB_Account_GetBankName(ab_acc);
bankname = ab_bankname ? gnc_utf8_strip_invalid_strdup(ab_bankname) : NULL;
bankcode = AB_Account_GetBankCode(ab_acc);
subAccountId = AB_Account_GetSubAccountId(ab_acc);
account_number = AB_Account_GetAccountNumber (ab_acc);
#endif
/* Translators: Strings are 1. Bank code, 2. Bank name,
3. Account Number, 4. Subaccount ID */
result = g_strdup_printf(_("Bank code %s (%s), Account %s (%s)"),
@@ -593,14 +537,8 @@ update_account_list(ABInitialInfo *info)
/* Refill the list */
gtk_list_store_clear(info->account_store);
#ifdef AQBANKING6
if (AB_Banking_GetAccountSpecList(info->api, &acclist) >= 0 && acclist)
AB_AccountSpec_List_ForEach(acclist, update_account_list_acc_cb, info);
#else
acclist = AB_Banking_GetAccounts(info->api);
if (acclist)
AB_Account_List2_ForEach(acclist, update_account_list_acc_cb, info);
#endif
else
g_warning("update_account_list: Oops, account list from AB_Banking "
"is NULL");
@@ -639,11 +577,7 @@ clear_line_cb(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
gtk_tree_model_get(model, iter, ACCOUNT_LIST_COL_AB_ACCT, &ab_acc, -1);
#ifdef AQBANKING6
if (aai_ab_account_equal(ab_acc, data->ab_acc))
#else
if (ab_acc == data->ab_acc)
#endif
{
gtk_list_store_set(store, iter, ACCOUNT_LIST_COL_GNC_NAME, "",
ACCOUNT_LIST_COL_CHECKED, TRUE, -1);
@@ -682,11 +616,7 @@ account_list_clicked_cb (GtkTreeView *view, GtkTreePath *path,
old_value = g_hash_table_lookup(info->gnc_hash, ab_acc);
longname = ab_account_longname(ab_acc);
#ifdef AQBANKING6
currency = AB_AccountSpec_GetCurrency(ab_acc);
#else
currency = AB_Account_GetCurrency(ab_acc);
#endif
if (currency && *currency)
{
commodity = gnc_commodity_table_lookup(
@@ -753,51 +683,35 @@ save_kvp_acc_cb(gpointer key, gpointer value, gpointer user_data)
guint32 ab_account_uid;
const gchar *ab_accountid, *gnc_accountid;
const gchar *ab_bankcode, *gnc_bankcode;
#ifdef AQBANKING6
gchar *ab_online_id;
gchar *gnc_online_id;
#endif
g_return_if_fail(ab_acc && gnc_acc);
#ifdef AQBANKING6
ab_account_uid = AB_AccountSpec_GetUniqueId(ab_acc);
#else
ab_account_uid = AB_Account_GetUniqueId(ab_acc);
#endif
if (gnc_ab_get_account_uid(gnc_acc) != ab_account_uid)
gnc_ab_set_account_uid(gnc_acc, ab_account_uid);
#ifdef AQBANKING6
ab_accountid = AB_AccountSpec_GetAccountNumber(ab_acc);
#else
ab_accountid = AB_Account_GetAccountNumber(ab_acc);
#endif
gnc_accountid = gnc_ab_get_account_accountid(gnc_acc);
if (ab_accountid
&& (!gnc_accountid
|| (strcmp(ab_accountid, gnc_accountid) != 0)))
gnc_ab_set_account_accountid(gnc_acc, ab_accountid);
#ifdef AQBANKING6
ab_bankcode = AB_AccountSpec_GetBankCode(ab_acc);
#else
ab_bankcode = AB_Account_GetBankCode(ab_acc);
#endif
gnc_bankcode = gnc_ab_get_account_bankcode(gnc_acc);
if (ab_bankcode
&& (!gnc_bankcode
|| (strcmp(gnc_bankcode, ab_bankcode) != 0)))
gnc_ab_set_account_bankcode(gnc_acc, ab_bankcode);
#ifdef AQBANKING6
ab_online_id = gnc_ab_create_online_id(ab_bankcode, ab_accountid);
gnc_online_id = gnc_import_get_acc_online_id(gnc_acc);
if (ab_online_id && (!gnc_online_id || (strcmp(ab_online_id, gnc_online_id) != 0)))
gnc_import_set_acc_online_id(gnc_acc, ab_online_id);
g_free(ab_online_id);
g_free (gnc_online_id);
#endif
}
static void

View File

@@ -0,0 +1,245 @@
/*
* dialog-ab-select-imexporter.c --
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
/**
* @internal
* @file dialog-ab-select-imexporter.h
* @brief Dialog to select AQBanking importer/exporter and format profile.
* @author Copyright (C) 2022 John Ralls <jralls@ceridwen.us>
*/
#include <config.h>
#include <glib/gi18n.h>
#include "dialog-ab-select-imexporter.h"
#include <dialog-utils.h>
static QofLogModule log_module = G_LOG_DOMAIN;
struct _GncABSelectImExDlg
{
GtkWidget *dialog;
GtkWidget *parent;
GtkListStore *imexporter_list;
GtkListStore *profile_list;
GtkWidget *select_imexporter;
GtkWidget *select_profile;
GtkWidget *ok_button;
AB_BANKING* abi;
};
// Expose the selection handlers to GtkBuilder.
static gboolean imexporter_changed(GtkTreeSelection* sel,
gpointer data);
static gboolean profile_changed(GtkTreeSelection* sel, gpointer data);
enum
{
NAME_COL,
PROF_COL
};
static void
populate_list_store (GtkListStore* model, GList* entries)
{
gtk_list_store_clear (model);
for (GList* node = entries; node; node = g_list_next (node))
{
AB_Node_Pair *pair = (AB_Node_Pair*)(node->data);
GtkTreeIter iter;
gtk_list_store_insert_with_values (GTK_LIST_STORE (model),
&iter, -1,
NAME_COL, pair->name,
PROF_COL, pair->descr,
-1);
g_slice_free1 (sizeof(AB_Node_Pair), pair);
}
}
GncABSelectImExDlg*
gnc_ab_select_imex_dlg_new (GtkWidget* parent, AB_BANKING* abi)
{
GncABSelectImExDlg* imexd;
GtkBuilder* builder;
GList* imexporters;
GtkTreeSelection *imex_select = NULL, *prof_select = NULL;
g_return_val_if_fail (abi, NULL);
imexporters = gnc_ab_imexporter_list (abi);
g_return_val_if_fail (imexporters, NULL);
imexd = g_new0(GncABSelectImExDlg, 1);
imexd->parent = parent;
imexd->abi = abi;
g_signal_connect (parent, "destroy",
G_CALLBACK (gtk_widget_destroyed), &imexd->parent);
builder = gtk_builder_new();
gnc_builder_add_from_file (builder, "dialog-ab.glade", "imexporter-list");
gnc_builder_add_from_file (builder, "dialog-ab.glade", "profile-list");
gnc_builder_add_from_file (builder, "dialog-ab.glade",
"aqbanking-select-imexporter-dialog");
imexd->dialog =
GTK_WIDGET (gtk_builder_get_object (builder,
"aqbanking-select-imexporter-dialog"));
g_signal_connect (imexd->dialog, "destroy",
G_CALLBACK (gtk_widget_destroyed), &imexd->dialog);
imexd->imexporter_list =
GTK_LIST_STORE (gtk_builder_get_object (builder, "imexporter-list"));
imexd->profile_list =
GTK_LIST_STORE (gtk_builder_get_object (builder, "profile-list"));
imexd->select_imexporter =
GTK_WIDGET (gtk_builder_get_object (builder, "imexporter-sel"));
imexd->select_profile =
GTK_WIDGET (gtk_builder_get_object (builder, "profile-sel"));
imexd->ok_button =
GTK_WIDGET (gtk_builder_get_object (builder, "imex-okbutton"));
imex_select = GTK_TREE_SELECTION (gtk_builder_get_object (builder, "imex-selection"));
prof_select = GTK_TREE_SELECTION (gtk_builder_get_object (builder, "prof-selection"));
populate_list_store (imexd->imexporter_list,
imexporters);
g_signal_connect (imex_select, "changed", G_CALLBACK(imexporter_changed),
imexd);
g_signal_connect (prof_select, "changed", G_CALLBACK(profile_changed),
imexd);
g_list_free (imexporters);
g_object_unref (G_OBJECT (builder));
gtk_window_set_transient_for (GTK_WINDOW (imexd->dialog),
GTK_WINDOW (imexd->parent));
return imexd;
}
void
gnc_ab_select_imex_dlg_destroy (GncABSelectImExDlg* imexd)
{
if (imexd->imexporter_list)
gtk_list_store_clear (imexd->imexporter_list);
if (imexd->profile_list)
gtk_list_store_clear (imexd->profile_list);
if (imexd->dialog)
gtk_widget_destroy (imexd->dialog);
g_free (imexd);
}
gboolean
imexporter_changed(GtkTreeSelection* sel, gpointer data)
{
GncABSelectImExDlg* imexd = (GncABSelectImExDlg*)data;
GtkTreeIter iter;
GtkTreeModel* model;
gtk_widget_set_sensitive (imexd->ok_button, FALSE);
if (gtk_tree_selection_get_selected (sel, &model, &iter))
{
char* name = NULL;
GList* profiles = NULL;
gtk_tree_model_get (model, &iter, NAME_COL, &name, -1);
if (name && *name)
profiles = gnc_ab_imexporter_profile_list (imexd->abi, name);
g_free (name);
gtk_list_store_clear (imexd->profile_list);
if (profiles)
{
populate_list_store (imexd->profile_list, profiles);
}
else
{
gtk_widget_set_sensitive (imexd->ok_button, TRUE);
return FALSE;
}
if (!profiles->next)
{
GtkTreePath* path = gtk_tree_path_new_first();
GtkTreeSelection* profile_sel =
gtk_tree_view_get_selection (GTK_TREE_VIEW (imexd->select_profile));
gtk_tree_selection_select_path (profile_sel, path); //should call profile_changed
gtk_tree_path_free (path);
}
return FALSE;
}
return TRUE;
}
gboolean
profile_changed (GtkTreeSelection* sel, gpointer data)
{
GncABSelectImExDlg* imexd = (GncABSelectImExDlg*)data;
GtkTreeIter iter;
GtkTreeModel* model;
gtk_widget_set_sensitive (imexd->ok_button, FALSE);
if (gtk_tree_selection_get_selected (sel, &model, &iter))
{
gtk_widget_set_sensitive (imexd->ok_button, TRUE);
return FALSE;
}
return TRUE;
}
gboolean
gnc_ab_select_imex_dlg_run (GncABSelectImExDlg* imexd)
{
int response = gtk_dialog_run (GTK_DIALOG (imexd->dialog));
return response == GTK_RESPONSE_OK ? TRUE : FALSE;
}
static char*
tree_view_get_name (GtkTreeView *tv)
{
GtkTreeSelection* sel = gtk_tree_view_get_selection (tv);
GtkTreeIter iter;
GtkTreeModel* model;
if (sel && gtk_tree_selection_get_selected (sel, &model, &iter))
{
char* name;
gtk_tree_model_get(model, &iter, NAME_COL, &name, -1);
return name;
}
return NULL;
}
char*
gnc_ab_select_imex_dlg_get_imexporter_name (GncABSelectImExDlg* imexd)
{
return tree_view_get_name (GTK_TREE_VIEW (imexd->select_imexporter));
}
char*
gnc_ab_select_imex_dlg_get_profile_name (GncABSelectImExDlg* imexd)
{
return tree_view_get_name (GTK_TREE_VIEW (imexd->select_profile));
}

View File

@@ -0,0 +1,87 @@
/*
* dialog-ab-select-imexporter.h --
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
/**
* @addtogroup Import_Export
* @{
* @addtogroup AqBanking
* @{
* @file dialog-ab-select-imexporter.h
* @brief Dialog to select AQBanking importer/exporter and format profile.
* @author Copyright (C) 2022 John Ralls <jralls@ceridwen.us>
*/
#ifndef DIALOG_AB_SELECT_IMEXPORTER_H
#define DIALOG_AB_SELECT_IMEXPORTER_H
#include "gnc-ab-utils.h"
#include <gtk/gtk.h>
#include <aqbanking/banking.h>
typedef struct _GncABSelectImExDlg GncABSelectImExDlg;
G_BEGIN_DECLS
/**
* Create an AQBanking importer/exporter selection dialog.
* @param parent A widget to center the dialog over.
* @param abi The AQBanking instance to query.
* @return a GncABSelectImExDlg.
*/
GncABSelectImExDlg* gnc_ab_select_imex_dlg_new (GtkWidget* parent,
AB_BANKING* abi);
/**
* Destroy an AQBanking importer/exporter selection dialog.
* @param imexd the dialog.
*/
void gnc_ab_select_imex_dlg_destroy (GncABSelectImExDlg* imexd);
/**
* Run an AQBanking importer/exporter selection dialog.
* @param imexd the dialog.
* @return A GTK_RESPONSE status.
*/
int gnc_ab_select_imex_dlg_run (GncABSelectImExDlg* imexd);
/**
* Get the selected importer/exporter name
* @param imexd the dialog with the selection
* @return the selected importer/exporter name, free with g_free.
*/
char*
gnc_ab_select_imex_dlg_get_imexporter_name (GncABSelectImExDlg* imexd);
/**
* Get the selected file format profile name
* @param imexd the dialog with the selection
* @return the selected format profile name, free with g_free.
*/
char*
gnc_ab_select_imex_dlg_get_profile_name (GncABSelectImExDlg* imexd);
G_END_DECLS
#endif //DIALOG_AB_SELECT_IMEXPORTER_H
/**
* @}
* @}
*/

View File

@@ -32,16 +32,8 @@
#include <config.h>
#include <glib/gi18n.h>
#include "gnc-ab-utils.h" /* for AQBANKING6 */
#ifdef AQBANKING6
# include <aqbanking/types/transaction.h>
#else
# include <aqbanking/jobsingletransfer.h>
# include <aqbanking/jobsingledebitnote.h>
# include <aqbanking/jobinternaltransfer.h>
# include <aqbanking/jobsepatransfer.h>
# include <aqbanking/jobsepadebitnote.h>
#endif
#include "gnc-ab-utils.h"
#include <aqbanking/types/transaction.h>
#include <gnc-aqbanking-templates.h>
#include "dialog-ab-trans.h"
@@ -72,26 +64,26 @@ static void gnc_ab_trans_dialog_check_iban(const GncABTransDialog *td,
const AB_TRANSACTION *trans);
/* Callbacks - connected with GtkBuilder */
G_MODULE_EXPORT void gnc_ab_trans_dialog_add_templ_cb(GtkButton *button, gpointer user_data);
G_MODULE_EXPORT void gnc_ab_trans_dialog_moveup_templ_cb(GtkButton *button, gpointer user_data);
G_MODULE_EXPORT void gnc_ab_trans_dialog_movedown_templ_cb(GtkButton *button, gpointer user_data);
G_MODULE_EXPORT void gnc_ab_trans_dialog_sort_templ_cb(GtkButton *button, gpointer user_data);
G_MODULE_EXPORT void gnc_ab_trans_dialog_del_templ_cb(GtkButton *button, gpointer user_data);
G_MODULE_EXPORT void gnc_ab_trans_dialog_ibanentry_filter_cb (GtkEditable *editable,
static void gnc_ab_trans_dialog_add_templ_cb(GtkButton *button, gpointer user_data);
static void gnc_ab_trans_dialog_moveup_templ_cb(GtkButton *button, gpointer user_data);
static void gnc_ab_trans_dialog_movedown_templ_cb(GtkButton *button, gpointer user_data);
static void gnc_ab_trans_dialog_sort_templ_cb(GtkButton *button, gpointer user_data);
static void gnc_ab_trans_dialog_del_templ_cb(GtkButton *button, gpointer user_data);
static void gnc_ab_trans_dialog_ibanentry_filter_cb (GtkEditable *editable,
const gchar *text,
gint length,
gint *position,
gpointer user_data);
G_MODULE_EXPORT void gnc_ab_trans_dialog_bicentry_filter_cb (GtkEditable *editable,
static void gnc_ab_trans_dialog_bicentry_filter_cb (GtkEditable *editable,
const gchar *text,
gint length,
gint *position,
gpointer user_data);
G_MODULE_EXPORT void gnc_ab_trans_dialog_templ_list_row_activated_cb(GtkTreeView *view,
static void gnc_ab_trans_dialog_templ_list_row_activated_cb(GtkTreeView *view,
GtkTreePath *path,
GtkTreeViewColumn *column,
gpointer user_data);
G_MODULE_EXPORT void gnc_ab_trans_dialog_verify_values(GncABTransDialog *td);
static void gnc_ab_trans_dialog_verify_values(GncABTransDialog *td);
enum
@@ -189,11 +181,7 @@ gnc_ab_trans_dialog_fill_values(GncABTransDialog *td)
AB_TRANSACTION *trans = AB_Transaction_new();
AB_VALUE *value;
#ifdef AQBANKING6
AB_Banking_FillTransactionFromAccountSpec(trans, td->ab_acc);
#else
AB_Transaction_FillLocalFromAccount(trans, td->ab_acc);
#endif
if (gnc_ab_trans_isSEPA(td->trans_type))
{
@@ -212,7 +200,6 @@ gnc_ab_trans_dialog_fill_values(GncABTransDialog *td)
trans, gtk_entry_get_text(GTK_ENTRY(td->recp_account_entry)));
}
AB_Transaction_SetRemoteCountry(trans, "DE");
#ifdef AQBANKING6
AB_Transaction_SetRemoteName(
trans, gtk_entry_get_text(GTK_ENTRY(td->recp_name_entry)));
@@ -222,19 +209,6 @@ gnc_ab_trans_dialog_fill_values(GncABTransDialog *td)
trans, gtk_entry_get_text(GTK_ENTRY(td->purpose_cont_entry)));
AB_Transaction_AddPurposeLine(
trans, gtk_entry_get_text(GTK_ENTRY(td->purpose_cont2_entry)));
#else
AB_Transaction_AddRemoteName(
trans, gtk_entry_get_text(GTK_ENTRY(td->recp_name_entry)), FALSE);
AB_Transaction_AddPurpose(
trans, gtk_entry_get_text(GTK_ENTRY(td->purpose_entry)), FALSE);
AB_Transaction_AddPurpose(
trans, gtk_entry_get_text(GTK_ENTRY(td->purpose_cont_entry)), FALSE);
AB_Transaction_AddPurpose(
trans, gtk_entry_get_text(GTK_ENTRY(td->purpose_cont2_entry)), FALSE);
AB_Transaction_AddPurpose(
trans, gtk_entry_get_text(GTK_ENTRY(td->purpose_cont3_entry)), FALSE);
#endif
value = AB_Value_fromDouble(gnc_amount_edit_get_damount(
GNC_AMOUNT_EDIT(td->amount_edit)));
/* FIXME: Replace "EUR" by account-dependent string here. */
@@ -294,23 +268,12 @@ gnc_ab_trans_dialog_new(GtkWidget *parent, GNC_AB_ACCOUNT_SPEC *ab_acc,
g_return_val_if_fail(ab_acc, NULL);
#ifdef AQBANKING6
ab_ownername = AB_AccountSpec_GetOwnerName(ab_acc);
if (!ab_ownername)
ab_ownername = "";
ab_accountnumber = AB_AccountSpec_GetAccountNumber(ab_acc);
ab_bankcode = AB_AccountSpec_GetBankCode(ab_acc);
ab_bankname = _("(unknown)");
#else
ab_ownername = AB_Account_GetOwnerName(ab_acc);
if (!ab_ownername)
ab_ownername = "";
ab_accountnumber = AB_Account_GetAccountNumber(ab_acc);
ab_bankcode = AB_Account_GetBankCode(ab_acc);
ab_bankname = AB_Account_GetBankName(ab_acc);
if (!ab_bankname || !*ab_bankname)
ab_bankname = _("(unknown)");
#endif
td = g_new0(GncABTransDialog, 1);
td->parent = parent;
@@ -474,13 +437,8 @@ gnc_ab_trans_dialog_new(GtkWidget *parent, GNC_AB_ACCOUNT_SPEC *ab_acc,
if (gnc_ab_trans_isSEPA(trans_type))
{
gtk_widget_set_sensitive(GTK_WIDGET(td->orig_name_entry), TRUE);
#if AQBANKING6
ab_accountnumber = AB_AccountSpec_GetIban(ab_acc);
ab_bankcode = AB_AccountSpec_GetBic(ab_acc);
#else
ab_accountnumber = AB_Account_GetIBAN(ab_acc);
ab_bankcode = AB_Account_GetBIC(ab_acc);
#endif
gtk_label_set_text(GTK_LABEL(orig_account_label), ab_accountnumber);
gtk_label_set_text (GTK_LABEL (orig_bankcode_label), ab_bankcode);
}
@@ -711,11 +669,7 @@ gnc_ab_trans_dialog_run_until_ok(GncABTransDialog *td)
}
/* Activate as many purpose entries as available for the job */
#ifdef AQBANKING6
joblimits = AB_AccountSpec_GetTransactionLimitsForCommand(td->ab_acc, AB_Transaction_GetCommand(job));
#else
joblimits = AB_Job_GetFieldLimits (job);
#endif
max_purpose_lines = joblimits ?
AB_TransactionLimits_GetMaxLinesPurpose(joblimits) : 2;
gtk_widget_set_sensitive(td->purpose_cont_entry, max_purpose_lines > 1);
@@ -855,7 +809,6 @@ static GNC_AB_JOB *
gnc_ab_trans_dialog_get_available_empty_job(GNC_AB_ACCOUNT_SPEC *ab_acc, GncABTransType trans_type)
{
GNC_AB_JOB *job;
#ifdef AQBANKING6
AB_TRANSACTION_COMMAND cmd = AB_Transaction_CommandUnknown;
switch (trans_type)
@@ -869,11 +822,9 @@ gnc_ab_trans_dialog_get_available_empty_job(GNC_AB_ACCOUNT_SPEC *ab_acc, GncABTr
case SEPA_TRANSFER:
cmd=AB_Transaction_CommandSepaTransfer;
break;
#if (AQBANKING_VERSION_INT >= 60400)
case SEPA_INTERNAL_TRANSFER:
cmd=AB_Transaction_CommandSepaInternalTransfer;
break;
#endif
case SEPA_DEBITNOTE:
cmd=AB_Transaction_CommandSepaDebitNote;
break;
@@ -887,32 +838,6 @@ gnc_ab_trans_dialog_get_available_empty_job(GNC_AB_ACCOUNT_SPEC *ab_acc, GncABTr
job = AB_Transaction_new();
AB_Transaction_SetCommand(job, cmd);
AB_Transaction_SetUniqueAccountId(job, AB_AccountSpec_GetUniqueId(ab_acc));
#else
switch (trans_type)
{
case SINGLE_DEBITNOTE:
job = AB_JobSingleDebitNote_new(ab_acc);
break;
case SINGLE_INTERNAL_TRANSFER:
job = AB_JobInternalTransfer_new(ab_acc);
break;
case SINGLE_TRANSFER:
job = AB_JobSingleTransfer_new(ab_acc);
break;
case SEPA_DEBITNOTE:
job = AB_JobSepaDebitNote_new(ab_acc);
break;
case SEPA_TRANSFER:
default:
job = AB_JobSepaTransfer_new(ab_acc);
break;
};
if (!job || AB_Job_CheckAvailability(job))
{
if (job) AB_Job_free(job);
return NULL;
}
#endif
return job;
}
@@ -932,7 +857,6 @@ gnc_ab_get_trans_job(GNC_AB_ACCOUNT_SPEC *ab_acc,
g_return_val_if_fail(ab_acc && ab_trans, NULL);
#ifdef AQBANKING6
job = gnc_ab_trans_dialog_get_available_empty_job(ab_acc, trans_type);
if (job)
{
@@ -949,14 +873,6 @@ gnc_ab_get_trans_job(GNC_AB_ACCOUNT_SPEC *ab_acc,
}
return NULL;
#else
job = gnc_ab_trans_dialog_get_available_empty_job(ab_acc, trans_type);
if (job)
{
AB_Job_SetTransaction(job, ab_trans);
}
return job;
#endif
}
void

View File

@@ -1643,4 +1643,189 @@
<action-widget response="-8">exec_now_button</action-widget>
</action-widgets>
</object>
<object class="GtkListStore" id="imexporter-list">
<columns>
<column type="gchararray"/>
<column type="gchararray"/>
</columns>
</object>
<object class="GtkListStore" id="profile-list">
<columns>
<column type="gchararray"/>
<column type="gchararray"/>
</columns>
</object>
<object class="GtkDialog" id="aqbanking-select-imexporter-dialog">
<property name="can-focus">False</property>
<property name="border-width">5</property>
<property name="title" translatable="yes">Select File Importer/Exporter</property>
<property name="type-hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox3">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area3">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="layout-style">end</property>
<child>
<object class="GtkButton" id="imex-cancelbutton">
<property name="label" translatable="yes">_Cancel</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="can-default">True</property>
<property name="receives-default">True</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="imex-okbutton">
<property name="label" translatable="yes">_OK</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="can-default">True</property>
<property name="receives-default">True</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack-type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="selector-box">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="border-width">5</property>
<property name="orientation">horizontal</property>
<property name="spacing">18</property>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="hscrollbar-policy">never</property>
<property name="shadow-type">in</property>
<property name="min-content-height">300</property>
<child>
<object class="GtkTreeView" id="imexporter-sel">
<property name="model">imexporter-list</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<child>
<object class="GtkTreeViewColumn" id="imexporter-name">
<property name="title" translatable="yes">Name</property>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="imexporter-descr">
<property name="title" translatable="yes">Description</property>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
</child>
<child internal-child="selection">
<object class="GtkTreeSelection" id="imex-selection">
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="hscrollbar-policy">never</property>
<property name="shadow-type">in</property>
<property name="min-content-height">300</property>
<child>
<object class="GtkTreeView" id="profile-sel">
<property name="model">profile-list</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<!-- Request the maximum width for the profile
list so that it doesn't change the dialog
width when an imexporter with long
descriptions is selected. -->
<property name="width-request">400</property>
<child>
<object class="GtkTreeViewColumn" id="profile-name">
<property name="title" translatable="yes">Name</property>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="profile-descr">
<property name="title" translatable="yes">Description</property>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
</child>
<child internal-child="selection">
<object class="GtkTreeSelection" id="prof-selection">
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-6">imex-cancelbutton</action-widget>
<action-widget response="-5">imex-okbutton</action-widget>
</action-widgets>
</object>
</interface>

View File

@@ -33,11 +33,7 @@
#include <glib/gi18n.h>
#include <aqbanking/banking.h>
#ifdef AQBANKING6
# include <aqbanking/types/transaction.h>
#else
#include <aqbanking/jobgetbalance.h>
#endif
#include "gnc-ab-getbalance.h"
#include "gnc-ab-kvp.h"
@@ -70,14 +66,6 @@ gnc_ab_getbalance(GtkWidget *parent, Account *gnc_acc)
return;
}
#ifndef AQBANKING6
if (AB_Banking_OnlineInit(api) != 0)
{
g_warning("gnc_ab_gettrans: Couldn't initialize AqBanking API");
goto cleanup;
}
online = TRUE;
#endif
/* Get the AqBanking Account */
ab_acc = gnc_ab_get_ab_account(api, gnc_acc);
if (!ab_acc)
@@ -88,29 +76,19 @@ gnc_ab_getbalance(GtkWidget *parent, Account *gnc_acc)
}
/* Get a GetBalance job and enqueue it */
#ifdef AQBANKING6
if (!AB_AccountSpec_GetTransactionLimitsForCommand(ab_acc, AB_Transaction_CommandGetBalance))
#else
job = AB_JobGetBalance_new(ab_acc);
if (!job || AB_Job_CheckAvailability(job))
#endif
{
g_warning("gnc_ab_getbalance: JobGetBalance not available for this "
"account");
gnc_error_dialog (GTK_WINDOW (parent), _("Online action \"Get Balance\" not available for this account."));
goto cleanup;
}
#ifdef AQBANKING6
job = AB_Transaction_new();
AB_Transaction_SetCommand(job, AB_Transaction_CommandGetBalance);
AB_Transaction_SetUniqueAccountId(job, AB_AccountSpec_GetUniqueId(ab_acc));
job_list = AB_Transaction_List2_new();
AB_Transaction_List2_PushBack(job_list, job);
#else
job_list = AB_Job_List2_new();
AB_Job_List2_PushBack(job_list, job);
#endif
/* Get a GUI object */
gui = gnc_GWEN_Gui_get(parent);
if (!gui)
@@ -123,38 +101,21 @@ gnc_ab_getbalance(GtkWidget *parent, Account *gnc_acc)
context = AB_ImExporterContext_new();
/* Execute the job */
#ifdef AQBANKING6
AB_Banking_SendCommands(api, job_list, context);
#else
AB_Banking_ExecuteJobs(api, job_list, context);
#endif
/* 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
*/
#ifdef AQBANKING6
job_status = AB_Transaction_GetStatus(job);
if (job_status != AB_Transaction_StatusEnqueued
&& job_status != AB_Transaction_StatusPending
&& job_status != AB_Transaction_StatusAccepted)
#else
job_status = AB_Job_GetStatus(job);
if (job_status != AB_Job_StatusFinished
&& job_status != AB_Job_StatusPending)
#endif
{
g_warning("gnc_ab_getbalance: Error on executing job: %d", job_status);
#ifdef AQBANKING6
gnc_error_dialog (GTK_WINDOW (parent),
_("Error on executing job.\n\nStatus: %s"),
AB_Transaction_Status_toString(job_status));
#else
gnc_error_dialog (GTK_WINDOW (parent),
_("Error on executing job.\n\nStatus: %s - %s"),
AB_Job_Status2Char(job_status),
AB_Job_GetResultText(job));
#endif
goto cleanup;
}
@@ -168,18 +129,9 @@ cleanup:
AB_ImExporterContext_free(context);
if (gui)
gnc_GWEN_Gui_release(gui);
#ifdef AQBANKING6
if (job_list)
AB_Transaction_List2_free(job_list);
if (job)
AB_Transaction_free(job);
#else
if (job_list)
AB_Job_List2_free(job_list);
if (job)
AB_Job_free(job);
if (online)
AB_Banking_OnlineFini(api);
#endif
gnc_AB_BANKING_fini(api);
}

View File

@@ -33,11 +33,7 @@
#include <glib/gi18n.h>
#include <aqbanking/banking.h>
#ifdef AQBANKING6
# include <aqbanking/types/transaction.h>
#else
# include <aqbanking/jobgettransactions.h>
#endif
#include "Account.h"
#include "dialog-ab-daterange.h"
#include "gnc-ab-gettrans.h"
@@ -121,14 +117,6 @@ gnc_ab_gettrans(GtkWidget *parent, Account *gnc_acc)
g_warning("gnc_ab_gettrans: Couldn't get AqBanking API");
return;
}
#ifndef AQBANKING6
if (AB_Banking_OnlineInit(api) != 0)
{
g_warning("gnc_ab_gettrans: Couldn't initialize AqBanking API");
goto cleanup;
}
online = TRUE;
#endif
/* Get the AqBanking Account */
ab_acc = gnc_ab_get_ab_account(api, gnc_acc);
if (!ab_acc)
@@ -148,19 +136,13 @@ gnc_ab_gettrans(GtkWidget *parent, Account *gnc_acc)
until = GWEN_Time_toTime_t(to_date);
/* Get a GetTransactions job and enqueue it */
#ifdef AQBANKING6
if (!AB_AccountSpec_GetTransactionLimitsForCommand(ab_acc, AB_Transaction_CommandGetTransactions))
#else
job = AB_JobGetTransactions_new(ab_acc);
if (!job || AB_Job_CheckAvailability(job))
#endif
{
g_warning("gnc_ab_gettrans: JobGetTransactions not available for this "
"account");
gnc_error_dialog (GTK_WINDOW (parent), _("Online action \"Get Transactions\" not available for this account."));
goto cleanup;
}
#ifdef AQBANKING6
job = AB_Transaction_new();
AB_Transaction_SetCommand(job, AB_Transaction_CommandGetTransactions);
AB_Transaction_SetUniqueAccountId(job, AB_AccountSpec_GetUniqueId(ab_acc));
@@ -185,12 +167,6 @@ gnc_ab_gettrans(GtkWidget *parent, Account *gnc_acc)
job_list = AB_Transaction_List2_new();
AB_Transaction_List2_PushBack(job_list, job);
#else
AB_JobGetTransactions_SetFromTime(job, from_date);
AB_JobGetTransactions_SetToTime(job, to_date);
job_list = AB_Job_List2_new();
AB_Job_List2_PushBack(job_list, job);
#endif
/* Get a GUI object */
gui = gnc_GWEN_Gui_get(parent);
if (!gui)
@@ -203,38 +179,22 @@ gnc_ab_gettrans(GtkWidget *parent, Account *gnc_acc)
context = AB_ImExporterContext_new();
/* Execute the job */
#ifdef AQBANKING6
AB_Banking_SendCommands(api, job_list, context);
#else
AB_Banking_ExecuteJobs(api, job_list, context);
#endif
/* 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
*/
#ifdef AQBANKING6
job_status = AB_Transaction_GetStatus(job);
if (job_status != AB_Transaction_StatusAccepted
&& job_status != AB_Transaction_StatusPending)
#else
job_status = AB_Job_GetStatus(job);
if (job_status != AB_Job_StatusFinished
&& job_status != AB_Job_StatusPending)
#endif
{
g_warning("gnc_ab_gettrans: Error on executing job");
#ifdef AQBANKING6
gnc_error_dialog (GTK_WINDOW (parent),
_("Error on executing job.\n\nStatus: %s (%d)"),
AB_Transaction_Status_toString(job_status),
job_status);
#else
gnc_error_dialog (GTK_WINDOW (parent),
_("Error on executing job.\n\nStatus: %s - %s"),
AB_Job_Status2Char(job_status),
AB_Job_GetResultText(job));
#endif
goto cleanup;
}
@@ -267,24 +227,12 @@ cleanup:
if (gui)
gnc_GWEN_Gui_release(gui);
if (job_list)
#ifdef AQBANKING6
AB_Transaction_List2_free(job_list);
#else
AB_Job_List2_free(job_list);
#endif
if (job)
#ifdef AQBANKING6
AB_Transaction_free(job);
#else
AB_Job_free(job);
#endif
if (to_date)
GWEN_Time_free(to_date);
if (from_date)
GWEN_Time_free(from_date);
#ifndef AQBANKING6
if (online)
AB_Banking_OnlineFini(api);
#endif
gnc_AB_BANKING_fini(api);
}

View File

@@ -97,14 +97,6 @@ gnc_ab_maketrans(GtkWidget *parent, Account *gnc_acc,
g_warning("gnc_ab_maketrans: Couldn't get AqBanking API");
return;
}
#ifndef AQBANKING6
if (AB_Banking_OnlineInit(api) != 0)
{
g_warning("gnc_ab_maketrans: Couldn't initialize AqBanking API");
goto cleanup;
}
online = TRUE;
#endif
/* Get the AqBanking Account */
ab_acc = gnc_ab_get_ab_account(api, gnc_acc);
if (!ab_acc)
@@ -114,7 +106,6 @@ gnc_ab_maketrans(GtkWidget *parent, Account *gnc_acc,
goto cleanup;
}
#if (AQBANKING_VERSION_INT >= 60400)
if (trans_type == SEPA_INTERNAL_TRANSFER)
{
/* Generate list of template transactions from the reference accounts*/
@@ -127,7 +118,6 @@ gnc_ab_maketrans(GtkWidget *parent, Account *gnc_acc,
}
}
else
#endif
{
/* Get list of template transactions */
templates = gnc_ab_trans_templ_list_new_from_book(
@@ -158,26 +148,12 @@ gnc_ab_maketrans(GtkWidget *parent, Account *gnc_acc,
GNC_AB_JOB_STATUS job_status;
GncABImExContextImport *ieci = NULL;
#ifndef AQBANKING6
/* Get a GUI object */
gui = gnc_GWEN_Gui_get(parent);
if (!gui)
{
g_warning("gnc_ab_maketrans: Couldn't initialize Gwenhywfar GUI");
aborted = TRUE;
goto repeat;
}
#endif
/* Let the user enter the values */
result = gnc_ab_trans_dialog_run_until_ok(td);
templates = gnc_ab_trans_dialog_get_templ(td, &changed);
#if (AQBANKING_VERSION_INT >= 60400)
if (trans_type != SEPA_INTERNAL_TRANSFER && changed)
#else
if (changed)
#endif
{
/* Save the templates */
save_templates(parent, gnc_acc, templates,
@@ -195,11 +171,7 @@ gnc_ab_maketrans(GtkWidget *parent, Account *gnc_acc,
/* Get a job and enqueue it */
ab_trans = gnc_ab_trans_dialog_get_ab_trans(td);
job = gnc_ab_trans_dialog_get_job(td);
#ifdef AQBANKING6
if (!job || AB_AccountSpec_GetTransactionLimitsForCommand(ab_acc, AB_Transaction_GetCommand(job))==NULL)
#else
if (!job || AB_Job_CheckAvailability(job))
#endif
{
if (!gnc_verify_dialog (
GTK_WINDOW (parent), FALSE, "%s",
@@ -215,13 +187,8 @@ gnc_ab_maketrans(GtkWidget *parent, Account *gnc_acc,
aborted = TRUE;
goto repeat;
}
#ifdef AQBANKING6
job_list = AB_Transaction_List2_new();
AB_Transaction_List2_PushBack(job_list, job);
#else
job_list = AB_Job_List2_new();
AB_Job_List2_PushBack(job_list, job);
#endif
/* Setup a Transfer Dialog for the GnuCash transaction */
xfer_dialog = gnc_xfer_dialog(gnc_ab_trans_dialog_get_parent(td),
gnc_acc);
@@ -305,25 +272,15 @@ gnc_ab_maketrans(GtkWidget *parent, Account *gnc_acc,
}
/* Finally, execute the job */
#ifdef AQBANKING6
AB_Banking_SendCommands(api, job_list, context);
#else
AB_Banking_ExecuteJobs(api, job_list, context);
#endif
/* 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
*/
#ifdef AQBANKING6
job_status = AB_Transaction_GetStatus(job);
if (job_status != AB_Transaction_StatusAccepted
&& job_status != AB_Transaction_StatusPending)
#else
job_status = AB_Job_GetStatus(job);
if (job_status != AB_Job_StatusFinished
&& job_status != AB_Job_StatusPending)
#endif
{
successful = FALSE;
if (!gnc_verify_dialog (
@@ -364,20 +321,12 @@ repeat:
AB_ImExporterContext_free(context);
if (job_list)
{
#ifdef AQBANKING6
AB_Transaction_List2_free(job_list);
#else
AB_Job_List2_free(job_list);
#endif
job_list = NULL;
}
if (job)
{
#ifdef AQBANKING6
AB_Transaction_free(job);
#else
AB_Job_free(job);
#endif
job = NULL;
}
if (gui)
@@ -392,9 +341,5 @@ repeat:
cleanup:
if (td)
gnc_ab_trans_dialog_free(td);
#ifndef AQBANKING6
if (online)
AB_Banking_OnlineFini(api);
#endif
gnc_AB_BANKING_fini(api);
}

View File

@@ -41,7 +41,7 @@
G_BEGIN_DECLS
/**
* FIXME
* Create SEPA transfers.
*
* @param parent Widget to use as parent, may be NULL
* @param gnc_acc GnuCash account to fetch balance for

View File

@@ -34,13 +34,9 @@
#include <glib/gi18n.h>
#include <gwenhywfar/gwenhywfar.h>
#include <aqbanking/banking.h>
#ifdef AQBANKING6
#include <aqbanking/types/balance.h>
#if (AQBANKING_VERSION_INT >= 60400)
#include <aqbanking/types/refaccount.h>
#include <gnc-aqbanking-templates.h>
#endif
#endif
#include "window-reconcile.h"
#include "Transaction.h"
#include "dialog-ab-trans.h"
@@ -54,11 +50,7 @@
#include "import-utilities.h"
#include "qof.h"
#include "engine-helpers.h"
#ifdef AQBANKING6
# include <aqbanking/gui/abgui.h>
#else
# include <aqbanking/abgui.h>
#endif
#include <aqbanking/gui/abgui.h>
/* This static indicates the debugging module that this .o belongs to. */
G_GNUC_UNUSED static QofLogModule log_module = G_LOG_DOMAIN;
@@ -101,7 +93,6 @@ static inline gboolean is_leap_year (int year)
static inline time64
gnc_gwen_date_to_time64 (const GNC_GWEN_DATE* date)
{
#if AQBANKING_VERSION_INT >= 59900
int day = GWEN_Date_GetDay (date);
int month = GWEN_Date_GetMonth (date);
int year = GWEN_Date_GetYear (date);
@@ -114,12 +105,6 @@ gnc_gwen_date_to_time64 (const GNC_GWEN_DATE* date)
while (month == 2 && day <= 30 && day > (is_leap_year (year) ? 29 : 28))
--day;
return gnc_dmy2time64_neutral (day, month, year);
#else
int month, day, year;
GWEN_Time_GetBrokenDownDate (date, &day, &month, &year);
/* GWEN_Time_GetBrokenDownDate returns localtime(3) format; month is [0..11] */
return gnc_dmy2time64_neutral (day, month + 1, year);
#endif
}
void
@@ -192,8 +177,6 @@ gnc_AB_BANKING_new (void)
api = AB_Banking_new ("gnucash", NULL, 0);
g_return_val_if_fail (api, NULL);
#if AQBANKING_VERSION_INT >= 59925 \
|| (AQBANKING_VERSION_INT >= 50709 && AQBANKING_VERSION_INT < 59900)
/* These two values must be set because newest bank regulation requires
the bank servers to require it. The string itself results from our
registration with the German bank association at
@@ -202,30 +185,6 @@ gnc_AB_BANKING_new (void)
introduced in aqbanking-5.99.25 and aqbanking-5.7.9. */
AB_Banking_RuntimeConfig_SetCharValue (api, "fintsRegistrationKey", "412748A1836CDD07181CE1910");
AB_Banking_RuntimeConfig_SetCharValue (api, "fintsApplicationVersionString", PROJECT_VERSION);
#endif
#ifndef AQBANKING6
/* Check for config migration */
if (AB_Banking_HasConf4 (api) != 0)
{
if (AB_Banking_HasConf3 (api) == 0)
{
PINFO("gnc_AB_BANKING_new: importing aqbanking3 configuration\n");
if (AB_Banking_ImportConf3 (api) < 0)
{
PINFO("gnc_AB_BANKING_new: unable to import aqbanking3 configuration\n");
}
}
else if (AB_Banking_HasConf2 (api) == 0)
{
PINFO("gnc_AB_BANKING_new: importing aqbanking2 configuration\n");
if (AB_Banking_ImportConf2 (api) < 0)
{
PINFO("gnc_AB_BANKING_new: unable to import aqbanking2 configuration\n");
}
}
}
#endif
/* Init the API */
g_return_val_if_fail (AB_Banking_Init (api) == 0, NULL);
@@ -298,7 +257,6 @@ gnc_ab_get_ab_account (const AB_BANKING *api, Account *gnc_acc)
if (account_uid > 0)
{
#ifdef AQBANKING6
gint rv;
rv = AB_Banking_GetAccountSpecByUniqueId (api, account_uid, &ab_account);
@@ -314,25 +272,6 @@ gnc_ab_get_ab_account (const AB_BANKING *api, Account *gnc_acc)
return NULL;
}
return ab_account;
#else
ab_account = AB_Banking_GetAccount (api, account_uid);
if (!ab_account && bankcode && *bankcode && accountid && *accountid)
{
PINFO("gnc_ab_get_ab_account: No AB_ACCOUNT found for UID %d, "
"trying bank code\n", account_uid);
ab_account = AB_Banking_GetAccountByCodeAndNumber (api, bankcode,
accountid);
}
return ab_account;
}
else if (bankcode && *bankcode && accountid && *accountid)
{
ab_account = AB_Banking_GetAccountByCodeAndNumber (api, bankcode,
accountid);
return ab_account;
#endif
}
return NULL;
@@ -405,23 +344,14 @@ join_ab_strings_cb (const gchar *str, gpointer user_data)
gchar *
gnc_ab_get_remote_name (const AB_TRANSACTION *ab_trans)
{
#ifdef AQBANKING6
const char* ab_remote_name;
#else
const GWEN_STRINGLIST *ab_remote_name;
#endif
gchar *gnc_other_name = NULL;
g_return_val_if_fail (ab_trans, NULL);
ab_remote_name = AB_Transaction_GetRemoteName (ab_trans);
if (ab_remote_name)
#ifdef AQBANKING6
gnc_other_name = g_strdup(ab_remote_name);
#else
GWEN_StringList_ForEach (ab_remote_name, join_ab_strings_cb,
&gnc_other_name);
#endif
if (!gnc_other_name || !*gnc_other_name)
{
g_free (gnc_other_name);
@@ -434,14 +364,7 @@ gnc_ab_get_remote_name (const AB_TRANSACTION *ab_trans)
gchar *
gnc_ab_get_purpose (const AB_TRANSACTION *ab_trans, gboolean is_ofx)
{
#ifdef AQBANKING6
# if AQBANKING_VERSION_INT < 59929
# error "You are using an old beta version of aqbanking > 5.99.0 but < 5.99.29, please upgrade to the latest 5.99.29 or newer."
# endif
#else
const /* only const in aqbanking < 5.99 */
#endif
GWEN_STRINGLIST *ab_purpose;
GWEN_STRINGLIST *ab_purpose;
const char *ab_transactionText = NULL;
gchar *gnc_description = NULL;
@@ -457,22 +380,12 @@ gnc_ab_get_purpose (const AB_TRANSACTION *ab_trans, gboolean is_ofx)
gnc_description = g_strdup (ab_transactionText);
}
ab_purpose =
#ifdef AQBANKING6
/* With aqbanking-5.99.29, the identical function as before is now available under this new name. */
AB_Transaction_GetPurposeAsStringList
#else
AB_Transaction_GetPurpose
#endif
(ab_trans);
ab_purpose = AB_Transaction_GetPurposeAsStringList (ab_trans);
if (ab_purpose)
GWEN_StringList_ForEach (ab_purpose, join_ab_strings_cb,
&gnc_description);
#ifdef AQBANKING6
/* With aqbanking>=5.99, the return value must now be free'd */
GWEN_StringList_free (ab_purpose);
#endif
return gnc_description;
}
@@ -487,9 +400,6 @@ static gchar *
ab_ultimate_creditor_debtor_to_gnc (const AB_TRANSACTION *ab_trans,
gboolean is_ofx)
{
#if AQBANKING_VERSION_INT < 60200
return NULL;
#else
const gchar* ultimate;
if (is_ofx)
@@ -504,7 +414,6 @@ ab_ultimate_creditor_debtor_to_gnc (const AB_TRANSACTION *ab_trans,
return NULL;
return g_strdup (ultimate);
#endif
}
gchar *
@@ -782,17 +691,10 @@ txn_transaction_cb (const AB_TRANSACTION *element, gpointer user_data)
/* NEW: The imported transaction has been imported into gnucash.
* Now also add it as a job to aqbanking */
#ifdef AQBANKING6
AB_Transaction_SetLocalBankCode (
ab_trans, AB_AccountSpec_GetBankCode (data->ab_acc));
AB_Transaction_SetLocalAccountNumber (
ab_trans, AB_AccountSpec_GetAccountNumber (data->ab_acc));
#else
AB_Transaction_SetLocalBankCode (
ab_trans, AB_Account_GetBankCode (data->ab_acc));
AB_Transaction_SetLocalAccountNumber (
ab_trans, AB_Account_GetAccountNumber (data->ab_acc));
#endif
AB_Transaction_SetLocalCountry (ab_trans, "DE");
@@ -805,9 +707,6 @@ txn_transaction_cb (const AB_TRANSACTION *element, gpointer user_data)
/* trans_type = SINGLE_INTERNAL_TRANSFER;
* break; */
case AB_Transaction_TypeTransfer:
#ifndef AQBANKING6
case AB_Transaction_TypeEuTransfer:
#endif
default:
trans_type = SEPA_TRANSFER;
break;
@@ -816,11 +715,7 @@ txn_transaction_cb (const AB_TRANSACTION *element, gpointer user_data)
job = gnc_ab_get_trans_job (data->ab_acc, ab_trans, trans_type);
/* Check whether we really got a job */
#ifdef AQBANKING6
if (!job || AB_AccountSpec_GetTransactionLimitsForCommand (data->ab_acc, AB_Transaction_GetCommand (job)) == NULL)
#else
if (!job || AB_Job_CheckAvailability (job))
#endif
{
/* Oops, no job, probably not supported by bank */
if (gnc_verify_dialog (
@@ -843,11 +738,7 @@ txn_transaction_cb (const AB_TRANSACTION *element, gpointer user_data)
{
gnc_gen_trans_list_add_trans_with_ref_id (data->generic_importer,
gnc_trans,
#ifdef AQBANKING6
AB_Transaction_GetUniqueId (job));
#else
AB_Job_GetJobId (job));
#endif
/* AB_Job_List2_PushBack(data->job_list, job); -> delayed until trans is successfully imported */
g_datalist_set_data (&data->tmp_job_list, gnc_AB_JOB_to_readable_string (job), job);
}
@@ -872,19 +763,11 @@ static void gnc_ab_trans_processed_cb (GNCImportTransInfo *trans_info,
if (imported)
{
#ifdef AQBANKING6
AB_Transaction_List2_PushBack (data->job_list, job);
#else
AB_Job_List2_PushBack (data->job_list, job);
#endif
}
else
{
#ifdef AQBANKING6
AB_Transaction_free (job);
#else
AB_Job_free (job);
#endif
}
g_datalist_remove_data (&data->tmp_job_list, jobname);
@@ -895,11 +778,7 @@ gnc_AB_JOB_to_readable_string (const GNC_AB_JOB *job)
{
if (job)
{
#ifdef AQBANKING6
return gnc_AB_JOB_ID_to_string (AB_Transaction_GetUniqueId (job));
#else
return gnc_AB_JOB_ID_to_string (AB_Job_GetJobId (job));
#endif
}
else
{
@@ -926,11 +805,7 @@ txn_accountinfo_cb (AB_IMEXPORTER_ACCOUNTINFO *element, gpointer user_data)
/* Ignore them */
return NULL;
#ifdef AQBANKING6
if (!AB_ImExporterAccountInfo_GetFirstTransaction (element, AB_Transaction_TypeStatement, 0))
#else
if (!AB_ImExporterAccountInfo_GetFirstTransaction (element))
#endif
/* No transaction found */
return NULL;
else
@@ -988,7 +863,6 @@ txn_accountinfo_cb (AB_IMEXPORTER_ACCOUNTINFO *element, gpointer user_data)
}
/* Iterate through all transactions */
#ifdef AQBANKING6
{
AB_TRANSACTION_LIST *ab_trans_list = AB_ImExporterAccountInfo_GetTransactionList (element);
if (ab_trans_list)
@@ -996,10 +870,6 @@ txn_accountinfo_cb (AB_IMEXPORTER_ACCOUNTINFO *element, gpointer user_data)
txn_transaction_cb, data,
AB_Transaction_TypeStatement, 0);
}
#else
AB_ImExporterAccountInfo_TransactionsForEach (element, txn_transaction_cb,
data);
#endif
return NULL;
}
@@ -1015,9 +885,6 @@ bal_accountinfo_cb (AB_IMEXPORTER_ACCOUNTINFO *element, gpointer user_data)
time64 booked_tt = 0;
GtkWidget *dialog;
gboolean show_recn_window = FALSE;
#ifndef AQBANKING6
AB_ACCOUNT_STATUS *best = NULL;
#endif
g_return_val_if_fail (element && data, NULL);
@@ -1025,40 +892,15 @@ bal_accountinfo_cb (AB_IMEXPORTER_ACCOUNTINFO *element, gpointer user_data)
/* Ignore them */
return NULL;
#ifdef AQBANKING6
if (!AB_ImExporterAccountInfo_GetFirstBalance (element))
#else
if (!AB_ImExporterAccountInfo_GetFirstAccountStatus (element))
#endif
/* No balance found */
return NULL;
else
data->awaiting |= FOUND_BALANCES;
#ifdef AQBANKING6
/* Lookup the most recent BALANCE available */
booked_bal = AB_Balance_List_GetLatestByType (AB_ImExporterAccountInfo_GetBalanceList (element),
AB_Balance_TypeBooked);
#else
{
AB_ACCOUNT_STATUS *item = NULL;
const GWEN_TIME *best_time = NULL;
/* Lookup the most recent ACCOUNT_STATUS available */
item = AB_ImExporterAccountInfo_GetFirstAccountStatus (element);
while (item)
{
const GWEN_TIME *item_time = AB_AccountStatus_GetTime (item);
if (!best || GWEN_Time_Diff (best_time, item_time) < 0.0)
{
best = item;
best_time = item_time;
}
item = AB_ImExporterAccountInfo_GetNextAccountStatus (element);
}
booked_bal = AB_AccountStatus_GetBookedBalance (best);
}
#endif
if (!(data->awaiting & AWAIT_BALANCES))
{
@@ -1092,11 +934,7 @@ bal_accountinfo_cb (AB_IMEXPORTER_ACCOUNTINFO *element, gpointer user_data)
/* Lookup booked balance and time */
if (booked_bal)
{
#ifdef AQBANKING6
const GWEN_DATE *ti = AB_Balance_GetDate (booked_bal);
#else
const GNC_GWEN_DATE *ti = AB_Balance_GetTime (booked_bal);
#endif
if (ti)
{
booked_tt = gnc_gwen_date_to_time64 (ti);
@@ -1126,12 +964,8 @@ bal_accountinfo_cb (AB_IMEXPORTER_ACCOUNTINFO *element, gpointer user_data)
}
/* Lookup noted balance */
#ifdef AQBANKING6
noted_bal = AB_Balance_List_GetLatestByType (AB_ImExporterAccountInfo_GetBalanceList (element),
AB_Balance_TypeNoted);
#else
noted_bal = AB_AccountStatus_GetNotedBalance (best);
#endif
if (noted_bal)
{
noted_val = AB_Balance_GetValue (noted_bal);
@@ -1235,9 +1069,7 @@ gnc_ab_import_context (AB_IMEXPORTER_CONTEXT *context,
AB_BANKING *api, GtkWidget *parent)
{
GncABImExContextImport *data = g_new (GncABImExContextImport, 1);
#ifdef AQBANKING6
AB_IMEXPORTER_ACCOUNTINFO_LIST *ab_ail;
#endif
g_return_val_if_fail (context, NULL);
/* Do not await and ignore at the same time */
g_return_val_if_fail (!(awaiting & AWAIT_BALANCES)
@@ -1256,18 +1088,13 @@ gnc_ab_import_context (AB_IMEXPORTER_CONTEXT *context,
data->execute_txns = execute_txns;
data->api = api;
data->parent = parent;
#ifdef AQBANKING6
data->job_list = AB_Transaction_List2_new ();
#else
data->job_list = AB_Job_List2_new ();
#endif
data->tmp_job_list = NULL;
data->generic_importer = NULL;
g_datalist_init (&data->tmp_job_list);
/* Import transactions */
#ifdef AQBANKING6
ab_ail = AB_ImExporterContext_GetAccountInfoList (context);
if (ab_ail && AB_ImExporterAccountInfo_List_GetCount (ab_ail))
{
@@ -1286,22 +1113,6 @@ gnc_ab_import_context (AB_IMEXPORTER_CONTEXT *context,
bal_accountinfo_cb,
data);
}
#else
if (!(awaiting & IGNORE_TRANSACTIONS))
AB_ImExporterContext_AccountInfoForEach (context,
txn_accountinfo_cb,
data);
/* populate and display the matching window */
if (data->generic_importer)
gnc_gen_trans_list_show_all (data->generic_importer);
/* Check balances */
if (!(awaiting & IGNORE_BALANCES))
AB_ImExporterContext_AccountInfoForEach (context,
bal_accountinfo_cb,
data);
#endif
/* Check bank-messages */
{
@@ -1316,11 +1127,7 @@ gnc_ab_import_context (AB_IMEXPORTER_CONTEXT *context,
subject,
text);
#ifdef AQBANKING6
bankmsg = AB_Message_List_Next (bankmsg);
#else
bankmsg = AB_ImExporterContext_GetNextMessage (context); // The iterator is incremented within aqbanking
#endif
}
}
@@ -1365,7 +1172,6 @@ gnc_ab_get_permanent_certs (void)
return perm_certs;
}
#if (AQBANKING_VERSION_INT >= 60400)
GList*
gnc_ab_trans_templ_list_new_from_ref_accounts (GNC_AB_ACCOUNT_SPEC *ab_acc)
{
@@ -1406,4 +1212,55 @@ gnc_ab_trans_templ_list_new_from_ref_accounts (GNC_AB_ACCOUNT_SPEC *ab_acc)
return retval;
}
#endif
static int
ab_node_pair_compare (AB_Node_Pair* left, AB_Node_Pair* right)
{
return left ? (right ? g_strcmp0 (left->name, right->name) : -1) :
(right ? 1 : 0);
}
GList*
gnc_ab_imexporter_list (AB_BANKING* api)
{
GList* desc_list = NULL;
GWEN_PLUGIN_DESCRIPTION_LIST2 *il =
AB_Banking_GetImExporterDescrs (api);
GWEN_PLUGIN_DESCRIPTION_LIST2_ITERATOR *ilit;
g_return_val_if_fail (il, NULL);
ilit = GWEN_PluginDescription_List2_First(il);
for (GWEN_PLUGIN_DESCRIPTION *pd =
GWEN_PluginDescription_List2Iterator_Data(ilit);
pd;
pd = GWEN_PluginDescription_List2Iterator_Next(ilit))
{
AB_Node_Pair *node = NULL;
GWEN_BUFFER *tbuf = GWEN_Buffer_new(0, 256, 0, 1);
node = g_slice_new (AB_Node_Pair);
node->name = g_strdup(GWEN_PluginDescription_GetName(pd));
node->descr = g_strdup(GWEN_PluginDescription_GetShortDescr(pd));
desc_list = g_list_prepend (desc_list, node);
}
GWEN_PluginDescription_List2_free(il);
return g_list_sort (desc_list, (GCompareFunc)ab_node_pair_compare);
}
GList*
gnc_ab_imexporter_profile_list (AB_BANKING* api, const char* importer_name)
{
GList* prof_list = NULL;
GWEN_DB_NODE* db = AB_Banking_GetImExporterProfiles(api, importer_name);
g_return_val_if_fail (db, NULL);
for (GWEN_DB_NODE *profile = GWEN_DB_GetFirstGroup(db); profile;
profile = GWEN_DB_GetNextGroup(profile))
{
AB_Node_Pair *node = g_slice_new(AB_Node_Pair);
if (!profile) continue;
node->name = g_strdup(GWEN_DB_GetCharValue(profile, "name", 0, NULL));
node->descr = g_strdup(GWEN_DB_GetCharValue(profile, "shortDescr", 0, NULL));
prof_list = g_list_prepend (prof_list, node);
}
return g_list_sort (prof_list, (GCompareFunc)ab_node_pair_compare);
}

View File

@@ -52,8 +52,6 @@ G_BEGIN_DECLS
* in the interval [0..99]. */
#define GWENHYWFAR_VERSION_INT (10000 * GWENHYWFAR_VERSION_MAJOR + 100 * GWENHYWFAR_VERSION_MINOR + GWENHYWFAR_VERSION_PATCHLEVEL)
#if AQBANKING_VERSION_INT >= 59900
# define AQBANKING6 1
# define GNC_AB_ACCOUNT_SPEC AB_ACCOUNT_SPEC
# define GNC_AB_ACCOUNT_SPEC_LIST AB_ACCOUNT_SPEC_LIST
# define GNC_AB_JOB AB_TRANSACTION
@@ -61,18 +59,6 @@ G_BEGIN_DECLS
# define GNC_AB_JOB_LIST2_ITERATOR AB_TRANSACTION_LIST2_ITERATOR
# define GNC_AB_JOB_STATUS AB_TRANSACTION_STATUS
# define GNC_GWEN_DATE GWEN_DATE
#else
# define GNC_AB_ACCOUNT_SPEC AB_ACCOUNT
# define GNC_AB_ACCOUNT_SPEC_LIST AB_ACCOUNT_LIST2
# define GNC_AB_JOB AB_JOB
# define GNC_AB_JOB_LIST2 AB_JOB_LIST2
# define GNC_AB_JOB_LIST2_ITERATOR AB_JOB_LIST2_ITERATOR
# define GNC_AB_JOB_STATUS AB_JOB_STATUS
# define GNC_GWEN_DATE GWEN_TIME
#endif
#if GWENHYWFAR_VERSION_INT >= 49900
# define GWENHYWFAR5
#endif
#define GNC_PREFS_GROUP_AQBANKING "dialogs.import.hbci"
#define GNC_PREF_FORMAT_SWIFT940 "format-swift-mt940"
@@ -81,6 +67,12 @@ G_BEGIN_DECLS
#define GNC_PREF_USE_TRANSACTION_TXT "use-ns-transaction-text"
#define GNC_PREF_VERBOSE_DEBUG "verbose-debug"
typedef struct
{
char* name;
char* descr;
} AB_Node_Pair;
typedef struct _GncABImExContextImport GncABImExContextImport;
#define AWAIT_BALANCES 1 << 1
@@ -290,7 +282,6 @@ GWEN_DB_NODE *gnc_ab_get_permanent_certs (void);
gchar* gnc_ab_create_online_id (const gchar *bankcode, const gchar *accountnumber);
#if (AQBANKING_VERSION_INT >= 60400)
/**
* Obtain the list of templates based on the aqbanking account spec's target accounts.
*
@@ -299,7 +290,22 @@ gchar* gnc_ab_create_online_id (const gchar *bankcode, const gchar *accountnumbe
*/
GList*
gnc_ab_trans_templ_list_new_from_ref_accounts (GNC_AB_ACCOUNT_SPEC *ab_acc);
#endif
/**
* Retrieve the available AQBanking importers.
* @param abi The AQBanking instance.
* @return a GList<AB_Node_Pair> containing importer names and descriptions.
*/
GList* gnc_ab_imexporter_list (AB_BANKING* abi);
/**
* Retrieve the available format templates for an AQBanking importer.
* @param api the AQBanking instance.
* @param importer_name The importer's name.
* @return a GList<AB_Node_Pair> containing format template names and descriptions.
*/
GList* gnc_ab_imexporter_profile_list (AB_BANKING* abi,
const char* importer_name);
G_END_DECLS

View File

@@ -22,12 +22,13 @@
/**
* @internal
* @file gnc-file-aqb-import.c
* @brief DTAUS import module code
* @brief File import module code
* @author Copyright (C) 2002 Benoit Grégoire <bock@step.polymtl.ca>
* @author Copyright (C) 2003 Jan-Pascal van Best <janpascal@vanbest.org>
* @author Copyright (C) 2006 Florian Steinel
* @author Copyright (C) 2006 Christian Stimming
* @author Copyright (C) 2008 Andreas Koehler <andi5.py@gmx.net>
* @author Copyright (C) 2022 John Ralls <jralls@ceridwen.us>
*/
#include <config.h>
@@ -44,10 +45,12 @@
#include "gnc-ab-utils.h"
# include <gwenhywfar/syncio_file.h>
# include <gwenhywfar/syncio_buffered.h>
#include <gwenhywfar/syncio_file.h>
#include <gwenhywfar/syncio_buffered.h>
#include <gwenhywfar/gui.h>
typedef GWEN_SYNCIO GWEN_IO_LAYER;
#include "dialog-ab-select-imexporter.h"
#include "dialog-ab-trans.h"
#include "dialog-utils.h"
#include "gnc-file.h"
@@ -61,45 +64,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;
#ifndef AQBANKING6
AB_IMEXPORTER *importer;
#endif
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 */
@@ -107,286 +87,63 @@ gnc_file_aqbanking_import(GtkWindow *parent,
gnc_set_default_directory(GNC_PREFS_GROUP_AQBANKING, default_dir);
g_free(default_dir);
#ifndef AQBANKING6
dtaus_fd = g_open(selected_filename, O_RDONLY, 0);
if (dtaus_fd == -1)
{
DEBUG("Could not open file %s", selected_filename);
goto cleanup;
}
#endif
/* Get the API */
api = gnc_AB_BANKING_new();
if (!api)
{
g_warning("gnc_file_aqbanking_import: Couldn't get AqBanking API");
goto cleanup;
}
#ifndef AQBANKING6
if (AB_Banking_OnlineInit(api) != 0)
{
g_warning("gnc_file_aqbanking_import: "
"Couldn't initialize AqBanking API");
goto cleanup;
}
online = TRUE;
/* Get import module */
importer = AB_Banking_GetImExporter(api, aqbanking_importername);
if (!importer)
{
g_warning("Import module %s not found", aqbanking_importername);
gnc_error_dialog(parent, "%s",
_("Import module for DTAUS import not found."));
goto cleanup;
}
/* Load the import profile */
db_profiles = AB_Banking_GetImExporterProfiles(api, aqbanking_importername);
/* Select profile */
db_profile = GWEN_DB_GetFirstGroup(db_profiles);
while (db_profile)
{
const gchar *name;
name = GWEN_DB_GetCharValue(db_profile, "name", 0, 0);
g_return_if_fail(name);
if (g_ascii_strcasecmp(name, aqbanking_profilename) == 0)
break;
db_profile = GWEN_DB_GetNextGroup(db_profile);
}
if (!db_profile)
{
g_warning("Profile \"%s\" for importer \"%s\" not found",
aqbanking_profilename, aqbanking_importername);
/* For debugging: Print those available names that have been found */
db_profile = GWEN_DB_GetFirstGroup(db_profiles);
while (db_profile)
{
const char *name = GWEN_DB_GetCharValue(db_profile, "name", 0, 0);
g_warning("Only found profile \"%s\"\n", name ? name : "(null)");
db_profile = GWEN_DB_GetNextGroup(db_profile);
}
goto cleanup;
}
#endif
/* Create a context to store the results */
/* Create a context to store the results */
context = AB_ImExporterContext_new();
#ifdef AQBANKING6
if (AB_Banking_ImportFromFileLoadProfile(api, aqbanking_importername,
success =
AB_Banking_ImportFromFileLoadProfile(api, aqbanking_importername,
context, aqbanking_profilename,
NULL, selected_filename) < 0)
NULL, selected_filename);
g_free (selected_filename);
if (success < 0)
{
g_warning("gnc_file_aqbanking_import: Error on import");
goto cleanup;
}
#else
/* Wrap file in buffered gwen io */
close(dtaus_fd);
io = GWEN_SyncIo_File_new(selected_filename, GWEN_SyncIo_File_CreationMode_OpenExisting);
g_assert(io);
GWEN_SyncIo_AddFlags(io, GWEN_SYNCIO_FILE_FLAGS_READ);
{
/* We must explicitly call "Connect" on the GWEN_SYNCIO
* object. */
int rv = GWEN_SyncIo_Connect(io);
if (rv < 0)
{
g_warning("gnc_file_aqbanking_import: Failed to open file %s: %d", selected_filename, rv);
goto cleanup;
}
g_assert(GWEN_SyncIo_GetStatus(io) == GWEN_SyncIo_Status_Connected);
}
dtaus_fd = -1;
/* Run the import */
if (AB_ImExporter_Import(importer, context, io, db_profile))
{
g_warning("gnc_file_aqbanking_import: Error on import");
goto cleanup;
}
/* Close the file */
GWEN_SyncIo_free(io);
io = NULL;
#endif
/* Before importing the results, if this is a new book, let user specify
* book options, since they affect how transactions are created */
if (gnc_is_new_book())
gnc_new_book_option_display (GTK_WIDGET (parent));
/* Import the results */
ieci = gnc_ab_import_context(context, AWAIT_TRANSACTIONS,
execute_transactions,
execute_transactions ? api : NULL,
GTK_WIDGET(parent));
if (execute_transactions)
{
if (gnc_ab_ieci_run_matcher(ieci))
{
AB_IMEXPORTER_CONTEXT *execution_context;
/* 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 */
#ifdef AQBANKING6
AB_Banking_SendCommands(api, job_list, execution_context);
#else
AB_Banking_ExecuteJobs(api, job_list, execution_context);
#endif
/* 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. */
#ifdef AQBANKING6
jit = AB_Transaction_List2_First(job_list);
#else
jit = AB_Job_List2_First(job_list);
#endif
if (jit)
{
#ifdef AQBANKING6
job = AB_Transaction_List2Iterator_Data(jit);
#else
job = AB_Job_List2Iterator_Data(jit);
#endif
while (job)
{
num_jobs += 1;
#ifdef AQBANKING6
job_status = AB_Transaction_GetStatus(job);
if (job_status != AB_Transaction_StatusAccepted &&
job_status != AB_Transaction_StatusPending)
#else
job_status = AB_Job_GetStatus(job);
if (job_status != AB_Job_StatusFinished &&
job_status != AB_Job_StatusPending)
#endif
{
successful = FALSE;
num_jobs_failed += 1;
if (num_jobs_failed <= max_failures)
{
#ifdef AQBANKING6
gchar *fmt_str =_("Job %d status %d - %s\n");
#else
gchar *fmt_str =_("Job %d status %d - %s: %s\n");
#endif
if (num_jobs_failed == 1)
{
errstr = g_string_new("Failed jobs:\n");
}
g_string_append_printf(errstr, fmt_str, num_jobs,
job_status,
#ifdef AQBANKING6
AB_Transaction_Status_toString(job_status));
#else
AB_Job_Status2Char(job_status),
AB_Job_GetResultText(job));
#endif
}
else
{
if (num_jobs_failed == (max_failures + 1) )
{
/* indicate that additional failures exist */
g_string_append(errstr, _("...\n"));
}
}
}
#ifdef AQBANKING6
job = AB_Transaction_List2Iterator_Next(jit);
#else
job = AB_Job_List2Iterator_Next(jit);
#endif
} /* while */
#ifdef AQBANKING6
AB_Transaction_List2Iterator_free(jit);
#else
AB_Job_List2Iterator_free(jit);
#endif
}
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)
#ifdef AQBANKING6
AB_Transaction_List2_freeAll(job_list);
#else
AB_Job_List2_FreeAll(job_list);
if (io)
GWEN_SyncIo_free(io);
if (db_profiles)
GWEN_DB_Group_free(db_profiles);
if (online)
AB_Banking_OnlineFini(api);
if (dtaus_fd != -1)
close(dtaus_fd);
#endif
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_warning("gnc_file_aqbanking_import: Error on import");
return NULL;
}
return context;
}
void
gnc_file_aqbanking_import_dialog (GtkWindow *parent)
{
AB_BANKING* api = gnc_AB_BANKING_new ();
GncABSelectImExDlg* imexd =
gnc_ab_select_imex_dlg_new (GTK_WIDGET (parent), api);
char *imexporter, *profile;
AB_IMEXPORTER_CONTEXT* ctx = NULL;
if (!imexd)
{
PERR ("Failed to create select imex dialog.");
gnc_AB_BANKING_fini(api);
return;
}
if (!gnc_ab_select_imex_dlg_run (imexd))
{
gnc_ab_select_imex_dlg_destroy (imexd);
return;
}
imexporter = gnc_ab_select_imex_dlg_get_imexporter_name (imexd);
profile = gnc_ab_select_imex_dlg_get_profile_name (imexd);
if (imexporter && profile)
{
ctx = named_import_get_context (parent, api, imexporter, profile);
gnc_ab_select_imex_dlg_destroy (imexd);
if (ctx)
{
GncABImExContextImport* ieci = NULL;
ieci = gnc_ab_import_context (ctx, 0, FALSE, api, GTK_WIDGET(parent));
g_free(ieci);
AB_ImExporterContext_free(ctx);
}
g_free (imexporter);
g_free (profile);
}
gnc_AB_BANKING_fini(api);
}

View File

@@ -25,9 +25,8 @@
* @addtogroup AqBanking
* @{
* @file aqbanking/gnc-file-aqb-import.h
* @brief DTAUS import module interface
* @author Copyright (C) 2002 Benoit Grégoire <bock@step.polymtl.ca>
* @author Copyright (C) 2008 Andreas Koehler <andi5.py@gmx.net>
* @brief File import module interface
* @author Copyright (C) 2022 John Ralls <jralls@ceridwen.us>
*/
#ifndef GNC_FILE_AQB_IMPORT_H
@@ -38,29 +37,12 @@
G_BEGIN_DECLS
/**
* This routine will pop up a standard file selection dialog asking the user to
* pick a file to import. This file will be opened and 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 should be
* used. Possible values: "dtaus", "csv", "swift", or more.
*
* @param aqbanking_formatname In aqbanking, each importer has one or more data
* formats available which define the actual data fields that should be used.
* In aqbanking, such a different format is called a "profile". Possible values
* for swift: "swift-mt940" or "swift-mt942", but for all others: "default", or
* more precisely: Look into $datadir/aqbanking/imexporters and look into the
* "name" field of the foo.conf files.
*
* @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.
* Import files via AQBanking's Import Dialog. This permits importing
* any file format that Aqbanking supports.
* @param parent A GtkWindow for setting the import dialog transient for.
*/
void gnc_file_aqbanking_import (GtkWindow *parent,
const gchar *aqbanking_importername,
const gchar *aqbanking_formatname,
gboolean exec_as_aqbanking_jobs);
void gnc_file_aqbanking_import_dialog (GtkWindow *parent);
G_END_DECLS

View File

@@ -110,16 +110,10 @@ static gboolean keep_alive(GncGWENGui *gui);
static void cm_close_handler(gpointer user_data);
static void erase_password(gchar *password);
static gchar *strip_html(gchar *text);
#ifndef AQBANKING6
static void get_input(GncGWENGui *gui, guint32 flags, const gchar *title,
const gchar *text, gchar **input, gint min_len,
gint max_len);
#else
static void get_input(GncGWENGui *gui, guint32 flags, const gchar *title,
const gchar *text, const char *mimeType,
const char *pChallenge, uint32_t lChallenge,
gchar **input, gint min_len, gint max_len);
#endif
static gint GNC_GWENHYWFAR_CB messagebox_cb(GWEN_GUI *gwen_gui, guint32 flags, const gchar *title,
const gchar *text, const gchar *b1, const gchar *b2,
const gchar *b3, guint32 guiid);
@@ -137,14 +131,6 @@ static gint GNC_GWENHYWFAR_CB progress_advance_cb(GWEN_GUI *gwen_gui, uint32_t i
static gint GNC_GWENHYWFAR_CB progress_log_cb(GWEN_GUI *gwen_gui, guint32 id,
GWEN_LOGGER_LEVEL level, const gchar *text);
static gint GNC_GWENHYWFAR_CB progress_end_cb(GWEN_GUI *gwen_gui, guint32 id);
#ifndef AQBANKING6
static gint GNC_GWENHYWFAR_CB getpassword_cb(GWEN_GUI *gwen_gui, guint32 flags,
const gchar *token,
const gchar *title,
const gchar *text, gchar *buffer,
gint min_len, gint max_len,
guint32 guiid);
#else
static gint GNC_GWENHYWFAR_CB getpassword_cb(GWEN_GUI *gwen_gui, guint32 flags,
const gchar *token,
const gchar *title,
@@ -153,7 +139,6 @@ static gint GNC_GWENHYWFAR_CB getpassword_cb(GWEN_GUI *gwen_gui, guint32 flags,
GWEN_GUI_PASSWORD_METHOD methodId,
GWEN_DB_NODE *methodParams,
guint32 guiid);
#endif
static gint GNC_GWENHYWFAR_CB setpasswordstatus_cb(GWEN_GUI *gwen_gui, const gchar *token,
const gchar *pin,
GWEN_GUI_PASSWORD_STATUS status, guint32 guiid);
@@ -912,15 +897,10 @@ strip_html(gchar *text)
}
static void
#ifndef AQBANKING6
get_input(GncGWENGui *gui, guint32 flags, const gchar *title, const gchar *text,
gchar **input, gint min_len, gint max_len)
#else
get_input(GncGWENGui *gui, guint32 flags, const gchar *title,
const gchar *text, const char *mimeType,
const char *pChallenge, uint32_t lChallenge,
gchar **input, gint min_len, gint max_len)
#endif
{
GtkBuilder *builder;
GtkWidget *dialog;
@@ -968,7 +948,6 @@ get_input(GncGWENGui *gui, guint32 flags, const gchar *title,
gtk_widget_set_visible(GTK_WIDGET(flickergui->spin_barwidth), FALSE);
gtk_widget_set_visible(GTK_WIDGET(flickergui->spin_delay), FALSE);
#ifdef AQBANKING6
if (g_strcmp0(mimeType,"text/x-flickercode") == 0 && pChallenge != NULL)
{
/* Chiptan Optic (aka Flicker) */
@@ -983,7 +962,6 @@ get_input(GncGWENGui *gui, guint32 flags, const gchar *title,
/* Phototan or Chiptan QR */
gtk_widget_set_visible(GTK_WIDGET(optical_challenge), TRUE);
}
#endif
if (is_tan)
{
gtk_widget_hide(remember_pin_checkbutton);
@@ -1022,7 +1000,6 @@ get_input(GncGWENGui *gui, guint32 flags, const gchar *title,
g_free(raw_text);
}
#ifdef AQBANKING6
/* Optical challenge. Flickercode sets the mimetype to
* x-flickercode and doesn't set the challenge length */
if (g_strcmp0(mimeType,"text/x-flickercode") == 0 && pChallenge != NULL)
@@ -1062,7 +1039,6 @@ get_input(GncGWENGui *gui, guint32 flags, const gchar *title,
gtk_image_set_from_pixbuf(optical_challenge, pixbuf);
}
#endif
if (*input)
{
@@ -1199,11 +1175,7 @@ inputbox_cb(GWEN_GUI *gwen_gui, guint32 flags, const gchar *title,
ENTER("gui=%p, flags=%d", gui, flags);
#ifndef AQBANKING6
get_input(gui, flags, title, text, &input, min_len, max_len);
#else
get_input(gui, flags, title, text, NULL, NULL, 0, &input, min_len, max_len);
#endif
if (input)
{
@@ -1439,31 +1411,22 @@ progress_end_cb(GWEN_GUI *gwen_gui, guint32 id)
}
static gint GNC_GWENHYWFAR_CB
#ifndef AQBANKING6
getpassword_cb(GWEN_GUI *gwen_gui, guint32 flags, const gchar *token,
const gchar *title, const gchar *text, gchar *buffer,
gint min_len, gint max_len, guint32 guiid)
#else
getpassword_cb(GWEN_GUI *gwen_gui, guint32 flags, const gchar *token,
const gchar *title, const gchar *text, gchar *buffer,
gint min_len, gint max_len, GWEN_GUI_PASSWORD_METHOD methodId,
GWEN_DB_NODE *methodParams, guint32 guiid)
#endif
{
GncGWENGui *gui = GETDATA_GUI(gwen_gui);
gchar *password = NULL;
gboolean is_tan = (flags & GWEN_GUI_INPUT_FLAGS_TAN) != 0;
#ifdef AQBANKING6
int opticalMethodId;
const char *mimeType = NULL;
const char *pChallenge = NULL;
uint32_t lChallenge = 0;
#endif
g_return_val_if_fail(gui, -1);
#ifdef AQBANKING6
// cf. https://www.aquamaniac.de/rdm/projects/aqbanking/wiki/ImplementTanMethods
if(is_tan && methodId == GWEN_Gui_PasswordMethod_OpticalHHD)
{
@@ -1507,7 +1470,6 @@ getpassword_cb(GWEN_GUI *gwen_gui, guint32 flags, const gchar *token,
break;
}
}
#endif
ENTER("gui=%p, flags=%d, token=%s", gui, flags, token ? token : "(null");
@@ -1536,11 +1498,7 @@ getpassword_cb(GWEN_GUI *gwen_gui, guint32 flags, const gchar *token,
}
}
#ifndef AQBANKING6
get_input(gui, flags, title, text, &password, min_len, max_len);
#else
get_input(gui, flags, title, text, mimeType, pChallenge, lChallenge, &password, min_len, max_len);
#endif
if (password)
{

View File

@@ -3,14 +3,7 @@
<menu name="File" action="FileAction">
<menu name="FileImport" action="FileImportAction">
<placeholder name="FileImportPlaceholder">
<menuitem name="FileMt940Import" action="Mt940ImportAction"/>
<menuitem name="FileMt942Import" action="Mt942ImportAction"/>
<menuitem name="FileDtausImport" action="DtausImportAction"/>
<menuitem name="FileDtausImportsend" action="DtausImportSendAction"/>
<!-- When CsvImport works:
<menuitem name="FileCsvImport" action="CsvImportAction"/>
<menuitem name="FileCsvImportsend" action="CsvImportSendAction"/>
-->
<menuitem name="FileAQBImport" action="AQBankingImportAction"/>
</placeholder>
</menu>
</menu>

View File

@@ -75,10 +75,7 @@ static void gnc_plugin_ab_cmd_issue_sepainternaltransaction(GtkAction *action, G
static void gnc_plugin_ab_cmd_issue_inttransaction(GtkAction *action, GncMainWindowActionData *data);
static void gnc_plugin_ab_cmd_issue_sepa_direct_debit(GtkAction *action, GncMainWindowActionData *data);
static void gnc_plugin_ab_cmd_view_logwindow(GtkToggleAction *action, GncMainWindow *window);
static void gnc_plugin_ab_cmd_mt940_import(GtkAction *action, GncMainWindowActionData *data);
static void gnc_plugin_ab_cmd_mt942_import(GtkAction *action, GncMainWindowActionData *data);
static void gnc_plugin_ab_cmd_dtaus_import(GtkAction *action, GncMainWindowActionData *data);
static void gnc_plugin_ab_cmd_dtaus_importsend(GtkAction *action, GncMainWindowActionData *data);
static void gnc_plugin_ab_cmd_aqb_import(GtkAction *action, GncMainWindowActionData *data);
#define PLUGIN_ACTIONS_NAME "gnc-plugin-aqbanking-actions"
#define PLUGIN_UI_FILENAME "gnc-plugin-aqbanking-ui.xml"
@@ -133,38 +130,9 @@ static GtkActionEntry gnc_plugin_actions [] =
/* File -> Import menu item */
{
"Mt940ImportAction", "go-previous",
/* Translators: Message types MTxxxx are exchange formats used by the SWIFT network
https://en.wikipedia.org/wiki/Society_for_Worldwide_Interbank_Financial_Telecommunication */
N_("Import _MT940"), NULL,
N_("Import an end-of-day account statement in SWIFT MT940 format into GnuCash."),
G_CALLBACK(gnc_plugin_ab_cmd_mt940_import)
},
{
"Mt942ImportAction", "go-previous", N_("Import MT94_2"), NULL,
N_("Import an interim account statement in SWIFT MT942 format into GnuCash."),
G_CALLBACK(gnc_plugin_ab_cmd_mt942_import)
},
{
"DtausImportAction", "go-previous",
/* Translators: DTAUS is a traditional german exchange format.
https://de.wikipedia.org/wiki/Datentr%C3%A4geraustauschverfahren */
N_("Import _DTAUS"), NULL,
N_("Import a traditional german DTAUS file into GnuCash."),
G_CALLBACK(gnc_plugin_ab_cmd_dtaus_import)
},
/* #ifdef CSV_IMPORT_FUNCTIONAL */
/* { "CsvImportAction", "go-previous", N_("Import _CSV"), NULL, */
/* N_("Import a CSV file into GnuCash"), */
/* G_CALLBACK(gnc_plugin_ab_cmd_csv_import) }, */
/* { "CsvImportSendAction", "go-previous", N_("Import CSV and s_end..."), NULL, */
/* N_("Import a CSV file into GnuCash and send the transfers online through Online Banking"), */
/* G_CALLBACK(gnc_plugin_ab_cmd_csv_importsend) }, */
/* #endif */
{
"DtausImportSendAction", "go-previous", N_("Import DTAUS and _send..."), NULL,
N_("Import a DTAUS file into GnuCash and transmit its orders by Online Banking."),
G_CALLBACK(gnc_plugin_ab_cmd_dtaus_importsend)
"AQBankingImportAction", "go-previous", N_("Import using AQBanking"),
NULL, N_("Import into GnuCash any file format supported by AQBanking."),
G_CALLBACK(gnc_plugin_ab_cmd_aqb_import)
},
};
static guint gnc_plugin_n_actions = G_N_ELEMENTS(gnc_plugin_actions);
@@ -659,50 +627,13 @@ gnc_plugin_ab_cmd_view_logwindow(GtkToggleAction *action, GncMainWindow *window)
}
}
static void
gnc_plugin_ab_cmd_mt940_import(GtkAction *action, GncMainWindowActionData *data)
gnc_plugin_ab_cmd_aqb_import(GtkAction *action,
GncMainWindowActionData *data)
{
gchar *format = gnc_prefs_get_string(GNC_PREFS_GROUP_AQBANKING,
GNC_PREF_FORMAT_SWIFT940);
gnc_main_window = data->window;
gnc_file_aqbanking_import (GTK_WINDOW (gnc_main_window),
"swift", format && *format ? format : "swift-mt940", FALSE);
g_free(format);
}
gnc_file_aqbanking_import_dialog (GTK_WINDOW (gnc_main_window));
static void
gnc_plugin_ab_cmd_mt942_import(GtkAction *action, GncMainWindowActionData *data)
{
gchar *format = gnc_prefs_get_string(GNC_PREFS_GROUP_AQBANKING,
GNC_PREF_FORMAT_SWIFT942);
gnc_main_window = data->window;
gnc_file_aqbanking_import (GTK_WINDOW (gnc_main_window),
"swift", format && *format? format : "swift-mt942", FALSE);
g_free(format);
}
static void
gnc_plugin_ab_cmd_dtaus_import(GtkAction *action, GncMainWindowActionData *data)
{
gchar *format = gnc_prefs_get_string(GNC_PREFS_GROUP_AQBANKING,
GNC_PREF_FORMAT_DTAUS);
gnc_main_window = data->window;
gnc_file_aqbanking_import (GTK_WINDOW (gnc_main_window),
"dtaus", format && *format ? format : "default", FALSE);
g_free(format);
}
static void
gnc_plugin_ab_cmd_dtaus_importsend(GtkAction *action,
GncMainWindowActionData *data)
{
gchar *format = gnc_prefs_get_string(GNC_PREFS_GROUP_AQBANKING,
GNC_PREF_FORMAT_DTAUS);
gnc_main_window = data->window;
gnc_file_aqbanking_import (GTK_WINDOW (gnc_main_window),
"dtaus", format && *format ? format : "default", TRUE);
g_free(format);
}
/************************************************************

View File

@@ -303,6 +303,7 @@ gnucash/import-export/aqb/assistant-ab-initial.glade
gnucash/import-export/aqb/dialog-ab-daterange.c
gnucash/import-export/aqb/dialog-ab.glade
gnucash/import-export/aqb/dialog-ab-pref.glade
gnucash/import-export/aqb/dialog-ab-select-imexporter.c
gnucash/import-export/aqb/dialog-ab-trans.c
gnucash/import-export/aqb/gnc-ab-getbalance.c
gnucash/import-export/aqb/gnc-ab-gettrans.c

View File

@@ -22,7 +22,7 @@ ninja
pkg-config
python3
python3-config
python3.8
python3.8-config
python3.10
python3.10-config
swig
xgettext

View File

@@ -24,8 +24,7 @@ lzma
lzma.h
pango-1.0
pixman-1
pygobject-3.0
python3.8
python3.10
unicase.h
unicode
uniconv.h

View File

@@ -5,6 +5,7 @@ libaqbanking.44.dylib
libaqbanking.dylib
libatk-1.0.0.dylib
libatk-1.0.dylib
libboost_atomic.dylib
libboost_chrono.dylib
libboost_date_time.dylib
libboost_filesystem.dylib
@@ -23,11 +24,9 @@ libchipcard.6.dylib
libchipcard.dylib
libcord.1.dylib
libcord.dylib
libcroco-0.6.3.dylib
libcroco-0.6.dylib
libcrypto.1.1.dylib
libcrypto.dylib
libdbi.1.dylib
libdbi.3.dylib
libdbi.dylib
libecpg.6.12.dylib
libecpg.6.dylib
@@ -35,21 +34,17 @@ libecpg.dylib
libecpg_compat.3.12.dylib
libecpg_compat.3.dylib
libecpg_compat.dylib
libenchant.1.dylib
libenchant.dylib
libenchant-2.2.dylib
libenchant-2.dylib
libepoxy.0.dylib
libepoxy.dylib
libexslt.0.dylib
libexslt.dylib
libffi.7.dylib
libffi.dylib
libfl.2.dylib
libfl.dylib
libfl_pic.2.dylib
libfl_pic.dylib
libfontconfig.1.dylib
libfontconfig.dylib
libfreetype.6.17.2.dylib
libfreetype.6.18.1.dylib
libfreetype.6.dylib
libfreetype.dylib
libfribidi.0.dylib
@@ -64,11 +59,11 @@ libgdk-3.0.dylib
libgdk-3.dylib
libgdk_pixbuf-2.0.0.dylib
libgdk_pixbuf-2.0.dylib
libgettextlib-0.20.2.dylib
libgettextlib-0.21.dylib
libgettextlib.dylib
libgettextpo.0.dylib
libgettextpo.dylib
libgettextsrc-0.20.2.dylib
libgettextsrc-0.21.dylib
libgettextsrc.dylib
libgio-2.0.0.dylib
libgio-2.0.dylib
@@ -82,7 +77,7 @@ libgmp.10.dylib
libgmp.dylib
libgnutls.30.dylib
libgnutls.dylib
libgnutlsxx.28.dylib
libgnutlsxx.30.dylib
libgnutlsxx.dylib
libgobject-2.0.0.dylib
libgobject-2.0.dylib
@@ -92,7 +87,7 @@ libgthread-2.0.0.dylib
libgthread-2.0.dylib
libgtk-3.0.dylib
libgtk-3.dylib
libgtkmacintegration-gtk3.2.dylib
libgtkmacintegration-gtk3.4.dylib
libgtkmacintegration-gtk3.dylib
libguile-2.2.1.dylib
libguile-2.2.dylib
@@ -110,33 +105,33 @@ libharfbuzz-subset.0.dylib
libharfbuzz-subset.dylib
libharfbuzz.0.dylib
libharfbuzz.dylib
libhistory.8.0.dylib
libhistory.8.1.dylib
libhistory.8.dylib
libhistory.dylib
libhogweed.5.0.dylib
libhogweed.5.dylib
libhogweed.6.3.dylib
libhogweed.6.dylib
libhogweed.dylib
libicudata.66.1.dylib
libicudata.66.dylib
libicudata.68.2.dylib
libicudata.68.dylib
libicudata.dylib
libicui18n.66.1.dylib
libicui18n.66.dylib
libicui18n.68.2.dylib
libicui18n.68.dylib
libicui18n.dylib
libicuio.66.1.dylib
libicuio.66.dylib
libicuio.68.2.dylib
libicuio.68.dylib
libicuio.dylib
libicutest.66.1.dylib
libicutest.66.dylib
libicutest.68.2.dylib
libicutest.68.dylib
libicutest.dylib
libicutu.66.1.dylib
libicutu.66.dylib
libicutu.68.2.dylib
libicutu.68.dylib
libicutu.dylib
libicuuc.66.1.dylib
libicuuc.66.dylib
libicuuc.68.2.dylib
libicuuc.68.dylib
libicuuc.dylib
libintl.8.dylib
libintl.dylib
libjavascriptcoregtk-4.0.18.17.10.dylib
libjavascriptcoregtk-4.0.18.18.4.dylib
libjavascriptcoregtk-4.0.18.dylib
libjavascriptcoregtk-4.0.dylib
libjpeg.9.dylib
@@ -145,10 +140,8 @@ libltdl.7.dylib
libltdl.dylib
liblzma.5.dylib
liblzma.dylib
libmysqlclient.18.dylib
libmysqlclient.dylib
libnettle.7.0.dylib
libnettle.7.dylib
libnettle.8.3.dylib
libnettle.8.dylib
libnettle.dylib
libofx.7.dylib
libofx.dylib
@@ -180,8 +173,8 @@ libpq.5.dylib
libpq.dylib
libpsl.5.dylib
libpsl.dylib
libpython3.8.dylib
libreadline.8.0.dylib
libpython3.10.dylib
libreadline.8.1.dylib
libreadline.8.dylib
libreadline.dylib
librsvg-2.2.dylib
@@ -204,9 +197,9 @@ libtiffxx.5.dylib
libtiffxx.dylib
libunistring.2.dylib
libunistring.dylib
libvala-0.36.0.dylib
libvala-0.36.dylib
libwebkit2gtk-4.0.37.49.6.dylib
libvala-0.52.0.dylib
libvala-0.52.dylib
libwebkit2gtk-4.0.37.53.1.dylib
libwebkit2gtk-4.0.37.dylib
libwebkit2gtk-4.0.dylib
libwebp.7.dylib
@@ -229,8 +222,9 @@ libxmlsec1.1.dylib
libxmlsec1.dylib
libxslt.1.dylib
libxslt.dylib
libz.1.2.11.dylib
libz.1.2.13.dylib
libz.1.dylib
libz.dylib
mariadb
pkgconfig
python3.8
python3.10

View File

@@ -1,7 +1,7 @@
cmake
cmake-3.17
cmake-3.20
gettext
gettext-0.20.2
gettext-0.21
guile
itstool
pkgconfig
swig

View File

@@ -12,6 +12,7 @@ jhbuild build
cd /Users/runner/gnucash
mv inst arch
cp $(which ninja) arch/bin/
mkdir inst
for i in 'bin' 'include' 'lib' 'share'; do
j="$DIR/util/ci/macos-ci-deps/macos_$i.manifest"