r17190 - gnucash/branches/aqbanking3/src/import-export/aqbanking - Readd online transaction issuing, a first rough sketch.
Andreas Köhler
andi5 at cvs.gnucash.org
Wed Jun 4 18:25:41 EDT 2008
Author: andi5
Date: 2008-06-04 18:25:40 -0400 (Wed, 04 Jun 2008)
New Revision: 17190
Trac: http://svn.gnucash.org/trac/changeset/17190
Modified:
gnucash/branches/aqbanking3/src/import-export/aqbanking/aqbanking.glade
gnucash/branches/aqbanking3/src/import-export/aqbanking/dialog-ab-trans.c
gnucash/branches/aqbanking3/src/import-export/aqbanking/dialog-ab-trans.h
gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-getbalance.h
gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-gettrans.h
gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-transfer.c
gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-transfer.h
Log:
Readd online transaction issuing, a first rough sketch.
Modified: gnucash/branches/aqbanking3/src/import-export/aqbanking/aqbanking.glade
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/aqbanking.glade 2008-06-04 22:25:32 UTC (rev 17189)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/aqbanking.glade 2008-06-04 22:25:40 UTC (rev 17190)
@@ -19,7 +19,6 @@
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
- <property name="urgency_hint">False</property>
<signal name="key_press_event" handler="dai_key_press_event_cb" last_modification_time="Mon, 24 Mar 2008 03:19:32 GMT"/>
<signal name="destroy" handler="dai_destroy_cb" last_modification_time="Mon, 24 Mar 2008 03:20:48 GMT"/>
@@ -244,7 +243,6 @@
<widget class="GtkDialog" id="Transaction Dialog">
<property name="border_width">5</property>
- <property name="visible">True</property>
<property name="title" translatable="yes">Online Transaction</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
@@ -257,7 +255,6 @@
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
- <property name="urgency_hint">False</property>
<property name="has_separator">True</property>
<child internal-child="vbox">
@@ -273,7 +270,6 @@
<child>
<widget class="GtkButton" id="exec_later_button">
- <property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Execute later (unimpl.)</property>
@@ -494,6 +490,7 @@
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">False</property>
+ <signal name="changed" handler="dat_bankcode_changed_cb" last_modification_time="Tue, 03 Jun 2008 22:22:13 GMT"/>
</widget>
<packing>
<property name="left_attach">2</property>
@@ -964,7 +961,7 @@
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
- <signal name="clicked" handler="add_template_cb"/>
+ <signal name="clicked" handler="dat_add_templ_cb" last_modification_time="Sun, 01 Jun 2008 14:39:57 GMT"/>
<child>
<widget class="GtkAlignment" id="alignment3">
@@ -1041,7 +1038,7 @@
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
- <signal name="clicked" handler="moveup_templ_cb"/>
+ <signal name="clicked" handler="dat_moveup_templ_cb" last_modification_time="Sun, 01 Jun 2008 14:32:42 GMT"/>
</widget>
</child>
@@ -1054,7 +1051,7 @@
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
- <signal name="clicked" handler="movedown_templ_cb"/>
+ <signal name="clicked" handler="dat_movedown_templ_cb" last_modification_time="Sun, 01 Jun 2008 14:32:50 GMT"/>
</widget>
</child>
@@ -1065,7 +1062,7 @@
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
- <signal name="clicked" handler="sort_templ_cb"/>
+ <signal name="clicked" handler="dat_sort_templ_cb" last_modification_time="Sun, 01 Jun 2008 14:32:33 GMT"/>
<child>
<widget class="GtkAlignment" id="alignment4">
@@ -1142,7 +1139,7 @@
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
- <signal name="clicked" handler="del_template_cb"/>
+ <signal name="clicked" handler="dat_del_templ_cb" last_modification_time="Sun, 01 Jun 2008 14:41:33 GMT"/>
</widget>
</child>
</widget>
@@ -1163,24 +1160,16 @@
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
- <widget class="GtkViewport" id="viewport1">
+ <widget class="GtkTreeView" id="template_list">
<property name="visible">True</property>
- <property name="shadow_type">GTK_SHADOW_IN</property>
-
- <child>
- <widget class="GtkTreeView" id="template_list">
- <property name="headers_visible">True</property>
- <property name="rules_hint">True</property>
- <property name="reorderable">False</property>
- <property name="enable_search">True</property>
- <property name="fixed_height_mode">False</property>
- <property name="hover_selection">False</property>
- <property name="hover_expand">False</property>
- <signal name="select_child" handler="on_template_list_select_child"/>
- <signal name="selection_changed" handler="on_template_list_selection_changed"/>
- <signal name="unselect_child" handler="on_template_list_unselect_child"/>
- </widget>
- </child>
+ <property name="headers_visible">False</property>
+ <property name="rules_hint">True</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ <property name="fixed_height_mode">False</property>
+ <property name="hover_selection">False</property>
+ <property name="hover_expand">False</property>
+ <signal name="row_activated" handler="templ_list_row_activated_cb" last_modification_time="Wed, 04 Jun 2008 20:43:02 GMT"/>
</widget>
</child>
</widget>
@@ -1420,7 +1409,6 @@
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
- <property name="urgency_hint">False</property>
<property name="has_separator">True</property>
<signal name="delete_event" handler="ggg_delete_event_cb" last_modification_time="Thu, 03 Apr 2008 23:38:57 GMT"/>
@@ -1822,7 +1810,6 @@
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
- <property name="urgency_hint">False</property>
<property name="has_separator">True</property>
<child internal-child="vbox">
@@ -2204,7 +2191,6 @@
<widget class="GtkDialog" id="Template Name Dialog">
<property name="border_width">5</property>
- <property name="visible">True</property>
<property name="title" translatable="yes">Name for new template</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
@@ -2217,7 +2203,6 @@
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
- <property name="urgency_hint">False</property>
<property name="has_separator">True</property>
<child internal-child="vbox">
@@ -2341,7 +2326,6 @@
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
- <property name="urgency_hint">False</property>
<property name="has_separator">True</property>
<child internal-child="vbox">
@@ -2559,7 +2543,6 @@
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
- <property name="urgency_hint">False</property>
<child>
<widget class="GtkTable" id="aqbanking_prefs">
Modified: gnucash/branches/aqbanking3/src/import-export/aqbanking/dialog-ab-trans.c
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/dialog-ab-trans.c 2008-06-04 22:25:32 UTC (rev 17189)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/dialog-ab-trans.c 2008-06-04 22:25:40 UTC (rev 17190)
@@ -31,9 +31,961 @@
#include "config.h"
+#include <glib/gi18n.h>
+#if HAVE_KTOBLZCHECK_H
+# include <ktoblzcheck.h>
+#endif
+#include <aqbanking/jobsingletransfer.h>
+#include <aqbanking/jobsingledebitnote.h>
+#include <aqbanking/jobinternaltransfer.h>
+
#include "dialog-ab-trans.h"
-#include "qof.h" /* check later */
+#include "dialog-transfer.h"
+#include "dialog-utils.h"
+#include "gnc-ab-trans-templ.h"
+#include "gnc-ab-utils.h"
+#include "gnc-amount-edit.h"
+#include "gnc-ui.h"
+enum _ConfirmationState {
+ UNCHANGED,
+ REPLACE,
+ RETAIN
+};
+
/* This static indicates the debugging module that this .o belongs to. */
static QofLogModule log_module = G_LOG_DOMAIN;
+static void fill_templ_helper(gpointer data, gpointer user_data);
+static AB_TRANSACTION *ab_trans_fill_values(GncABTransDialog *td);
+static gboolean check_ktoblzcheck(GtkWidget *parent, const GncABTransDialog *td,
+ const AB_TRANSACTION *trans);
+static gboolean clear_templ_helper(GtkTreeModel *model, GtkTreePath *path,
+ GtkTreeIter *iter, gpointer user_data);
+static gboolean get_templ_helper(GtkTreeModel *model, GtkTreePath *path,
+ GtkTreeIter *iter, gpointer data);
+static gboolean is_change_allowed(gboolean changed,
+ enum _ConfirmationState *state,
+ GtkWidget *parent, GncABTransTempl *templ);
+
+void dat_bankcode_changed_cb(GtkEditable *editable, gpointer user_data);
+void templ_list_row_activated_cb(GtkTreeView *view, GtkTreePath *path,
+ GtkTreeViewColumn *column, gpointer user_data);
+static gboolean find_templ_helper(GtkTreeModel *model, GtkTreePath *path,
+ GtkTreeIter *iter, gpointer user_data);
+void dat_add_templ_cb(GtkButton *button, gpointer user_data);
+void dat_moveup_templ_cb(GtkButton *button, gpointer user_data);
+void dat_movedown_templ_cb(GtkButton *button, gpointer user_data);
+void dat_sort_templ_cb(GtkButton *button, gpointer user_data);
+void dat_del_templ_cb(GtkButton *button, gpointer user_data);
+
+enum {
+ TEMPLATE_NAME,
+ TEMPLATE_POINTER,
+ TEMPLATE_NUM_COLUMNS
+};
+
+struct _GncABTransDialog {
+ /* The dialog itself */
+ GtkWidget *dialog;
+ GtkWidget *parent;
+ AB_ACCOUNT *ab_acc;
+
+ /* Whether this is a transfer or a direct debit */
+ GncABTransType trans_type;
+
+ /* Recipient */
+ GtkWidget *recp_name_entry;
+ GtkWidget *recp_account_entry;
+ GtkWidget *recp_bankcode_entry;
+
+ /* Amount */
+ GtkWidget *amount_edit;
+
+ /* Purpose, description */
+ GtkWidget *purpose_entry;
+ GtkWidget *purpose_cont_entry;
+ GtkWidget *purpose_cont2_entry;
+ GtkWidget *purpose_cont3_entry;
+
+ /* Recipient's bank name (may be filled in automatically sometime later) */
+ GtkWidget *recp_bankname_label;
+
+ /* The template choosing GtkTreeView/GtkListStore */
+ GtkTreeView *template_gtktreeview;
+ GtkListStore *template_list_store;
+
+ /* Flag, if template list has been changed */
+ gboolean templ_changed;
+
+ /* The aqbanking transaction that got created here */
+ AB_TRANSACTION *ab_trans;
+
+ /* The gnucash transaction dialog where the user specifies the
+ * gnucash transaction. */
+ XferDialog *gnc_trans_dialog;
+
+ /* The gnucash transaction that got created here */
+ Transaction *gnc_trans;
+
+#if HAVE_KTOBLZCHECK_H
+ /* object for Account number checking */
+ AccountNumberCheck *blzcheck;
+#endif
+};
+
+static void
+fill_templ_helper(gpointer data, gpointer user_data)
+{
+ GncABTransTempl *templ = data;
+ GtkListStore *store = user_data;
+ GtkTreeIter iter;
+
+ g_return_if_fail(templ && store);
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter,
+ TEMPLATE_NAME, gnc_ab_trans_templ_get_name(templ),
+ TEMPLATE_POINTER, templ,
+ -1);
+}
+
+/**
+ * Create a new AB_TRANSACTION, fill the values from the entry fields into it
+ * and return it. The caller must AB_TRANSACTION_free() it when finished.
+ */
+static AB_TRANSACTION *
+ab_trans_fill_values(GncABTransDialog *td)
+{
+ /* Fill in the user-entered values */
+ AB_TRANSACTION *trans = AB_Transaction_new();
+ AB_VALUE *value;
+
+ AB_Transaction_SetLocalBankCode(trans, AB_Account_GetBankCode(td->ab_acc));
+ AB_Transaction_SetLocalAccountNumber(
+ trans, AB_Account_GetAccountNumber(td->ab_acc));
+ AB_Transaction_SetLocalCountry(trans, "DE");
+
+ AB_Transaction_SetRemoteBankCode(
+ trans, gtk_entry_get_text(GTK_ENTRY(td->recp_bankcode_entry)));
+ AB_Transaction_SetRemoteAccountNumber(
+ trans, gtk_entry_get_text(GTK_ENTRY(td->recp_account_entry)));
+ AB_Transaction_SetRemoteCountry(trans, "DE");
+ 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);
+
+ value = AB_Value_fromDouble(gnc_amount_edit_get_damount(
+ GNC_AMOUNT_EDIT(td->amount_edit)));
+ /* FIXME: Replace "EUR" by account-dependent string here. */
+ AB_Value_SetCurrency(value, "EUR");
+ AB_Transaction_SetValue(trans, value);
+ AB_Value_free(value);
+
+ /* If this is a direct debit, a textkey/ "Textschluessel"/transactionCode
+ * different from the default has to be set. */
+ switch (td->trans_type) {
+ case SINGLE_DEBITNOTE:
+ /* AB_Transaction_SetTransactionCode (trans, 05); */
+ AB_Transaction_SetTextKey(trans, 05);
+ break;
+ default:
+ /* AB_Transaction_SetTransactionCode (trans, 51); */
+ AB_Transaction_SetTextKey (trans, 51);
+ }
+
+ return trans;
+}
+
+GncABTransDialog *
+gnc_ab_trans_dialog_new(GtkWidget *parent, AB_ACCOUNT *ab_acc,
+ gint commodity_scu, GncABTransType trans_type,
+ GList *templates)
+{
+ GncABTransDialog *td;
+ GladeXML *xml;
+ const gchar *ab_ownername;
+ const gchar *ab_accountnumber;
+ const gchar *ab_bankname;
+ const gchar *ab_bankcode;
+ GtkWidget *heading_label;
+ GtkWidget *recp_name_heading;
+ GtkWidget *recp_account_heading;
+ GtkWidget *recp_bankcode_heading;
+ GtkWidget *amount_hbox;
+ GtkWidget *orig_name_heading;
+ GtkWidget *orig_name_label;
+ GtkWidget *orig_account_heading;
+ GtkWidget *orig_account_label;
+ GtkWidget *orig_bankname_heading;
+ GtkWidget *orig_bankname_label;
+ GtkWidget *orig_bankcode_heading;
+ GtkWidget *orig_bankcode_label;
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+
+ g_return_val_if_fail(ab_acc, NULL);
+
+ 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)");
+
+ td = g_new0(GncABTransDialog, 1);
+ td->parent = parent;
+ td->ab_acc = ab_acc;
+ td->trans_type = trans_type;
+
+#if HAVE_KTOBLZCHECK_H
+ td->blzcheck = AccountNumberCheck_new();
+#endif
+
+ xml = gnc_glade_xml_new("aqbanking.glade", "Transaction Dialog");
+ td->dialog = glade_xml_get_widget(xml, "Transaction Dialog");
+ g_object_set_data_full(G_OBJECT(td->dialog), "xml", xml, g_object_unref);
+ glade_xml_signal_autoconnect_full(xml, gnc_glade_autoconnect_full_func, td);
+
+ if (parent)
+ gtk_window_set_transient_for(GTK_WINDOW(td->dialog), GTK_WINDOW(parent));
+
+ /* Extract widgets */
+ heading_label = glade_xml_get_widget(xml, "heading_label");
+ recp_name_heading = glade_xml_get_widget(xml, "recp_name_heading");
+ td->recp_name_entry = glade_xml_get_widget(xml, "recp_name_entry");
+ recp_account_heading = glade_xml_get_widget(xml, "recp_account_heading");
+ td->recp_account_entry = glade_xml_get_widget(xml, "recp_account_entry");
+ recp_bankcode_heading = glade_xml_get_widget(xml, "recp_bankcode_heading");
+ td->recp_bankcode_entry = glade_xml_get_widget(xml, "recp_bankcode_entry");
+ td->recp_bankname_label = glade_xml_get_widget(xml, "recp_bankname_label");
+ amount_hbox = glade_xml_get_widget(xml, "amount_hbox");
+ td->purpose_entry = glade_xml_get_widget(xml, "purpose_entry");
+ td->purpose_cont_entry = glade_xml_get_widget(xml, "purpose_cont_entry");
+ td->purpose_cont2_entry = glade_xml_get_widget(xml, "purpose_cont2_entry");
+ td->purpose_cont3_entry = glade_xml_get_widget(xml, "purpose_cont3_entry");
+ orig_name_heading = glade_xml_get_widget(xml, "orig_name_heading");
+ orig_name_label = glade_xml_get_widget(xml, "orig_name_label");
+ orig_account_heading = glade_xml_get_widget(xml, "orig_account_heading");
+ orig_account_label = glade_xml_get_widget(xml, "orig_account_label");
+ orig_bankname_heading = glade_xml_get_widget(xml, "orig_bankname_heading");
+ orig_bankname_label = glade_xml_get_widget(xml, "orig_bankname_label");
+ orig_bankcode_heading = glade_xml_get_widget(xml, "orig_bankcode_heading");
+ orig_bankcode_label = glade_xml_get_widget(xml, "orig_bankcode_label");
+ td->template_gtktreeview =
+ GTK_TREE_VIEW(glade_xml_get_widget(xml, "template_list"));
+
+ /* Amount edit */
+ td->amount_edit = gnc_amount_edit_new();
+ gtk_box_pack_start_defaults(GTK_BOX(amount_hbox), td->amount_edit);
+ gnc_amount_edit_set_evaluate_on_enter(GNC_AMOUNT_EDIT(td->amount_edit),
+ TRUE);
+ gnc_amount_edit_set_fraction(GNC_AMOUNT_EDIT(td->amount_edit),
+ commodity_scu);
+
+ /* Check for what kind of transaction this should be, and change the
+ * labels accordingly */
+ switch (trans_type) {
+ case SINGLE_TRANSFER:
+ case SINGLE_INTERNAL_TRANSFER:
+ /* all labels are already set */
+ break;
+ case SINGLE_DEBITNOTE:
+ 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' (in 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 an Online Direct Debit Note"));
+
+ gtk_label_set_text(GTK_LABEL(recp_name_heading),
+ _("Debited Account Owner"));
+ gtk_label_set_text(GTK_LABEL(recp_account_heading),
+ _("Debited Account Number"));
+ gtk_label_set_text(GTK_LABEL(recp_bankcode_heading),
+ _("Debited Account Bank Code"));
+
+ gtk_label_set_text(GTK_LABEL(orig_name_heading),
+ _("Credited Account Owner"));
+ gtk_label_set_text(GTK_LABEL(orig_account_heading),
+ _("Credited Account Number"));
+ gtk_label_set_text(GTK_LABEL(orig_bankcode_heading),
+ _("Credited Account Bank Code"));
+ break;
+
+ default:
+ g_critical("gnc_ab_trans_dialog_new: Oops, unknown GncABTransType %d",
+ trans_type);
+ }
+
+ gtk_label_set_text(GTK_LABEL(orig_name_label), ab_ownername);
+ gtk_label_set_text(GTK_LABEL(orig_account_label), ab_accountnumber);
+ gtk_label_set_text(GTK_LABEL(orig_bankname_label), ab_bankname);
+ gtk_label_set_text (GTK_LABEL (orig_bankcode_label), ab_bankcode);
+
+ /* Fill list for choosing a transaction template */
+ td->template_list_store = gtk_list_store_new(TEMPLATE_NUM_COLUMNS,
+ G_TYPE_STRING, G_TYPE_POINTER);
+ g_list_foreach(templates, fill_templ_helper, td->template_list_store);
+ gtk_tree_view_set_model(td->template_gtktreeview,
+ GTK_TREE_MODEL(td->template_list_store));
+ td->templ_changed = FALSE;
+ /* Keep a reference to the store */
+
+ /* Show this list */
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes(
+ "Template Name", renderer, "text", TEMPLATE_NAME, NULL);
+ gtk_tree_view_append_column(td->template_gtktreeview, column);
+
+ return td;
+}
+
+static gboolean
+check_ktoblzcheck(GtkWidget *parent, const GncABTransDialog *td,
+ const AB_TRANSACTION *trans)
+{
+#ifndef HAVE_KTOBLZCHECK_H
+ return TRUE;
+#else
+ gint blzresult;
+ const char *blztext;
+ gboolean values_ok = TRUE;
+
+ ENTER(" ");
+
+ blzresult = AccountNumberCheck_check(
+ td->blzcheck,
+ AB_Transaction_GetRemoteBankCode(trans),
+ AB_Transaction_GetRemoteAccountNumber(trans));
+ switch (blzresult) {
+ case 2:
+ gtk_widget_show(parent);
+ values_ok = gnc_verify_dialog(
+ parent, TRUE,
+ _("The internal check of the destination account number '%s' "
+ "at the specified bank with bank code '%s' failed. This means "
+ "the account number might contain an error. Should the online "
+ "transfer job be sent with this account number anyway?"),
+ AB_Transaction_GetRemoteAccountNumber(trans),
+ AB_Transaction_GetRemoteBankCode(trans));
+ blztext = "Kontonummer wahrscheinlich falsch";
+ break;
+ case 0:
+ blztext = "Kontonummer ok";
+ break;
+ case 3:
+ blztext = "bank unbekannt";
+ break;
+ case 1:
+ default:
+ blztext = "unbekannt aus unbekanntem grund";
+ break;
+ }
+
+ LEAVE("KtoBlzCheck said check is %d = %s",
+ blzresult, blztext ? blztext : "(none)");
+
+ return values_ok;
+#endif
+}
+
+gint
+gnc_ab_trans_dialog_run_until_ok(GncABTransDialog *td)
+{
+ gint result;
+ AB_JOB *job;
+ const AB_TRANSACTION_LIMITS *joblimits;
+ guint8 max_purpose_lines;
+ gboolean values_ok;
+ gchar *purpose;
+ gchar *othername;
+
+ job = AB_JobSingleTransfer_new(td->ab_acc);
+ if (!job || AB_Job_CheckAvailability(job, 0)) {
+ if (job) AB_Job_free(job);
+ g_warning("gnc_ab_getbalance: JobGetBalance not available for this "
+ "account");
+ return GTK_RESPONSE_CANCEL;
+ }
+
+ /* Activate as many purpose entries as available for the job */
+ joblimits = AB_JobSingleTransfer_GetFieldLimits(job);
+ max_purpose_lines = joblimits ?
+ AB_TransactionLimits_GetMaxLinesPurpose(joblimits) : 2;
+ gtk_widget_set_sensitive(td->purpose_cont_entry, max_purpose_lines > 1);
+ gtk_widget_set_sensitive(td->purpose_cont2_entry, max_purpose_lines > 2);
+ gtk_widget_set_sensitive(td->purpose_cont3_entry, max_purpose_lines > 3);
+
+ /* Show the dialog */
+ gtk_widget_show(td->dialog);
+
+ /* Repeat until entered values make sense */
+ do {
+ /* Now run the dialog until it gets closed by a button press */
+ result = gtk_dialog_run (GTK_DIALOG (td->dialog));
+
+ /* Was cancel pressed or dialog closed?
+ * GNC_RESPONSE_NOW == execute now
+ * GNC_RESPONSE_LATER == scheduled for later execution (unimplemented)
+ * GTK_RESPONSE_CANCEL == cancel
+ * GTK_RESPONSE_DELETE_EVENT == window destroyed */
+ if (result != GNC_RESPONSE_NOW && result != GNC_RESPONSE_LATER) {
+ gtk_widget_destroy(td->dialog);
+ td->dialog = NULL;
+ break;
+ }
+
+ /* Now fill in the values from the entry fields into a new
+ * AB_TRANSACTION */
+ td->ab_trans = ab_trans_fill_values(td);
+ values_ok = TRUE;
+
+ /* Check transaction value */
+ values_ok =
+ AB_Value_GetValueAsDouble(AB_Transaction_GetValue(td->ab_trans))
+ != 0.0;
+ if (!values_ok) {
+ gtk_widget_show(td->dialog);
+ if (gnc_verify_dialog(
+ td->dialog, TRUE, "%s",
+ _("The amount is zero or the amount field could not be "
+ "interpreted correctly. You might have mixed up decimal "
+ "point and comma, compared to your locale settings. "
+ "This does not result in a valid online transfer job. \n"
+ "\n"
+ "Do you want to enter the job again?"))) {
+ continue;
+ } else {
+ AB_Transaction_free(td->ab_trans);
+ td->ab_trans = NULL;
+ result = GTK_RESPONSE_CANCEL;
+ break;
+ }
+ }
+
+ /* Check transaction purpose */
+ purpose = gnc_ab_get_purpose(td->ab_trans);
+ values_ok = *purpose;
+ g_free(purpose);
+ if (!values_ok) {
+ gtk_widget_show(td->dialog);
+ if (gnc_verify_dialog(
+ td->dialog, TRUE, "%s",
+ _("You did not enter any transaction purpose. A purpose is "
+ "required for an online transfer.\n"
+ "\n"
+ "Do you want to enter the job again?"))) {
+ continue;
+ } else {
+ AB_Transaction_free(td->ab_trans);
+ td->ab_trans = NULL;
+ result = GTK_RESPONSE_CANCEL;
+ break;
+ }
+ }
+
+ /* Check recipient / remote name */
+ othername = gnc_ab_get_remote_name(td->ab_trans);
+ values_ok = othername && *othername;
+ g_free(othername);
+ if (!values_ok) {
+ gtk_widget_show(td->dialog);
+ if (gnc_verify_dialog(
+ td->dialog, TRUE, "%s",
+ _("You did not enter a recipient name. A recipient name is "
+ "required for an online transfer.\n"
+ "\n"
+ "Do you want to enter the job again?"))) {
+ continue;
+ } else {
+ AB_Transaction_free(td->ab_trans);
+ td->ab_trans = NULL;
+ result = GTK_RESPONSE_CANCEL;
+ break;
+ }
+ }
+
+ /* FIXME: If this is a direct debit, set the textkey/ "Textschluessel"/
+ * transactionCode according to some GUI selection here!! */
+ /*if (td->trans_type == SINGLE_DEBITNOTE)
+ AB_TRANSACTION_setTextKey (td->hbci_trans, 05); */
+
+ /* And finally check the account code, if ktoblzcheck is available */
+ values_ok = check_ktoblzcheck(td->dialog, td, td->ab_trans);
+
+ } while (!values_ok);
+
+ /* Hide the dialog */
+ if (td->dialog)
+ gtk_widget_hide(td->dialog);
+
+ return result;
+}
+
+static gboolean
+clear_templ_helper(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
+ gpointer user_data) {
+ GncABTransTempl *templ;
+
+ g_return_val_if_fail(model && iter, TRUE);
+
+ gtk_tree_model_get(model, iter, TEMPLATE_POINTER, &templ, -1);
+ gnc_ab_trans_templ_free(templ);
+ return FALSE;
+}
+
+void
+gnc_ab_trans_dialog_free(GncABTransDialog *td)
+{
+ if (!td) return;
+ /* Unregister handler for transaction creation callback */
+ if (td->gnc_trans_dialog)
+ gnc_xfer_dialog_set_txn_cb(td->gnc_trans_dialog, NULL, NULL);
+ if (td->ab_trans)
+ AB_Transaction_free(td->ab_trans);
+ if (td->dialog)
+ gtk_widget_destroy(td->dialog);
+ if (td->template_list_store) {
+ gtk_tree_model_foreach(GTK_TREE_MODEL(td->template_list_store),
+ clear_templ_helper, NULL);
+ g_object_unref(td->template_list_store);
+ }
+#if HAVE_KTOBLZCHECK_H
+ AccountNumberCheck_delete(td->blzcheck);
+#endif
+ g_free(td);
+}
+
+static gboolean
+get_templ_helper(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
+ gpointer data)
+{
+ GList **list = data;
+ GncABTransTempl *templ;
+
+ g_return_val_if_fail(model && iter, TRUE);
+
+ gtk_tree_model_get(model, iter, TEMPLATE_POINTER, &templ, -1);
+ *list = g_list_prepend(*list, templ);
+ return FALSE;
+}
+
+GList *
+gnc_ab_trans_dialog_get_templ(const GncABTransDialog *td, gboolean *changed)
+{
+ GList *list;
+
+ g_return_val_if_fail(td, NULL);
+
+ if (changed) {
+ *changed = td->templ_changed;
+ if (!*changed)
+ return NULL;
+ }
+
+ gtk_tree_model_foreach(GTK_TREE_MODEL(td->template_list_store),
+ get_templ_helper, &list);
+ list = g_list_reverse(list);
+ return list;
+}
+
+GtkWidget *
+gnc_ab_trans_dialog_get_parent(const GncABTransDialog *td)
+{
+ g_return_val_if_fail(td, NULL);
+ return td->parent;
+}
+
+const AB_TRANSACTION *
+gnc_ab_trans_dialog_get_ab_trans(const GncABTransDialog *td)
+{
+ g_return_val_if_fail(td, NULL);
+ return td->ab_trans;
+}
+
+AB_JOB *
+gnc_ab_trans_dialog_get_job(const GncABTransDialog *td)
+{
+ g_return_val_if_fail(td, NULL);
+ return gnc_ab_get_trans_job(td->ab_acc, td->ab_trans, td->trans_type);
+}
+
+AB_JOB *gnc_ab_get_trans_job(AB_ACCOUNT *ab_acc, const AB_TRANSACTION *ab_trans,
+ GncABTransType trans_type)
+{
+ AB_JOB *job;
+
+ g_return_val_if_fail(ab_acc && ab_trans, NULL);
+
+ 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:
+ default:
+ job = AB_JobSingleTransfer_new(ab_acc);
+ };
+
+ if (!job || AB_Job_CheckAvailability(job, 0))
+ return NULL;
+
+ switch (trans_type) {
+ case SINGLE_DEBITNOTE:
+ AB_JobSingleDebitNote_SetTransaction(job, ab_trans);
+ break;
+ case SINGLE_INTERNAL_TRANSFER:
+ AB_JobInternalTransfer_SetTransaction(job, ab_trans);
+ break;
+ case SINGLE_TRANSFER:
+ default:
+ AB_JobSingleTransfer_SetTransaction(job, ab_trans);
+ };
+
+ return job;
+}
+
+static gboolean
+is_change_allowed(gboolean changed, enum _ConfirmationState *state,
+ GtkWidget *parent, GncABTransTempl *templ)
+{
+ if (*state == RETAIN)
+ return FALSE;
+ if (*state == REPLACE || !changed)
+ return TRUE;
+ if (gnc_verify_dialog(
+ parent, FALSE,
+ _("Do you really want to overwrite your changes with the "
+ "contents of the template \"%s\"?"),
+ gnc_ab_trans_templ_get_name(templ))) {
+ *state = REPLACE;
+ return TRUE;
+ } else {
+ *state = RETAIN;
+ return FALSE;
+ }
+}
+
+#define FILL_ENTRY(accessor, widget) \
+ str = (accessor)(templ); \
+ if (!str) str = ""; \
+ changed = strcmp(str, gtk_entry_get_text(GTK_ENTRY((widget)))); \
+ if (is_change_allowed(changed, &state, td->parent, templ)) \
+ gtk_entry_set_text(GTK_ENTRY((widget)), str);
+
+void
+templ_list_row_activated_cb(GtkTreeView *view, GtkTreePath *path,
+ GtkTreeViewColumn *column, gpointer user_data)
+{
+ GncABTransDialog *td = user_data;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GncABTransTempl *templ;
+ const gchar *str;
+ gnc_numeric amount;
+ gboolean changed;
+ enum _ConfirmationState state = UNCHANGED;
+
+ g_return_if_fail(td);
+
+ ENTER("td=%p", td);
+ if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(td->template_list_store), &iter,
+ path)) {
+ LEAVE("Could not get iter");
+ return;
+ }
+ gtk_tree_model_get(GTK_TREE_MODEL(td->template_list_store), &iter,
+ TEMPLATE_POINTER, &templ, -1);
+
+ FILL_ENTRY(gnc_ab_trans_templ_get_recp_name, td->recp_name_entry);
+ FILL_ENTRY(gnc_ab_trans_templ_get_recp_account, td->recp_account_entry);
+ FILL_ENTRY(gnc_ab_trans_templ_get_recp_bankcode, td->recp_bankcode_entry);
+ FILL_ENTRY(gnc_ab_trans_templ_get_purpose, td->purpose_entry);
+ FILL_ENTRY(gnc_ab_trans_templ_get_purpose_cont, td->purpose_cont_entry);
+
+ amount = gnc_ab_trans_templ_get_amount(templ);
+ changed = !gnc_numeric_equal(
+ amount, gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(td->amount_edit)));
+ if (is_change_allowed(changed, &state, td->parent, templ))
+ gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(td->amount_edit), amount);
+
+ LEAVE(" ");
+}
+
+void
+dat_bankcode_changed_cb(GtkEditable *editable, gpointer user_data)
+{
+#if HAVE_KTOBLZCHECK_H
+ GncABTransDialog *td = user_data;
+ const AccountNumberCheck_Record *record;
+ const gchar *input = gtk_entry_get_text(GTK_ENTRY(td->recp_bankcode_entry));
+
+ g_return_if_fail(td);
+
+ ENTER("td=%p, input=%s", td, input);
+ record = AccountNumberCheck_findBank(td->blzcheck, input);
+
+ if (record) {
+ const char *bankname = AccountNumberCheck_Record_bankName(record);
+ GError *error = NULL;
+ const char *ktoblzcheck_encoding =
+#ifdef KTOBLZCHECK_VERSION_MAJOR
+ /* This version number macro has been added in ktoblzcheck-1.10, but
+ * this function exists already since ktoblzcheck-1.7, so we're on
+ * the safe side. */
+ AccountNumberCheck_stringEncoding()
+#else
+ /* Every ktoblzcheck release before 1.10 is guaranteed to return
+ * strings only in ISO-8859-15. */
+ "ISO-8859-15"
+#endif
+ ;
+ gchar *utf8_bankname = g_convert(bankname, strlen(bankname), "UTF-8",
+ ktoblzcheck_encoding, NULL, NULL,
+ &error);
+
+ if (error) {
+ g_critical("Error converting bankname \"%s\" to UTF-8", bankname);
+ g_error_free (error);
+ /* Conversion was erroneous, so don't use the string */
+ utf8_bankname = g_strdup(_("(unknown)"));
+ }
+ gtk_label_set_text(GTK_LABEL(td->recp_bankname_label),
+ *utf8_bankname ? utf8_bankname : _("(unknown)"));
+ DEBUG("Found: %s", utf8_bankname);
+ g_free(utf8_bankname);
+ } else {
+ gtk_label_set_text(GTK_LABEL(td->recp_bankname_label), _("(unknown)"));
+ }
+ LEAVE(" ");
+#endif
+}
+
+struct _FindTemplData {
+ const gchar *name;
+ const GncABTransTempl *pointer;
+};
+
+static gboolean
+find_templ_helper(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
+ gpointer user_data)
+{
+ struct _FindTemplData *data = user_data;
+ gchar *name;
+ GncABTransTempl *templ;
+ gboolean match;
+
+ g_return_val_if_fail(model && data, TRUE);
+ gtk_tree_model_get(model, iter,
+ TEMPLATE_NAME, &name,
+ TEMPLATE_POINTER, &templ,
+ -1);
+ if (data->name) {
+ /* Search for the template by name */
+ g_return_val_if_fail(!data->pointer, TRUE);
+ match = strcmp(name, data->name) == 0;
+ if (match) data->pointer = templ;
+ } else {
+ /* Search for the template by template pointer */
+ g_return_val_if_fail(!data->name, TRUE);
+ match = templ == data->pointer;
+ if (match) data->name = g_strdup(name);
+ }
+ g_free(name);
+ return match;
+}
+
+void
+dat_add_templ_cb(GtkButton *button, gpointer user_data)
+{
+ GncABTransDialog *td = user_data;
+ GladeXML *xml;
+ GtkWidget *dialog;
+ GtkWidget *entry;
+ gint retval;
+ const gchar *name;
+ GncABTransTempl *templ;
+ struct _FindTemplData data;
+ GtkTreeSelection *selection;
+ GtkTreeIter cur_iter;
+ GtkTreeIter new_iter;
+
+ g_return_if_fail(td);
+
+ ENTER("td=%p", td);
+ xml = gnc_glade_xml_new ("aqbanking.glade", "Template Name Dialog");
+ dialog = glade_xml_get_widget(xml, "Template Name Dialog");
+ g_object_set_data_full(G_OBJECT(dialog), "xml", xml, g_object_unref);
+ entry = glade_xml_get_widget(xml, "template_name");
+
+ /* Suggest recipient name as name of the template */
+ gtk_entry_set_text(GTK_ENTRY(entry),
+ gtk_entry_get_text(GTK_ENTRY(td->recp_name_entry)));
+
+ do {
+ retval = gtk_dialog_run(GTK_DIALOG(dialog));
+ if (retval != GTK_RESPONSE_OK)
+ break;
+
+ name = gtk_entry_get_text(GTK_ENTRY(entry));
+ if (!*name)
+ break;
+
+ data.name = name;
+ data.pointer = NULL;
+ gtk_tree_model_foreach(GTK_TREE_MODEL(td->template_list_store),
+ find_templ_helper, &data);
+ if (data.pointer) {
+ gnc_error_dialog(dialog,
+ _("A template with the given name already exists. "
+ "Please enter another name."));
+ continue;
+ }
+
+ /* Create a new template */
+ templ = gnc_ab_trans_templ_new_full(
+ name,
+ gtk_entry_get_text(GTK_ENTRY(td->recp_name_entry)),
+ gtk_entry_get_text(GTK_ENTRY(td->recp_account_entry)),
+ gtk_entry_get_text(GTK_ENTRY(td->recp_bankcode_entry)),
+ gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(td->amount_edit)),
+ gtk_entry_get_text(GTK_ENTRY(td->purpose_entry)),
+ gtk_entry_get_text (GTK_ENTRY(td->purpose_cont_entry)));
+
+ /* Insert it, either after the selected one or at the end */
+ selection = gtk_tree_view_get_selection(td->template_gtktreeview);
+ if (gtk_tree_selection_get_selected(selection, NULL, &cur_iter)) {
+ gtk_list_store_insert_after(td->template_list_store,
+ &new_iter, &cur_iter);
+ } else {
+ gtk_list_store_append(td->template_list_store, &new_iter);
+ }
+ gtk_list_store_set(td->template_list_store, &new_iter,
+ TEMPLATE_NAME, name,
+ TEMPLATE_POINTER, templ,
+ -1);
+ td->templ_changed = TRUE;
+ DEBUG("Added template with name %s", name);
+ break;
+ } while (TRUE);
+
+ gtk_widget_destroy(dialog);
+
+ LEAVE(" ");
+}
+
+void
+dat_moveup_templ_cb(GtkButton *button, gpointer user_data)
+{
+ GncABTransDialog *td = user_data;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkTreePath *prev_path;
+ GtkTreeIter prev_iter;
+
+ g_return_if_fail(td);
+
+ selection = gtk_tree_view_get_selection(td->template_gtktreeview);
+ if (!gtk_tree_selection_get_selected(selection, &model, &iter))
+ return;
+
+ prev_path = gtk_tree_model_get_path(model, &iter);
+ if (gtk_tree_path_prev(prev_path)) {
+ if (gtk_tree_model_get_iter(model, &prev_iter, prev_path)) {
+ gtk_list_store_move_before(GTK_LIST_STORE(model), &iter, &prev_iter);
+ td->templ_changed = TRUE;
+ }
+ }
+ gtk_tree_path_free(prev_path);
+}
+
+void
+dat_movedown_templ_cb(GtkButton *button, gpointer user_data)
+{
+ GncABTransDialog *td = user_data;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkTreeIter next_iter;
+
+ g_return_if_fail(td);
+
+ selection = gtk_tree_view_get_selection(td->template_gtktreeview);
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ return;
+
+ next_iter = iter;
+ if (gtk_tree_model_iter_next(model, &next_iter)) {
+ gtk_list_store_move_after(GTK_LIST_STORE(model), &iter, &next_iter);
+ td->templ_changed = TRUE;
+ }
+}
+
+void
+dat_sort_templ_cb(GtkButton *button, gpointer user_data)
+{
+ GncABTransDialog *td = user_data;
+
+ g_return_if_fail(td);
+
+ ENTER("td=%p", td);
+ gtk_tree_sortable_set_sort_column_id(
+ GTK_TREE_SORTABLE(td->template_list_store),
+ TEMPLATE_NAME, GTK_SORT_ASCENDING);
+ gtk_tree_sortable_set_sort_column_id(
+ GTK_TREE_SORTABLE(td->template_list_store),
+ GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID,
+ GTK_SORT_ASCENDING);
+ td->templ_changed = TRUE;
+ LEAVE(" ");
+}
+
+void
+dat_del_templ_cb(GtkButton *button, gpointer user_data)
+{
+ GncABTransDialog *td = user_data;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gchar *name;
+
+ g_return_if_fail(td);
+
+ ENTER("td=%p", td);
+ selection = gtk_tree_view_get_selection(td->template_gtktreeview);
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter)) {
+ LEAVE("None selected");
+ return;
+ }
+
+ gtk_tree_model_get(model, &iter, TEMPLATE_NAME, &name, -1);
+ if (gnc_verify_dialog(
+ td->parent, FALSE,
+ _("Do you really want to delete the template with the name \"%s\"?"),
+ name)) {
+ gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
+ td->templ_changed = TRUE;
+ DEBUG("Deleted template with name %s", name);
+ }
+ g_free(name);
+ LEAVE(" ");
+}
Modified: gnucash/branches/aqbanking3/src/import-export/aqbanking/dialog-ab-trans.h
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/dialog-ab-trans.h 2008-06-04 22:25:32 UTC (rev 17189)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/dialog-ab-trans.h 2008-06-04 22:25:40 UTC (rev 17190)
@@ -35,12 +35,18 @@
#ifndef DIALOG_AB_TRANS_H
#define DIALOG_AB_TRANS_H
-#include <glib.h>
+#include <gtk/gtk.h>
+#include <aqbanking/banking.h>
+#include "Account.h"
+
G_BEGIN_DECLS
-typedef struct _ABTransDialog ABTransDialog;
+#define GNC_RESPONSE_NOW GTK_RESPONSE_YES
+#define GNC_RESPONSE_LATER GTK_RESPONSE_NO
+typedef struct _GncABTransDialog GncABTransDialog;
+
typedef enum _GncABTransType GncABTransType;
enum _GncABTransType {
SINGLE_TRANSFER = 0,
@@ -48,6 +54,87 @@
SINGLE_INTERNAL_TRANSFER
};
+/**
+ * FIXME
+ *
+ * @param parent Widget to use as parent, may be NULL
+ * @param ab_acc FIXME
+ * @param commodity_scu FIXME
+ * @param trans_type Type of transaction
+ * @param templates A GList of template transactions which will become fully
+ * managed by the dialog, so do not free it and retrieve snapshots via
+ * gnc_ab_trans_dialog_get_templ()
+ * @return FIXME
+ */
+GncABTransDialog *gnc_ab_trans_dialog_new(GtkWidget *parent, AB_ACCOUNT *ab_acc,
+ gint commodity_scu,
+ GncABTransType trans_type,
+ GList *templates);
+
+/**
+ * FIXME
+ *
+ * @param td Transaction dialog
+ * @param ab_acc AqBanking account
+ * @return FIXME
+ */
+gint gnc_ab_trans_dialog_run_until_ok(GncABTransDialog *td);
+
+/**
+ * FIXME
+ *
+ * @param td Transaction dialog
+ */
+void gnc_ab_trans_dialog_free(GncABTransDialog *td);
+
+/**
+ * Retrieve the current list of transaction templates from the dialog @a
+ * td, unless @a changed is a specified location and the templates have
+ * not been touched by the user.
+ *
+ * @param td Transaction dialog
+ * @param changed Location to store whether the templates have been
+ * changed, may be NULL
+ * @return The a newly allocated list of the internal transaction
+ * templates. Free this one via g_list_free().
+ */
+GList *gnc_ab_trans_dialog_get_templ(const GncABTransDialog *td,
+ gboolean *changed);
+
+/**
+ * Retrieve the widget used as parent.
+ *
+ * @param td Transaction dialog
+ * @return The parent
+ */
+GtkWidget *gnc_ab_trans_dialog_get_parent(const GncABTransDialog *td);
+
+/**
+ * FIXME
+ *
+ * @param td Transaction dialog
+ * @return FIXME
+ */
+const AB_TRANSACTION *gnc_ab_trans_dialog_get_ab_trans(
+ const GncABTransDialog *td);
+
+/**
+ * FIXME
+ *
+ * @param td Transaction dialog
+ * @return FIXME
+ */
+AB_JOB *gnc_ab_trans_dialog_get_job(const GncABTransDialog *td);
+
+/**
+ * FIXME
+ *
+ * @param td Transaction dialog
+ * @return FIXME
+ */
+AB_JOB *gnc_ab_get_trans_job(AB_ACCOUNT *ab_acc, const AB_TRANSACTION *ab_trans,
+ GncABTransType trans_type);
+
G_END_DECLS
/** @} */
Modified: gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-getbalance.h
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-getbalance.h 2008-06-04 22:25:32 UTC (rev 17189)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-getbalance.h 2008-06-04 22:25:40 UTC (rev 17190)
@@ -43,7 +43,7 @@
* Execute a GetBalance job, show the resulting balance and offer to reconcile
* the GnuCash account.
*
- * @param parent Widget to use as parent
+ * @param parent Widget to use as parent, may be NULL
* @param gnc_acc GnuCash account to fetch balance for
*/
void gnc_ab_getbalance(GtkWidget *parent, Account *gnc_acc);
Modified: gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-gettrans.h
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-gettrans.h 2008-06-04 22:25:32 UTC (rev 17189)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-gettrans.h 2008-06-04 22:25:40 UTC (rev 17190)
@@ -40,7 +40,7 @@
/**
* Execute a GetTransactions job.
*
- * @param parent Widget to use as parent
+ * @param parent Widget to use as parent, may be NULL
* @param gnc_acc GnuCash account to fetch transactions for
*/
void gnc_ab_gettrans(GtkWidget *parent, Account *gnc_acc);
Modified: gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-transfer.c
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-transfer.c 2008-06-04 22:25:32 UTC (rev 17189)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-transfer.c 2008-06-04 22:25:40 UTC (rev 17190)
@@ -31,16 +31,51 @@
#include "config.h"
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
#include <aqbanking/banking.h>
+#include "Transaction.h"
+#include "dialog-transfer.h"
#include "gnc-ab-transfer.h"
#include "gnc-ab-kvp.h"
#include "gnc-ab-utils.h"
#include "gnc-ab-trans-templ.h"
+#include "gnc-gwen-gui.h"
+#include "gnc-ui.h"
/* This static indicates the debugging module that this .o belongs to. */
static QofLogModule log_module = G_LOG_DOMAIN;
+static void save_templates(GtkWidget *parent, Account *gnc_acc, GList *templates,
+ gboolean dont_ask);
+static void txn_created_cb(Transaction *trans, gpointer user_data);
+
+static void
+save_templates(GtkWidget *parent, Account *gnc_acc, GList *templates,
+ gboolean dont_ask)
+{
+ g_return_if_fail(gnc_acc);
+ if (dont_ask || gnc_verify_dialog(
+ parent, FALSE, "%s",
+ _("You have changed the list of online transfer templates, "
+ "but you cancelled the transfer dialog. "
+ "Do you nevertheless want to store the changes?"))) {
+ GList *kvp_list = gnc_ab_trans_templ_list_to_kvp_list(templates);
+ gnc_ab_set_book_template_list(gnc_account_get_book(gnc_acc), kvp_list);
+ }
+}
+
+static void
+txn_created_cb(Transaction *trans, gpointer user_data)
+{
+ Transaction **trans_loc = user_data;
+
+ if (!trans) return;
+ g_return_if_fail(trans_loc);
+ *trans_loc = trans;
+}
+
void
gnc_ab_maketrans(GtkWidget *parent, Account *gnc_acc,
GncABTransType trans_type)
@@ -48,8 +83,20 @@
AB_BANKING *api;
gboolean online = FALSE;
AB_ACCOUNT *ab_acc;
- ABTransDialog *dialog = NULL;
- GList *template_list = NULL;
+ GncGWENGui *gui = NULL;
+ GncABTransDialog *dialog = NULL;
+ GList *templates = NULL;
+ GncABTransDialog *td = NULL;
+ gboolean successful;
+ gboolean aborted = FALSE;
+ const AB_TRANSACTION *ab_trans;
+ AB_JOB *job = NULL;
+ AB_JOB_LIST2 *job_list = NULL;
+ XferDialog *xfer_dialog = NULL;
+ gnc_numeric amount;
+ gchar *description;
+ gchar *memo;
+ Transaction *gnc_trans = NULL;
g_return_if_fail(parent && gnc_acc);
@@ -72,26 +119,134 @@
goto cleanup;
}
+ /* Get a GUI object */
+ gui = gnc_GWEN_Gui_get(parent);
+ if (!gui) {
+ g_warning("gnc_ab_maketrans: Couldn't initialize Gwenhywfar GUI");
+ goto cleanup;
+ }
+
/* Get list of template transactions */
- template_list = gnc_ab_trans_templ_list_new_from_kvp_list(
+ templates = gnc_ab_trans_templ_list_new_from_kvp_list(
gnc_ab_get_book_template_list(gnc_account_get_book(gnc_acc)));
/* Create new ABTransDialog */
+ td = gnc_ab_trans_dialog_new(parent, ab_acc,
+ xaccAccountGetCommoditySCU(gnc_acc),
+ trans_type, templates);
+ /* Repeat until AqBanking action was successful or user pressed cancel */
+ do {
+ gint result;
+ gboolean changed;
+
+ /* Let the user enter the values */
+ result = gnc_ab_trans_dialog_run_until_ok(td);
+
+ if (result != GNC_RESPONSE_NOW && result != GNC_RESPONSE_LATER)
+ goto cleanup;
+
+ /* Save the templates */
+ templates = gnc_ab_trans_dialog_get_templ(td, &changed);
+ if (changed)
+ save_templates(parent, gnc_acc, templates,
+ (result == GNC_RESPONSE_NOW));
+ g_list_free(templates);
+
+ /* Get a job and enqueue it */
+ ab_trans = gnc_ab_trans_dialog_get_ab_trans(td);
+ job = gnc_ab_trans_dialog_get_job(td);
+ if (!job || AB_Job_CheckAvailability(job, 0)) {
+ if (!gnc_verify_dialog(
+ parent, FALSE, "%s",
+ _("The backend found an error during the preparation "
+ "of the job. It is not possible to execute this job. \n"
+ "\n"
+ "Most probable the bank does not support your chosen "
+ "job or your Online Banking account does not have the permission "
+ "to execute this job. More error messages might be "
+ "visible on your console log.\n"
+ "\n"
+ "Do you want to enter the job again?")))
+ aborted = TRUE;
+ goto repeat;
+ }
+ job_list = AB_Job_List2_new();
+ AB_Job_List2_PushBack(job_list, job);
+
+ /* Setup a Transfer Dialog for the GnuCash transaction */
+ xfer_dialog = gnc_xfer_dialog(gnc_ab_trans_dialog_get_parent(td),
+ gnc_acc);
+ switch (trans_type) {
+ case SINGLE_DEBITNOTE:
+ gnc_xfer_dialog_set_title(
+ xfer_dialog, _("Online Banking Direct Debit Note"));
+ case SINGLE_INTERNAL_TRANSFER:
+ gnc_xfer_dialog_set_title(
+ xfer_dialog, _("Online Banking Bank-Internal Transfer"));
+ case SINGLE_TRANSFER:
+ default:
+ gnc_xfer_dialog_set_title(
+ xfer_dialog, _("Online Banking Transaction"));
+ }
+
+ amount = double_to_gnc_numeric(
+ AB_Value_GetValueAsDouble(AB_Transaction_GetValue(ab_trans)),
+ xaccAccountGetCommoditySCU(gnc_acc),
+ GNC_RND_ROUND);
+ gnc_xfer_dialog_set_amount(xfer_dialog, amount);
+
+ description = gnc_ab_description_to_gnc(ab_trans);
+ gnc_xfer_dialog_set_description(xfer_dialog, description);
+ g_free(description);
+
+ memo = gnc_ab_memo_to_gnc(ab_trans);
+ gnc_xfer_dialog_set_memo(xfer_dialog, memo);
+ g_free(memo);
+
+ gnc_xfer_dialog_set_txn_cb(xfer_dialog, txn_created_cb, &gnc_trans);
+
+ /* And run it */
+ successful = gnc_xfer_dialog_run_until_done(xfer_dialog);
+
+ /* On cancel, go back to the AB transaction dialog */
+ if (!successful || !gnc_trans) {
+ successful = FALSE;
+ goto repeat;
+ }
+
+ if (result == GNC_RESPONSE_NOW) {
+ /* Finally, execute the job */
+ successful = AB_Banking_ExecuteJobs(api, job_list, NULL, 0) == 0;
+ }
+ /* Simply ignore any other case */
+
+ repeat:
+ /* Clean up */
+ if (gnc_trans && !successful) {
+ xaccTransBeginEdit(gnc_trans);
+ xaccTransDestroy(gnc_trans);
+ xaccTransCommitEdit(gnc_trans);
+ gnc_trans = NULL;
+ }
+ if (job_list) {
+ AB_Job_List2_free(job_list);
+ job_list = NULL;
+ }
+ if (job) {
+ AB_Job_free(job);
+ job = NULL;
+ }
+
+ } while (!successful && !aborted);
+
cleanup:
- /* if (context) */
- /* AB_ImExporterContext_free(context); */
- /* if (gui) */
- /* gnc_GWEN_Gui_release(gui); */
- /* if (job_list) */
- /* AB_Job_List2_free(job_list); */
- /* if (job) */
- /* AB_Job_free(job); */
- /* if (to_date) */
- /* GWEN_Time_free(to_date); */
- /* if (from_date) */
- /* GWEN_Time_free(from_date); */
- gnc_ab_trans_templ_list_free(template_list);
+ if (td)
+ gnc_ab_trans_dialog_free(td);
+ if (templates)
+ gnc_ab_trans_templ_list_free(templates);
+ if (gui)
+ gnc_GWEN_Gui_release(gui);
if (online)
AB_Banking_OnlineFini(api);
gnc_AB_BANKING_fini(api);
Modified: gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-transfer.h
===================================================================
--- gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-transfer.h 2008-06-04 22:25:32 UTC (rev 17189)
+++ gnucash/branches/aqbanking3/src/import-export/aqbanking/gnc-ab-transfer.h 2008-06-04 22:25:40 UTC (rev 17190)
@@ -43,7 +43,7 @@
/**
* FIXME
*
- * @param parent Widget to use as parent
+ * @param parent Widget to use as parent, may be NULL
* @param gnc_acc GnuCash account to fetch balance for
* @param trans_type Type of transaction
*/
More information about the gnucash-changes
mailing list