From a776d8b0b50f709c69f201b011dd0b4ba51214d4 Mon Sep 17 00:00:00 2001 From: Stefan Bayer Date: Fri, 15 Oct 2021 21:56:07 +0200 Subject: [PATCH] support SEPA internal transfer --- gnucash/import-export/aqb/dialog-ab-trans.c | 59 +++++++++++++++++++ gnucash/import-export/aqb/dialog-ab-trans.h | 3 + gnucash/import-export/aqb/gnc-ab-transfer.c | 46 ++++++++++++--- gnucash/import-export/aqb/gnc-ab-utils.c | 55 ++++++++++++++++- gnucash/import-export/aqb/gnc-ab-utils.h | 12 ++++ .../aqb/gnc-plugin-aqbanking-ui.xml | 1 + .../import-export/aqb/gnc-plugin-aqbanking.c | 57 ++++++++++++++++++ 7 files changed, 224 insertions(+), 9 deletions(-) diff --git a/gnucash/import-export/aqb/dialog-ab-trans.c b/gnucash/import-export/aqb/dialog-ab-trans.c index 446061b1a8..540df3fce6 100644 --- a/gnucash/import-export/aqb/dialog-ab-trans.c +++ b/gnucash/import-export/aqb/dialog-ab-trans.c @@ -153,6 +153,9 @@ gboolean gnc_ab_trans_isSEPA(GncABTransType t) switch (t) { case SEPA_TRANSFER: +#if (AQBANKING_VERSION_INT >= 60400) + case SEPA_INTERNAL_TRANSFER: +#endif case SEPA_DEBITNOTE: return TRUE; default: @@ -282,6 +285,12 @@ gnc_ab_trans_dialog_new(GtkWidget *parent, GNC_AB_ACCOUNT_SPEC *ab_acc, GtkWidget *orig_bankcode_label; GtkCellRenderer *renderer; GtkTreeViewColumn *column; +#if (AQBANKING_VERSION_INT >= 60400) + GtkExpander *template_expander; + GtkWidget *template_label; + GtkWidget *add_templ_button; + GtkWidget *del_templ_button; +#endif g_return_val_if_fail(ab_acc, NULL); @@ -342,6 +351,12 @@ gnc_ab_trans_dialog_new(GtkWidget *parent, GNC_AB_ACCOUNT_SPEC *ab_acc, orig_bankcode_label = GTK_WIDGET(gtk_builder_get_object (builder, "orig_bankcode_label")); td->template_gtktreeview = GTK_TREE_VIEW(gtk_builder_get_object (builder, "template_list")); +#if (AQBANKING_VERSION_INT >= 60400) + template_expander = GTK_EXPANDER(gtk_builder_get_object (builder, "expander1")); + template_label = GTK_WIDGET(gtk_builder_get_object (builder, "label1")); + add_templ_button= GTK_WIDGET(gtk_builder_get_object(builder, "add_templ_button")); + del_templ_button= GTK_WIDGET(gtk_builder_get_object(builder, "del_templ_button")); +#endif /* Amount edit */ td->amount_edit = gnc_amount_edit_new(); @@ -388,6 +403,45 @@ gnc_ab_trans_dialog_new(GtkWidget *parent, GNC_AB_ACCOUNT_SPEC *ab_acc, _("Originator BIC (Bank Code)")); break; +#if (AQBANKING_VERSION_INT >= 60400) + case SEPA_INTERNAL_TRANSFER: + gtk_label_set_text(GTK_LABEL (heading_label), + /* Translators: Strings from this file are + needed only in countries that have one of + aqbanking's Online Banking techniques + available. This is 'OFX DirectConnect' + (U.S. and others), 'HBCI' (Germany), + or 'YellowNet' (Switzerland). If none of + these techniques are available in your + country, you may safely ignore strings + from the import-export/hbci + subdirectory. */ + _("Enter a SEPA Internal Transfer")); + gtk_label_set_text(GTK_LABEL(recp_account_heading), + _("Recipient IBAN (International Account Number)")); + gtk_label_set_text(GTK_LABEL(recp_bankcode_heading), + _("Recipient BIC (Bank Code)")); + + gtk_label_set_text(GTK_LABEL(orig_account_heading), + _("Originator IBAN (International Account Number)")); + gtk_label_set_text(GTK_LABEL(orig_bankcode_heading), + _("Originator BIC (Bank Code)")); + /* Disable target account entry for SEPA internal transfers, but only let choose from templates */ + gtk_widget_set_sensitive(td->recp_name_entry, FALSE); + gtk_widget_set_sensitive(td->recp_account_entry, FALSE); + gtk_widget_set_sensitive(td->recp_bankcode_entry, FALSE); + gtk_widget_set_sensitive(add_templ_button, FALSE); + gtk_widget_set_visible(add_templ_button, FALSE); + gtk_widget_set_can_focus(add_templ_button, FALSE); + gtk_widget_set_sensitive(del_templ_button, FALSE); + gtk_widget_set_visible(del_templ_button, FALSE); + gtk_widget_set_can_focus(del_templ_button, FALSE); + gtk_label_set_text(GTK_LABEL(template_label), + _("Target Accounts")); + gtk_expander_set_expanded(template_expander,TRUE); + break; +#endif + case SINGLE_DEBITNOTE: /* this case is no longer in use; don't introduce extra strings */ break; @@ -825,6 +879,11 @@ 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; diff --git a/gnucash/import-export/aqb/dialog-ab-trans.h b/gnucash/import-export/aqb/dialog-ab-trans.h index 2a630e6e1c..1d12dce32f 100644 --- a/gnucash/import-export/aqb/dialog-ab-trans.h +++ b/gnucash/import-export/aqb/dialog-ab-trans.h @@ -56,6 +56,9 @@ enum _GncABTransType SINGLE_INTERNAL_TRANSFER , SEPA_TRANSFER , SEPA_DEBITNOTE +#if (AQBANKING_VERSION_INT >= 60400) + , SEPA_INTERNAL_TRANSFER +#endif }; /** * Returns true if the given GncABTransType is an European (SEPA) transaction diff --git a/gnucash/import-export/aqb/gnc-ab-transfer.c b/gnucash/import-export/aqb/gnc-ab-transfer.c index 8fc9819ee1..86e4bf8b32 100644 --- a/gnucash/import-export/aqb/gnc-ab-transfer.c +++ b/gnucash/import-export/aqb/gnc-ab-transfer.c @@ -114,10 +114,26 @@ 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*/ + templates = gnc_ab_trans_templ_list_new_from_ref_accounts (ab_acc); + if (templates == NULL) + { + g_warning ("gnc_ab_gettrans: No reference accounts found"); + gnc_error_dialog (GTK_WINDOW (parent), _("No reference accounts found.")); + goto cleanup; + } + } + else +#endif + { /* Get list of template transactions */ - templates = gnc_ab_trans_templ_list_new_from_book( - gnc_account_get_book(gnc_acc)); - + templates = gnc_ab_trans_templ_list_new_from_book( + gnc_account_get_book(gnc_acc)); + } + /* Create new ABTransDialog */ td = gnc_ab_trans_dialog_new(parent, ab_acc, xaccAccountGetCommoditySCU(gnc_acc), @@ -156,14 +172,21 @@ gnc_ab_maketrans(GtkWidget *parent, Account *gnc_acc, /* Let the user enter the values */ result = gnc_ab_trans_dialog_run_until_ok(td); - /* Save the templates */ + templates = gnc_ab_trans_dialog_get_templ(td, &changed); - if (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, (result == GNC_RESPONSE_NOW)); - g_list_free(templates); - templates = NULL; - + } + g_list_free(templates); + templates = NULL; + if (result != GNC_RESPONSE_NOW && result != GNC_RESPONSE_LATER) { aborted = TRUE; @@ -220,6 +243,13 @@ gnc_ab_maketrans(GtkWidget *parent, Account *gnc_acc, xfer_dialog, _("Online Banking European (SEPA) Transfer")); gnc_xfer_dialog_lock_from_account_tree(xfer_dialog); break; +#if (AQBANKING_VERSION_INT >= 60400) + case SEPA_INTERNAL_TRANSFER: + gnc_xfer_dialog_set_title ( + xfer_dialog, _("Online Banking European (SEPA) Internal Transfer")); + gnc_xfer_dialog_lock_from_account_tree (xfer_dialog); + break; +#endif case SEPA_DEBITNOTE: gnc_xfer_dialog_set_title( xfer_dialog, _("Online Banking European (SEPA) Debit Note")); diff --git a/gnucash/import-export/aqb/gnc-ab-utils.c b/gnucash/import-export/aqb/gnc-ab-utils.c index 1a91d63083..1941fdc9ec 100644 --- a/gnucash/import-export/aqb/gnc-ab-utils.c +++ b/gnucash/import-export/aqb/gnc-ab-utils.c @@ -35,7 +35,11 @@ #include #include #ifdef AQBANKING6 -# include +#include +#if (AQBANKING_VERSION_INT >= 60400) +#include +#include +#endif #endif #include "window-reconcile.h" #include "Transaction.h" @@ -1331,3 +1335,52 @@ gnc_ab_get_permanent_certs(void) g_return_val_if_fail(rv >= 0, NULL); return perm_certs; } + +#if (AQBANKING_VERSION_INT >= 60400) +GList* +gnc_ab_trans_templ_list_new_from_ref_accounts(GNC_AB_ACCOUNT_SPEC *ab_acc) +{ + GList *retval = NULL; + AB_REFERENCE_ACCOUNT *ra = NULL; + AB_REFERENCE_ACCOUNT_LIST *ral; + int16_t numAccounts; + int16_t counter; + GWEN_BUFFER *accNameForTemplate; + const char *accName; + const char *iban; + gnc_numeric zero=gnc_numeric_zero(); + + /* get the target account list */ + ral = AB_AccountSpec_GetRefAccountList(ab_acc); + numAccounts = AB_ReferenceAccount_List_GetCount(ral); + ra = AB_ReferenceAccount_List_First(ral); + accNameForTemplate = GWEN_Buffer_new(0,120,0,0); + + /* fill the template list with the target accounts */ + while (ra) + { + GncABTransTempl *new_templ; + GWEN_Buffer_Reset(accNameForTemplate); + iban = AB_ReferenceAccount_GetIban(ra); + accName = AB_ReferenceAccount_GetAccountName(ra); + if (accName) { + GWEN_Buffer_AppendString(accNameForTemplate, accName); + GWEN_Buffer_AppendString(accNameForTemplate, ": "); + } + GWEN_Buffer_AppendString(accNameForTemplate, iban); + new_templ = gnc_ab_trans_templ_new(); + gnc_ab_trans_templ_set_name(new_templ,GWEN_Buffer_GetStart(accNameForTemplate)); + gnc_ab_trans_templ_set_recp_name(new_templ,AB_ReferenceAccount_GetOwnerName(ra)); + gnc_ab_trans_templ_set_recp_account(new_templ,AB_ReferenceAccount_GetIban(ra)); + gnc_ab_trans_templ_set_recp_bankcode(new_templ,AB_ReferenceAccount_GetBic(ra)); + gnc_ab_trans_templ_set_amount(new_templ,zero); + retval = g_list_prepend (retval, new_templ); + ra = AB_ReferenceAccount_List_Next(ra); + } + retval = g_list_reverse (retval); + + GWEN_Buffer_free(accNameForTemplate); + + return retval; +} +#endif diff --git a/gnucash/import-export/aqb/gnc-ab-utils.h b/gnucash/import-export/aqb/gnc-ab-utils.h index 3f48462287..bc9a3251ca 100644 --- a/gnucash/import-export/aqb/gnc-ab-utils.h +++ b/gnucash/import-export/aqb/gnc-ab-utils.h @@ -287,6 +287,18 @@ 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. + * + * @param ab_abb aqbanking account spec. + * @return A GList of newly allocated GncABTransTempls + */ +GList* +gnc_ab_trans_templ_list_new_from_ref_accounts(GNC_AB_ACCOUNT_SPEC *ab_acc); +#endif + G_END_DECLS /** @} */ diff --git a/gnucash/import-export/aqb/gnc-plugin-aqbanking-ui.xml b/gnucash/import-export/aqb/gnc-plugin-aqbanking-ui.xml index 627c674124..6d7c55ad43 100644 --- a/gnucash/import-export/aqb/gnc-plugin-aqbanking-ui.xml +++ b/gnucash/import-export/aqb/gnc-plugin-aqbanking-ui.xml @@ -21,6 +21,7 @@ + diff --git a/gnucash/import-export/aqb/gnc-plugin-aqbanking.c b/gnucash/import-export/aqb/gnc-plugin-aqbanking.c index 0683492df7..ad237fddd0 100644 --- a/gnucash/import-export/aqb/gnc-plugin-aqbanking.c +++ b/gnucash/import-export/aqb/gnc-plugin-aqbanking.c @@ -72,6 +72,7 @@ static void gnc_plugin_ab_cmd_setup(GtkAction *action, GncMainWindowActionData * static void gnc_plugin_ab_cmd_get_balance(GtkAction *action, GncMainWindowActionData *data); static void gnc_plugin_ab_cmd_get_transactions(GtkAction *action, GncMainWindowActionData *data); static void gnc_plugin_ab_cmd_issue_sepatransaction(GtkAction *action, GncMainWindowActionData *data); +static void gnc_plugin_ab_cmd_issue_sepainternaltransaction(GtkAction *action, GncMainWindowActionData *data); 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); @@ -114,6 +115,12 @@ static GtkActionEntry gnc_plugin_actions [] = N_("Issue a new international European (SEPA) transaction online through Online Banking"), G_CALLBACK(gnc_plugin_ab_cmd_issue_sepatransaction) }, + { + "ABIssueSepaIntTransAction", NULL, + N_("Issue SEPA I_nternal Transaction..."), NULL, + N_("Issue a new internal European (SEPA) transaction online through Online Banking"), + G_CALLBACK(gnc_plugin_ab_cmd_issue_sepainternaltransaction) + }, { "ABIssueIntTransAction", NULL, N_("_Internal Transaction..."), NULL, N_("Issue a new bank-internal transaction online through Online Banking"), @@ -179,11 +186,22 @@ static const gchar *need_account_actions[] = "ABGetBalanceAction", "ABGetTransAction", "ABIssueSepaTransAction", +#if (AQBANKING_VERSION_INT >= 60400) + "ABIssueSepaIntTransAction", +#endif "ABIssueIntTransAction", "ABIssueSepaDirectDebitAction", NULL }; +#if (AQBANKING_VERSION_INT < 60400) +static const gchar *inactive_account_actions[] = +{ + "ABIssueSepaIntTransAction", + NULL +}; +#endif + static const gchar *readonly_inactive_actions[] = { "OnlineActionsAction", @@ -379,6 +397,12 @@ gnc_plugin_ab_account_selected(GncPluginPage *plugin_page, Account *account, && accountid && *accountid)); gnc_plugin_update_actions(action_group, need_account_actions, "visible", TRUE); +#if (AQBANKING_VERSION_INT < 60400) + gnc_plugin_update_actions(action_group, inactive_account_actions, + "sensitive", FALSE); + gnc_plugin_update_actions(action_group, inactive_account_actions, + "visible", FALSE); +#endif } else { @@ -549,6 +573,39 @@ gnc_plugin_ab_cmd_issue_sepatransaction(GtkAction *action, LEAVE(" "); } +#if (AQBANKING_VERSION_INT >= 60400) +static void +gnc_plugin_ab_cmd_issue_sepainternaltransaction(GtkAction *action, + GncMainWindowActionData *data) +{ + Account *account; + + ENTER("action %p, main window data %p", action, data); + account = main_window_to_account(data->window); + if (account == NULL) + { + PINFO("No AqBanking account selected"); + LEAVE("no account"); + return; + } + + gnc_main_window = data->window; + gnc_ab_maketrans(GTK_WIDGET(data->window), account, SEPA_INTERNAL_TRANSFER); + + LEAVE(" "); +} +#else +static void +gnc_plugin_ab_cmd_issue_sepainternaltransaction(GtkAction *action, + GncMainWindowActionData *data) +{ + + ENTER("action %p, main window data %p", action, data); + PINFO("Sepa Internal Transfer not supported by your aqbanking version!"); + LEAVE("Sepa Internal Transfer not supported!"); +} +#endif + static void gnc_plugin_ab_cmd_issue_inttransaction(GtkAction *action, GncMainWindowActionData *data)