dialog-hbcitrans.c

00001 /********************************************************************\
00002  * dialog-hbcitrans.c -- dialog for hbci transaction                *
00003  * Copyright (C) 2002 Christian Stimming                            *
00004  * Copyright (C) 2004 Bernd Wagner (changes for                     *
00005  *                     online transaction templates)                *
00006  * Copyright (c) 2006 David Hampton <hampton@employees.org>         *
00007  *                                                                  *
00008  * This program is free software; you can redistribute it and/or    *
00009  * modify it under the terms of the GNU General Public License as   *
00010  * published by the Free Software Foundation; either version 2 of   *
00011  * the License, or (at your option) any later version.              *
00012  *                                                                  *
00013  * This program is distributed in the hope that it will be useful,  *
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
00016  * GNU General Public License for more details.                     *
00017  *                                                                  *
00018  * You should have received a copy of the GNU General Public License*
00019  * along with this program; if not, contact:                        *
00020  *                                                                  *
00021  * Free Software Foundation           Voice:  +1-617-542-5942       *
00022  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
00023  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
00024 \********************************************************************/
00025 
00026 #ifdef HAVE_CONFIG_H
00027 #include "config.h"
00028 #endif
00029 
00030 #include <gnome.h>
00031 #include <glib/gi18n.h>
00032 #include <aqbanking/version.h>
00033 #include <aqbanking/account.h>
00034 #include <aqbanking/jobsingletransfer.h>
00035 #include <aqbanking/jobsingledebitnote.h>
00036 #include <aqbanking/jobinternaltransfer.h>
00037 #include <iconv.h>
00038 
00039 #include "dialog-utils.h"
00040 #include "gnc-glib-utils.h"
00041 #include "gnc-ui.h"
00042 #include "gnc-amount-edit.h"
00043 #include "dialog-transfer.h"
00044 
00045 #include "gnc-hbci-utils.h"
00046 #include "gnc-hbci-trans-templ.h"
00047 #include "dialog-hbcitrans.h"
00048 #if HAVE_KTOBLZCHECK_H
00049 #  include <ktoblzcheck.h>
00050 #endif
00051 
00052 #define TEMPLATE_LABEL "template"
00053 
00054 typedef enum {
00055         TEMPLATE_NAME,
00056         TEMPLATE_POINTER,
00057         TEMPLATE_NUM_COLUMNS
00058 } TemplateListColumns;
00059 
00060 /* -------------------------------------- */
00061 /* Data structure */
00062 /* -------------------------------------- */
00063 struct _trans_data 
00064 {
00065   /* The dialog itself */
00066   GtkWidget *dialog;
00067   GtkWidget *parent;
00068 
00069   /* Whether this is a transfer or a direct debit */
00070   GNC_HBCI_Transtype trans_type;
00071 
00072   /* Recipient */
00073   GtkWidget *recp_name_entry;
00074   GtkWidget *recp_account_entry;
00075   GtkWidget *recp_bankcode_entry;
00076 
00077   /* Amount */
00078   GtkWidget *amount_edit;
00079 
00080   /* Purpose, description */
00081   GtkWidget *purpose_entry;
00082   GtkWidget *purpose_cont_entry;
00083   GtkWidget *purpose_cont2_entry;
00084   GtkWidget *purpose_cont3_entry;
00085 
00086   /* Recipient's bank name (may be filled in automatically sometime later) */
00087   GtkWidget *recp_bankname_label;
00088 
00089   /* The template choosing GtkTreeView/GtkListStore */
00090   GtkTreeView *template_gtktreeview;
00091   GtkListStore *template_list_store;
00092 
00093   /* Flag, if template list has been changed */
00094   gboolean templ_changed;
00095   
00096   /* The HBCI transaction that got created here */
00097   AB_TRANSACTION *hbci_trans;
00098   
00099   /* The gnucash transaction dialog where the user specifies the gnucash transaction. */
00100   XferDialog *gnc_trans_dialog;
00101   
00102   /* The Gnucash transaction that got created here */
00103   Transaction *gnc_trans;
00104   
00105 #if HAVE_KTOBLZCHECK_H
00106   /* object for Account number checking */
00107   AccountNumberCheck *blzcheck;
00108 #endif
00109 };
00110 
00111 
00112 void gnc_hbci_dialog_delete(HBCITransDialog *td)
00113 {
00114   if (!td) return;
00115   /* Unregister handler for transaction creation callback */
00116   if (td->gnc_trans_dialog)
00117     gnc_xfer_dialog_set_txn_cb(td->gnc_trans_dialog, NULL, NULL);
00118   if (td->hbci_trans)
00119     AB_Transaction_free (td->hbci_trans);
00120 
00121   if (td->dialog)
00122     gtk_widget_destroy (GTK_WIDGET (td->dialog));
00123 #if HAVE_KTOBLZCHECK_H
00124   AccountNumberCheck_delete(td->blzcheck);
00125 #endif    
00126 }
00127 
00128 static gboolean
00129 get_templ_helper (GtkTreeModel *model,
00130                   GtkTreePath *path,
00131                   GtkTreeIter *iter,
00132                   gpointer data)
00133 {
00134   GList **list = data;
00135   GNCTransTempl *templ;
00136 
00137   gtk_tree_model_get (model, iter,
00138                       TEMPLATE_POINTER, &templ,
00139                       -1);
00140   *list = g_list_append(*list, templ);
00141   return FALSE; /* continue */
00142 }
00143 
00144 GList *gnc_hbci_dialog_get_templ(const HBCITransDialog *td)
00145 {
00146   GList *list = NULL;
00147 
00148   g_assert(td);
00149   gtk_tree_model_foreach(GTK_TREE_MODEL(td->template_list_store),
00150                          get_templ_helper, &list);
00151  return list;
00152 }
00153 GtkWidget *gnc_hbci_dialog_get_parent(const HBCITransDialog *td)
00154 {
00155   g_assert(td);
00156   return td->parent;
00157 }
00158 const AB_TRANSACTION *gnc_hbci_dialog_get_htrans(const HBCITransDialog *td)
00159 {
00160   g_assert(td);
00161   return td->hbci_trans;
00162 }
00163 Transaction *gnc_hbci_dialog_get_gtrans(const HBCITransDialog *td)
00164 {
00165   g_assert(td);
00166   return td->gnc_trans;
00167 }
00168 gboolean gnc_hbci_dialog_get_templ_changed(const HBCITransDialog *td)
00169 {
00170   g_assert(td);
00171   return td->templ_changed;
00172 }
00173 void gnc_hbci_dialog_hide(HBCITransDialog *td)
00174 {
00175   g_assert(td);
00176   gtk_widget_hide_all (td->dialog);
00177 }
00178 void gnc_hbci_dialog_show(HBCITransDialog *td)
00179 {
00180   g_assert(td);
00181   gtk_widget_show_all (td->dialog);
00182 }
00183 
00184 
00185 /* -------------------------------------- */
00186 /* Prototypes; callbacks for dialog function */
00187 /* -------------------------------------- */
00188 
00189 AB_TRANSACTION *
00190 hbci_trans_fill_values(const AB_ACCOUNT *h_acc, HBCITransDialog *td);
00191 gboolean
00192 check_ktoblzcheck(GtkWidget *parent, const HBCITransDialog *td, 
00193                   const AB_TRANSACTION *trans);
00194 
00195 void on_template_list_selection_changed(GtkTreeSelection *selection, gpointer user_data);
00196 
00197 void template_selection_cb(GtkButton *b, gpointer user_data);
00198 void add_template_cb(GtkButton *b, gpointer user_data);
00199 void moveup_template_cb(GtkButton *button, gpointer user_data);
00200 void movedown_template_cb(GtkButton *button, gpointer user_data);
00201 void sort_template_cb(GtkButton *button, gpointer user_data);
00202 void del_template_cb(GtkButton *button, gpointer user_data);
00203 
00204 void blz_changed_cb(GtkEditable *e, gpointer user_data);
00205 
00206 
00207 
00208 /* -------------------------------------- */
00209 /* Main dialog function */
00210 /* -------------------------------------- */
00211 
00212 /* doesn't exist any longer */
00213 
00214 /* ************************************************************
00215  * constructor 
00216  */
00217 
00218 static void fill_template_list_func(gpointer data, gpointer user_data)
00219 {
00220   GNCTransTempl *templ = data;
00221   GtkListStore *list_store = user_data;
00222   GtkTreeIter iter;
00223   
00224   g_assert(templ);
00225   g_assert(list_store);
00226   
00227   gtk_list_store_append(list_store, &iter);
00228   gtk_list_store_set(list_store, &iter,
00229                      TEMPLATE_NAME, gnc_trans_templ_get_name(templ),
00230                      TEMPLATE_POINTER, templ,
00231                      -1);
00232 }
00233 
00234 HBCITransDialog *
00235 gnc_hbci_dialog_new (GtkWidget *parent,
00236                 const AB_ACCOUNT *h_acc,
00237                 Account *gnc_acc,
00238                 GNC_HBCI_Transtype trans_type,
00239                 GList *templates)
00240 {
00241   GladeXML *xml;
00242   const char *hbci_bankid;
00243   HBCITransDialog *td;
00244   GtkTreeSelection *selection;
00245   GtkTreeViewColumn *column;
00246   GtkCellRenderer *renderer;
00247 
00248   td = g_new0(HBCITransDialog, 1);
00249   
00250   td->parent = parent;
00251   td->trans_type = trans_type;
00252   g_assert (h_acc);
00253   hbci_bankid = AB_Account_GetBankCode(h_acc);
00254 #if HAVE_KTOBLZCHECK_H
00255   td->blzcheck = AccountNumberCheck_new();
00256 #endif
00257   
00258   xml = gnc_glade_xml_new ("hbci.glade", "HBCI_trans_dialog");
00259 
00260   td->dialog = glade_xml_get_widget (xml, "HBCI_trans_dialog");
00261 
00262   if (parent)
00263     gtk_window_set_transient_for (GTK_WINDOW (td->dialog), 
00264                                   GTK_WINDOW (parent));
00265   
00266   {
00267     gchar *hbci_bankname, *hbci_ownername;
00268     GtkWidget *heading_label;
00269     GtkWidget *recp_name_heading;
00270     GtkWidget *recp_account_heading;
00271     GtkWidget *recp_bankcode_heading;
00272     GtkWidget *amount_hbox;
00273     GtkWidget *orig_name_label;
00274     GtkWidget *orig_account_label;
00275     GtkWidget *orig_bankname_label;
00276     GtkWidget *orig_bankcode_label;
00277     GtkWidget *orig_name_heading;
00278     GtkWidget *orig_account_heading;
00279     GtkWidget *orig_bankname_heading;
00280     GtkWidget *orig_bankcode_heading;
00281     GtkWidget *exec_later_button;
00282     GtkWidget *add_templ_button;
00283     GtkWidget *moveup_templ_button;
00284     GtkWidget *movedown_templ_button;
00285     GtkWidget *sort_templ_button;
00286     GtkWidget *del_templ_button;
00287         
00288     g_assert 
00289       ((heading_label = glade_xml_get_widget (xml, "heading_label")) != NULL);
00290     g_assert 
00291       ((td->recp_name_entry = glade_xml_get_widget (xml, "recp_name_entry")) != NULL);
00292     g_assert 
00293       ((recp_name_heading = glade_xml_get_widget (xml, "recp_name_heading")) != NULL);
00294     g_assert
00295       ((td->recp_account_entry = glade_xml_get_widget (xml, "recp_account_entry")) != NULL);
00296     g_assert
00297       ((recp_account_heading = glade_xml_get_widget (xml, "recp_account_heading")) != NULL);
00298     g_assert
00299       ((td->recp_bankcode_entry = glade_xml_get_widget (xml, "recp_bankcode_entry")) != NULL);
00300     g_assert
00301       ((recp_bankcode_heading = glade_xml_get_widget (xml, "recp_bankcode_heading")) != NULL);
00302     g_assert
00303       ((td->recp_bankname_label = glade_xml_get_widget (xml, "recp_bankname_label")) != NULL);
00304     g_assert
00305       ((amount_hbox = glade_xml_get_widget (xml, "amount_hbox")) != NULL);
00306     g_assert
00307       ((td->purpose_entry = glade_xml_get_widget (xml, "purpose_entry")) != NULL);
00308     g_assert
00309       ((td->purpose_cont_entry = glade_xml_get_widget (xml, "purpose_cont_entry")) != NULL);
00310     g_assert
00311       ((td->purpose_cont2_entry = glade_xml_get_widget (xml, "purpose_cont2_entry")) != NULL);
00312     g_assert
00313       ((td->purpose_cont3_entry = glade_xml_get_widget (xml, "purpose_cont3_entry")) != NULL);
00314     g_assert
00315       ((orig_name_label = glade_xml_get_widget (xml, "orig_name_label")) != NULL);
00316     g_assert
00317       ((orig_account_label = glade_xml_get_widget (xml, "orig_account_label")) != NULL);
00318     g_assert
00319       ((orig_bankname_label = glade_xml_get_widget (xml, "orig_bankname_label")) != NULL);
00320     g_assert
00321       ((orig_bankcode_label = glade_xml_get_widget (xml, "orig_bankcode_label")) != NULL);
00322     g_assert
00323       ((orig_name_heading = glade_xml_get_widget (xml, "orig_name_heading")) != NULL);
00324     g_assert
00325       ((orig_account_heading = glade_xml_get_widget (xml, "orig_account_heading")) != NULL);
00326     g_assert
00327       ((orig_bankname_heading = glade_xml_get_widget (xml, "orig_bankname_heading")) != NULL);
00328     g_assert
00329       ((orig_bankcode_heading = glade_xml_get_widget (xml, "orig_bankcode_heading")) != NULL);
00330     g_assert
00331       ((exec_later_button = glade_xml_get_widget (xml, "exec_later_button")) != NULL);
00332     g_assert
00333       ((td->template_gtktreeview = GTK_TREE_VIEW(glade_xml_get_widget (xml, "template_list"))) != NULL);
00334     g_assert
00335       ((add_templ_button = glade_xml_get_widget (xml, "add_templ_button")) != NULL);
00336     g_assert
00337       ((moveup_templ_button = glade_xml_get_widget (xml, "moveup_templ_button")) != NULL);
00338     g_assert
00339       ((movedown_templ_button = glade_xml_get_widget (xml, "movedown_templ_button")) != NULL);
00340     g_assert
00341       ((sort_templ_button = glade_xml_get_widget (xml, "sort_templ_button")) != NULL);
00342     g_assert
00343       ((del_templ_button = glade_xml_get_widget (xml, "del_templ_button")) != NULL);
00344 
00345     td->amount_edit = gnc_amount_edit_new();
00346     gtk_box_pack_start_defaults(GTK_BOX(amount_hbox), td->amount_edit);
00347     gnc_amount_edit_set_evaluate_on_enter (GNC_AMOUNT_EDIT (td->amount_edit), 
00348       TRUE);
00349     gnc_amount_edit_set_fraction (GNC_AMOUNT_EDIT (td->amount_edit),
00350                                   xaccAccountGetCommoditySCU (gnc_acc));
00351 
00352     /* Check for what kind of transaction this should be, and change
00353        the labels accordingly. */
00354     switch (trans_type) {
00355     case SINGLE_TRANSFER:
00356     case SINGLE_INTERNAL_TRANSFER:
00357       /* all labels are already set */
00358       break;
00359     case SINGLE_DEBITNOTE:
00360       gtk_label_set_text (GTK_LABEL (heading_label), 
00361       /* Translators: Strings from this file are needed only in
00362        * countries that have one of aqbanking's Online Banking
00363        * techniques available. This is 'OFX DirectConnect'
00364        * (U.S. and others), 'HBCI' (in Germany), or 'YellowNet'
00365        * (Switzerland). If none of these techniques are available
00366        * in your country, you may safely ignore strings from the
00367        * import-export/hbci subdirectory. */
00368                           _("Enter an Online Direct Debit Note"));
00369 
00370       gtk_label_set_text (GTK_LABEL (recp_name_heading),
00371                           _("Debited Account Owner"));
00372       gtk_label_set_text (GTK_LABEL (recp_account_heading),
00373                           _("Debited Account Number"));
00374       gtk_label_set_text (GTK_LABEL (recp_bankcode_heading),
00375                           _("Debited Account Bank Code"));
00376 
00377       gtk_label_set_text (GTK_LABEL (orig_name_heading),
00378                           _("Credited Account Owner"));
00379       gtk_label_set_text (GTK_LABEL (orig_account_heading),
00380                           _("Credited Account Number"));
00381       gtk_label_set_text (GTK_LABEL (orig_bankcode_heading),
00382                           _("Credited Account Bank Code"));
00383       break;
00384 
00385     default:
00386       g_critical("dialog-hbcitrans: Oops, unknown GNC_HBCI_Transtype %d.\n",
00387              trans_type);
00388     }
00389     
00390     /* Make this button insensitive since it's still unimplemented. */
00391     gtk_widget_destroy (exec_later_button);
00392     
00393     /* aqbanking up to 2.3.0 did not guarantee the following strings
00394        to be correct utf8; mentioned in bug#351371. */
00395     hbci_bankname = 
00396       gnc_utf8_strip_invalid_strdup (AB_Account_GetBankName(h_acc));
00397     hbci_ownername = 
00398       gnc_utf8_strip_invalid_strdup (AB_Account_GetOwnerName(h_acc));
00399 
00400     /* Fill in the values from the objects */
00401     gtk_label_set_text (GTK_LABEL (orig_name_label), 
00402                         hbci_ownername);
00403     gtk_label_set_text (GTK_LABEL (orig_account_label), 
00404                         AB_Account_GetAccountNumber (h_acc));
00405     gtk_label_set_text (GTK_LABEL (orig_bankname_label), 
00406                         (hbci_bankname && (strlen(hbci_bankname)>0) ?
00407                          hbci_bankname :
00408                          _("(unknown)")));
00409     gtk_label_set_text (GTK_LABEL (orig_bankcode_label), 
00410                         hbci_bankid);
00411     g_free (hbci_ownername);
00412     g_free (hbci_bankname);
00413 
00414     /* fill list for choosing a transaction template */
00415      gtk_tree_view_set_headers_visible(td->template_gtktreeview, FALSE);
00416     td->template_list_store = gtk_list_store_new(TEMPLATE_NUM_COLUMNS,
00417                                                  G_TYPE_STRING,
00418                                                  G_TYPE_POINTER);
00419     gtk_tree_view_set_model(td->template_gtktreeview,
00420                             GTK_TREE_MODEL(td->template_list_store));
00421     g_object_unref(td->template_list_store);
00422     g_list_foreach(templates, fill_template_list_func, td->template_list_store);
00423 
00424     renderer = gtk_cell_renderer_text_new();
00425     column = gtk_tree_view_column_new_with_attributes ("Template Name",
00426                                                       renderer,
00427                                                       "text", TEMPLATE_NAME,
00428                                                       NULL);
00429     gtk_tree_view_append_column(td->template_gtktreeview, column);
00430 
00431     td->templ_changed = FALSE;
00432     
00433     /* Connect signals */
00434     selection = gtk_tree_view_get_selection(td->template_gtktreeview);
00435     g_signal_connect (selection, "changed",
00436                       G_CALLBACK (on_template_list_selection_changed),
00437                       td);
00438                       
00439     g_signal_connect (add_templ_button, "clicked",
00440                       G_CALLBACK(add_template_cb), td);
00441     g_signal_connect (moveup_templ_button, "clicked",
00442                       G_CALLBACK (moveup_template_cb),
00443                       td);
00444                       
00445     g_signal_connect (movedown_templ_button, "clicked",
00446                       G_CALLBACK (movedown_template_cb),
00447                       td);
00448 
00449      g_signal_connect (sort_templ_button, "clicked",
00450                       G_CALLBACK (sort_template_cb),
00451                       td);
00452 
00453      g_signal_connect (del_templ_button, "clicked",
00454                       G_CALLBACK (del_template_cb),
00455                       td);
00456 
00457     g_signal_connect (td->recp_bankcode_entry, "changed",
00458                       G_CALLBACK(blz_changed_cb), td);
00459 
00460   } /* GtkWidget declarations/definitions */
00461   
00462   return td;
00463 }
00464 
00465 
00466 /* ************************************************************
00467  * Now all the functions where the action happens.
00468  */
00469 
00470 int gnc_hbci_dialog_run_until_ok(HBCITransDialog *td, 
00471                                  const AB_ACCOUNT *h_acc)
00472 {
00473   gint result;
00474   int max_purpose_lines;
00475   gboolean values_ok;
00476 
00477   {
00478     AB_JOB *job = AB_JobSingleTransfer_new((AB_ACCOUNT *)h_acc);
00479     if (AB_Job_CheckAvailability(job)) {
00480       g_warning("gnc_hbci_trans_dialog_enqueue: Oops, job not available. Aborting.\n");
00481       return GTK_RESPONSE_CANCEL;
00482     }
00483     {
00484       const AB_TRANSACTION_LIMITS *joblimits = AB_JobSingleTransfer_GetFieldLimits(job);
00485       max_purpose_lines = (joblimits ?
00486                            AB_TransactionLimits_GetMaxLinesPurpose (joblimits) :
00487                            2);
00488     }
00489     /* these are the number of fields, 27 characters each. */
00490     AB_Job_free(job);
00491   }
00492   /* gtk_widget_set_sensitive (GTK_WIDGET (td->purpose_entry), max_purpose_lines > 0); */
00493   gtk_widget_set_sensitive (GTK_WIDGET (td->purpose_cont_entry), max_purpose_lines > 1);
00494   gtk_widget_set_sensitive (GTK_WIDGET (td->purpose_cont2_entry), max_purpose_lines > 2);
00495   gtk_widget_set_sensitive (GTK_WIDGET (td->purpose_cont3_entry), max_purpose_lines > 3);
00496 
00497   /* Repeat until entered values make sense */
00498   do {
00499 
00500     /* Make sure to show the dialog here */
00501     gtk_widget_show_all (td->dialog); 
00502 
00503     /* Now run the dialog until it gets closed by a button press. */
00504     result = gtk_dialog_run (GTK_DIALOG (td->dialog));
00505     /* g_message("hbci_trans: result button was %d.\n", result); */
00506 
00507     /* The dialog gets hidden anyway as soon as any button is pressed. */
00508     gtk_widget_hide_all (td->dialog);
00509 
00510     /* Was cancel pressed or dialog closed?
00511      *  GNC_RESPONSE_NOW == execute now
00512      *  GNC_RESPONSE_LATER == scheduled for later execution (currently unimplemented)
00513      *  GTK_RESPONSE_CANCEL == cancel
00514      *  GTK_RESPONSE_DELETE_EVENT == window destroyed */
00515     if ((result != GNC_RESPONSE_NOW) && (result != GNC_RESPONSE_LATER)) {
00516       gtk_widget_destroy (GTK_WIDGET (td->dialog));
00517       td->dialog = NULL;
00518       return GTK_RESPONSE_CANCEL;
00519     }
00520 
00521     /* Now fill in the values from the entry fields into a new
00522        AB_TRANSACTION. */
00523     td->hbci_trans = hbci_trans_fill_values(h_acc, td);
00524     values_ok = TRUE;
00525 
00526     /*printf("dialog-hbcitrans: Got value as %s .\n", 
00527       AB_VALUE_toReadableString (AB_TRANSACTION_value (trans)));*/
00528     if (AB_Value_GetValue (AB_Transaction_GetValue (td->hbci_trans)) == 0.0) {
00529       gtk_widget_show_all (td->dialog); 
00530       values_ok = !gnc_verify_dialog
00531         (td->dialog,
00532          TRUE,
00533          "%s",
00534          _("The amount is zero or the amount field could not be "
00535            "interpreted correctly. You might have mixed up decimal "
00536            "point and comma, compared to your locale settings. "
00537            "This does not result in a valid online transfer job. \n"
00538            "\n"
00539            "Do you want to enter the job again?"));
00540       if (values_ok) {
00541         AB_Transaction_free (td->hbci_trans);
00542         td->hbci_trans = NULL;
00543         return GTK_RESPONSE_CANCEL;
00544       }
00545       continue;
00546     } /* check Transaction_value */
00547 
00548     {
00549       char *purpose = gnc_hbci_getpurpose (td->hbci_trans);
00550       if (strlen(purpose) == 0) {
00551         gtk_widget_show_all (td->dialog); 
00552         values_ok = !gnc_verify_dialog
00553           (GTK_WIDGET (td->dialog),
00554            TRUE,
00555            "%s",
00556            _("You did not enter any transaction purpose. A purpose is "
00557              "required for an online transfer.\n"
00558              "\n"
00559              "Do you want to enter the job again?"));
00560         if (values_ok) {
00561           AB_Transaction_free (td->hbci_trans);
00562           td->hbci_trans = NULL;
00563           return GTK_RESPONSE_CANCEL;
00564         }
00565         continue;
00566       } /* check Transaction_purpose */
00567     }
00568 
00569     {
00570       char *othername = gnc_hbci_getremotename (td->hbci_trans);
00571       if (!othername || (strlen (othername) == 0)) {
00572         gtk_widget_show_all (td->dialog); 
00573         values_ok = !gnc_verify_dialog
00574           (GTK_WIDGET (td->dialog),
00575            TRUE,
00576            "%s",
00577            _("You did not enter a recipient name.  A recipient name is "
00578              "required for an online transfer.\n"
00579              "\n"
00580              "Do you want to enter the job again?"));
00581         if (othername)
00582           g_free (othername);
00583         if (values_ok) {
00584           AB_Transaction_free (td->hbci_trans);
00585           td->hbci_trans = NULL;
00586           return GTK_RESPONSE_CANCEL;
00587         }
00588         continue;
00589       } /* check Recipient Name (in aqbanking: Remote Name) */
00590     }
00591 
00592     /* FIXME: If this is a direct debit, set the textkey/ "Textschluessel"/
00593        transactionCode according to some GUI selection here!! */
00594     /*if (td->trans_type == SINGLE_DEBITNOTE)
00595       AB_TRANSACTION_setTextKey (td->hbci_trans, 05);*/
00596 
00597     /* And finally check the account code, if ktoblzcheck is available. */
00598     values_ok = check_ktoblzcheck(GTK_WIDGET (td->dialog), td, td->hbci_trans);
00599 
00600   } while (!values_ok);
00601 
00602   return result;
00603 }
00604 
00608 AB_TRANSACTION *
00609 hbci_trans_fill_values(const AB_ACCOUNT *h_acc, HBCITransDialog *td)
00610 {
00611   /* Fill in the user-entered values */
00612   AB_TRANSACTION *trans = AB_Transaction_new();
00613   gchar *tmpchar;
00614 
00615   /* The internal source encoding is returned by
00616      gnc_hbci_book_encoding(), which is hard-coded so far. This needs
00617      to be fixed for the gnome2 version; the source encoding is then
00618      probably utf-8 as well. iconv is also used in
00619      gnc_AB_BANKING_interactors() in hbci-interaction.c. */
00620   GIConv gnc_iconv_handler =
00621     g_iconv_open(gnc_hbci_AQBANKING_encoding(), gnc_hbci_book_encoding());
00622   g_assert(gnc_iconv_handler != (GIConv)(-1));
00623         
00624   /* OpenHBCI newer than 0.9.8: use account's bankCode values
00625    * instead of the bank's ones since this is what some banks
00626    * require. */
00627   AB_Transaction_SetLocalBankCode (trans, 
00628                                    AB_Account_GetBankCode (h_acc));
00629   AB_Transaction_SetLocalAccountNumber (trans, AB_Account_GetAccountNumber (h_acc));
00630   AB_Transaction_SetLocalCountry (trans, "DE");
00631         
00632   AB_Transaction_SetRemoteBankCode
00633     (trans, gtk_entry_get_text (GTK_ENTRY (td->recp_bankcode_entry)));
00634   /* g_message("Got otherBankCode %s.\n",
00635      AB_Transaction_otherBankCode (trans)); */
00636   AB_Transaction_SetRemoteAccountNumber
00637     (trans, gtk_entry_get_text (GTK_ENTRY (td->recp_account_entry)));
00638   /* g_message("Got otherAccountId %s.\n",
00639      AB_Transaction_otherAccountId (trans)); */
00640   AB_Transaction_SetRemoteCountry (trans, "DE");
00641 
00642   /* Convert the result of GTK_ENTRY into UTF-8 */
00643   tmpchar = gnc_call_iconv(gnc_iconv_handler, 
00644                            gtk_entry_get_text (GTK_ENTRY (td->recp_name_entry)));
00645   AB_Transaction_AddRemoteName (trans, tmpchar, FALSE);
00646   g_free (tmpchar);
00647         
00648   /* The last argument means: If TRUE, then the string will be only be
00649      appended if it doesn't exist yet. */
00650   /* Convert the result of GTK_ENTRY into UTF-8 */
00651   tmpchar = gnc_call_iconv(gnc_iconv_handler, 
00652                            gtk_entry_get_text (GTK_ENTRY (td->purpose_entry)));
00653   AB_Transaction_AddPurpose (trans, tmpchar, FALSE);
00654   g_free (tmpchar);
00655   tmpchar = gnc_call_iconv(gnc_iconv_handler, 
00656                            gtk_entry_get_text (GTK_ENTRY (td->purpose_cont_entry)));
00657   if (strlen(tmpchar) > 0)
00658     AB_Transaction_AddPurpose (trans, tmpchar, FALSE);
00659   g_free (tmpchar);
00660   tmpchar = gnc_call_iconv(gnc_iconv_handler, 
00661                            gtk_entry_get_text (GTK_ENTRY (td->purpose_cont2_entry)));
00662   if (strlen(tmpchar) > 0)
00663     AB_Transaction_AddPurpose (trans, tmpchar, FALSE);
00664   g_free (tmpchar);
00665   tmpchar = gnc_call_iconv(gnc_iconv_handler, 
00666                            gtk_entry_get_text (GTK_ENTRY (td->purpose_cont3_entry)));
00667   if (strlen(tmpchar) > 0)
00668     AB_Transaction_AddPurpose (trans, tmpchar, FALSE);
00669   g_free (tmpchar);
00670         
00671   /* FIXME: Replace "EUR" by account-dependent string here. */
00672   AB_Transaction_SetValue 
00673     (trans, AB_Value_new
00674      (gnc_amount_edit_get_damount (GNC_AMOUNT_EDIT (td->amount_edit)), "EUR"));
00675 
00676   /* If this is a direct debit, a textkey/ "Textschluessel"/
00677      transactionCode different from the default has to be set. */
00678   switch(td->trans_type) {
00679   case SINGLE_DEBITNOTE:
00680     /* AB_Transaction_SetTransactionCode (trans, 05); */
00681     AB_Transaction_SetTextKey (trans, 05);
00682     break;
00683   default:
00684     /* AB_Transaction_SetTransactionCode (trans, 51); */
00685     AB_Transaction_SetTextKey (trans, 51);
00686   }
00687 
00688   g_iconv_close(gnc_iconv_handler);
00689   return trans;
00690 }
00691 
00695 gboolean
00696 check_ktoblzcheck(GtkWidget *parent, const HBCITransDialog *td, 
00697                   const AB_TRANSACTION *trans)  
00698 {
00699 #if HAVE_KTOBLZCHECK_H
00700   int blzresult;
00701   const char *blztext;
00702   gboolean values_ok = TRUE;
00703   
00704   blzresult = AccountNumberCheck_check
00705     (td->blzcheck, 
00706      AB_Transaction_GetRemoteBankCode (trans),
00707      AB_Transaction_GetRemoteAccountNumber (trans));
00708   switch (blzresult) {
00709   case 2:
00710     gtk_widget_show_all (parent); 
00711     values_ok = gnc_verify_dialog
00712       (parent,
00713        TRUE,
00714        _("The internal check of the destination account number '%s' "
00715          "at the specified bank with bank code '%s' failed. This means "
00716          "the account number might contain an error. Should the online "
00717          "transfer job be sent with this account number anyway?"),
00718        AB_Transaction_GetRemoteAccountNumber (trans),
00719        AB_Transaction_GetRemoteBankCode (trans));
00720     blztext = "Kontonummer wahrscheinlich falsch";
00721     break;
00722   case 0:
00723     blztext = "Kontonummer ok";
00724     break;
00725   case 3:
00726     blztext = "bank unbekannt";
00727     break;
00728   default:
00729   case 1:
00730     blztext = "unbekannt aus unbekanntem grund";
00731     break;
00732   }
00733         
00734   /*printf("gnc_hbci_trans: KtoBlzCheck said check is %d = %s\n",
00735     blzresult, blztext);*/
00736   return values_ok;
00737 #else
00738   return TRUE;
00739 #endif    
00740 }
00741 
00742 AB_JOB *
00743 gnc_hbci_trans_dialog_enqueue(const AB_TRANSACTION *hbci_trans, AB_BANKING *api,
00744                               AB_ACCOUNT *h_acc, 
00745                               GNC_HBCI_Transtype trans_type) 
00746 {
00747   AB_JOB *job;
00748 
00749   /* Create a Do-Transaction (Transfer) job. */
00750   switch (trans_type) {
00751   case SINGLE_DEBITNOTE:
00752     job = AB_JobSingleDebitNote_new(h_acc);
00753     break;
00754   case SINGLE_INTERNAL_TRANSFER:
00755     job = AB_JobInternalTransfer_new(h_acc);
00756     break;
00757   default:
00758   case SINGLE_TRANSFER:
00759     job = AB_JobSingleTransfer_new(h_acc);
00760   };
00761   if (AB_Job_CheckAvailability(job)) {
00762     g_warning("gnc_hbci_trans_dialog_enqueue: Oops, job not available. Aborting.\n");
00763     return NULL;
00764   }
00765 
00766   switch (trans_type) {
00767   case SINGLE_DEBITNOTE:
00768     AB_JobSingleDebitNote_SetTransaction(job, hbci_trans);
00769     break;
00770   case SINGLE_INTERNAL_TRANSFER:
00771     AB_JobInternalTransfer_SetTransaction(job, hbci_trans);
00772     break;
00773   default:
00774   case SINGLE_TRANSFER:
00775     AB_JobSingleTransfer_SetTransaction(job, hbci_trans);
00776   };
00777 
00778   /* Add job to queue */
00779   AB_Banking_EnqueueJob(api, job);
00780 
00781   return job;
00782 }
00783 
00784 gboolean 
00785 gnc_hbci_trans_dialog_execute(HBCITransDialog *td, AB_BANKING *api, 
00786                               AB_JOB *job, GNCInteractor *interactor)
00787 {
00788   gboolean successful;
00789   g_assert(td);
00790   g_assert(api);
00791   g_assert(job);
00792 
00793   successful = gnc_AB_BANKING_execute (td->parent, api, job, interactor);
00794 
00795   /*printf("dialog-hbcitrans: Ok, result of api_execute was %d.\n", 
00796     successful);*/
00797           
00798   if (!successful) {
00799     /* AB_BANKING_executeOutbox failed. */
00800     if ((AB_Job_GetStatus (job) == AB_Job_StatusPending) ||
00801         (AB_Job_GetStatus (job) == AB_Job_StatusError)) 
00802       successful = !gnc_verify_dialog
00803         (td->parent, 
00804          FALSE,
00805          "%s",
00806          _("The job was sent to the bank successfully, but the "
00807            "bank is refusing to execute the job. Please check "
00808            "the log window for the exact error message of the "
00809            "bank. The line with the error message contains a "
00810            "code number that is greater than 9000.\n"
00811            "\n"
00812            "Do you want to enter the job again?"));
00813 
00814     if (AB_Job_GetStatus (job) == AB_Job_StatusPending)
00815       AB_Banking_DelPendingJob(api, job);
00816 
00817     AB_Transaction_free (td->hbci_trans);
00818     td->hbci_trans = NULL;
00819   }
00820   /* Watch out! The job *has* to be removed from the queue
00821      here because otherwise it might be executed again. */
00822   /* FIXME: need to do AB_Banking_DequeueJob(api, job); */
00823   return successful;
00824 }
00825 
00826 
00827 /* -------------------------------------- */
00828 /* Callbacks */
00829 /* -------------------------------------- */
00830 static void fill_entry(const char *str, GtkWidget *entry) { 
00831   gtk_entry_set_text (GTK_ENTRY (entry), str ? str : ""); 
00832 }
00833 
00834 
00835 void
00836 on_template_list_selection_changed (GtkTreeSelection *selection,
00837                                     gpointer          user_data)
00838 {
00839   HBCITransDialog *td = user_data;
00840   GNCTransTempl *templ;
00841   GtkTreeModel *model;
00842   GtkTreeIter iter;
00843 
00844   g_assert(td);
00845 
00846   if (!gtk_tree_selection_get_selected(selection, &model, &iter))
00847     return;
00848   gtk_tree_model_get(model, &iter, TEMPLATE_POINTER, &templ, -1);
00849 
00850       fill_entry(gnc_trans_templ_get_recp_name(templ), td->recp_name_entry);
00851       fill_entry(gnc_trans_templ_get_recp_account(templ), td->recp_account_entry);
00852       fill_entry(gnc_trans_templ_get_recp_bankcode(templ), td->recp_bankcode_entry);
00853       fill_entry(gnc_trans_templ_get_purpose(templ), td->purpose_entry);
00854       fill_entry(gnc_trans_templ_get_purpose_cont(templ), td->purpose_cont_entry);
00855 
00856       gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT (td->amount_edit),
00857                                   gnc_trans_templ_get_amount (templ));
00858 
00859 }
00860 
00861 
00862 void blz_changed_cb(GtkEditable *e, gpointer user_data)
00863 {
00864 #if HAVE_KTOBLZCHECK_H
00865   HBCITransDialog *td = user_data;
00866   const AccountNumberCheck_Record *record;
00867   g_assert(td);
00868 
00869   record = AccountNumberCheck_findBank
00870     (td->blzcheck, 
00871      gtk_entry_get_text (GTK_ENTRY (td->recp_bankcode_entry)));
00872   
00873   if (record) {
00874     const char *bankname = AccountNumberCheck_Record_bankName (record);
00875     GError *error = NULL;
00876     const char *ktoblzcheck_encoding = 
00877 #ifdef KTOBLZCHECK_VERSION_MAJOR
00878       /* This version number macro has been added in
00879          ktoblzcheck-1.10, but this function exists already since
00880          ktoblzcheck-1.7, so we're on the safe side. */
00881       AccountNumberCheck_stringEncoding()
00882 #else
00883       /* Every ktoblzcheck release before 1.10 is guaranteed to
00884          return strings only in ISO-8859-15. */
00885       "ISO-8859-15"
00886 #endif
00887       ;
00888     gchar *utf8_bankname = g_convert (bankname, strlen(bankname), 
00889                                       "UTF-8", ktoblzcheck_encoding,
00890                                       NULL, NULL, &error);
00891     if (error != NULL) {
00892       g_critical ("Error converting bankname \"%s\" to UTF-8\n", bankname);
00893       g_error_free (error);
00894       /* Conversion was erroneous, so don't use the string */
00895       utf8_bankname = g_strdup (_("(unknown)"));
00896     }
00897     gtk_label_set_text (GTK_LABEL (td->recp_bankname_label),
00898                         (strlen(utf8_bankname)>0 ? 
00899                          utf8_bankname : _("(unknown)")));
00900     g_free (utf8_bankname);
00901     gtk_widget_show_all (td->recp_bankname_label);
00902 
00903     /*printf("blz_changed_cb: KtoBlzCheck said check is bank is '%s' at '%s'.\n",
00904       bankname,
00905       AccountNumberCheck_Record_location (record));*/
00906 
00907   } else {
00908     gtk_label_set_text (GTK_LABEL (td->recp_bankname_label),
00909                         _("(unknown)"));
00910     gtk_widget_show_all (td->recp_bankname_label);
00911   }
00912 #endif    
00913 }
00914 
00915 /* -------------------------------------- */
00916 /* -------------------------------------- */
00917 
00918 void add_template_cb(GtkButton *b,
00919                      gpointer user_data)
00920 {
00921   HBCITransDialog *td = user_data;
00922   GtkWidget *dlg;
00923   const gchar *name;
00924   int retval = -1;
00925   GladeXML *xml;
00926   GtkTreeSelection *selection;
00927   GtkTreeModel *model;
00928   GtkTreeIter cur_iter, new_iter;
00929   GtkWidget *entry;
00930 
00931   g_assert(td);
00932 
00933   xml = gnc_glade_xml_new ("hbci.glade", "HBCI_template_name_dialog");
00934 
00935   dlg = glade_xml_get_widget (xml, "HBCI_template_name_dialog");
00936   entry = glade_xml_get_widget (xml, "template_name");
00937   gtk_entry_set_text(GTK_ENTRY(entry),
00938                      gtk_entry_get_text(GTK_ENTRY(td->recp_name_entry)));
00939 
00940   retval = gtk_dialog_run(GTK_DIALOG(dlg));
00941 
00942   if (retval == GTK_RESPONSE_OK) {
00943     name = gtk_entry_get_text(GTK_ENTRY(entry));
00944 
00945     if (name && (strlen(name) > 0)) {
00946       GNCTransTempl *r;
00947       /*printf("add_template_cb: adding template '%s'\n", name);*/
00948       r = gnc_trans_templ_new_full
00949         (name, 
00950          gtk_entry_get_text (GTK_ENTRY (td->recp_name_entry)),
00951          gtk_entry_get_text (GTK_ENTRY (td->recp_account_entry)),
00952          gtk_entry_get_text (GTK_ENTRY (td->recp_bankcode_entry)),
00953          gnc_amount_edit_get_amount (GNC_AMOUNT_EDIT (td->amount_edit)),
00954          gtk_entry_get_text (GTK_ENTRY (td->purpose_entry)),
00955          gtk_entry_get_text (GTK_ENTRY (td->purpose_cont_entry)));
00956 
00957       selection = gtk_tree_view_get_selection(td->template_gtktreeview);
00958       if (gtk_tree_selection_get_selected(selection, &model, &cur_iter)) {
00959         gtk_list_store_insert_after(td->template_list_store,
00960                                     &new_iter, &cur_iter);
00961       } else {
00962         gtk_list_store_append(GTK_LIST_STORE(model), &new_iter);
00963       }
00964       gtk_list_store_set(td->template_list_store, &new_iter,
00965                          TEMPLATE_NAME, name,
00966                          TEMPLATE_POINTER, r,
00967                          -1);
00968       td->templ_changed = TRUE;
00969     }
00970   }
00971   gtk_widget_destroy(dlg);
00972   //  g_object_unref(xml);
00973 }
00974 
00975 
00976 void
00977 moveup_template_cb(GtkButton       *button,
00978                   gpointer         user_data)
00979 {
00980   HBCITransDialog *td = user_data;
00981   GtkTreeSelection *selection;
00982   GtkTreeModel *model;
00983   GtkTreeIter iter, prev_iter;
00984   GtkTreePath *prev_path;
00985 
00986   g_assert(td);
00987 
00988   selection = gtk_tree_view_get_selection(td->template_gtktreeview);
00989   if (!gtk_tree_selection_get_selected (selection, &model, &iter))
00990     return;
00991 
00992   prev_path = gtk_tree_model_get_path(model, &iter);
00993   if (gtk_tree_path_prev(prev_path)) {
00994     if (gtk_tree_model_get_iter(model, &prev_iter, prev_path)) {
00995       gtk_list_store_move_before(GTK_LIST_STORE(model), &iter, &prev_iter);
00996       td->templ_changed = TRUE;
00997     }
00998   }
00999 
01000   gtk_tree_path_free(prev_path);
01001 }
01002 
01003 
01004 void
01005 movedown_template_cb(GtkButton       *button,
01006                     gpointer         user_data)
01007 {
01008   HBCITransDialog *td = user_data;
01009   GtkTreeSelection *selection;
01010   GtkTreeModel *model;
01011   GtkTreeIter iter, next_iter;
01012 
01013   g_assert(td);
01014 
01015   selection = gtk_tree_view_get_selection(td->template_gtktreeview);
01016   if (!gtk_tree_selection_get_selected (selection, &model, &iter))
01017     return;
01018 
01019   next_iter = iter;
01020   if (gtk_tree_model_iter_next(model, &next_iter)) {
01021     gtk_list_store_move_after(GTK_LIST_STORE(model), &iter, &next_iter);
01022     td->templ_changed = TRUE;
01023   }
01024 }
01025 
01026 void
01027 sort_template_cb(GtkButton       *button,
01028                  gpointer         user_data)
01029 {
01030   HBCITransDialog *td = user_data;
01031   g_assert(td);
01032 
01033   gtk_tree_sortable_set_sort_column_id
01034     (GTK_TREE_SORTABLE(td->template_list_store),
01035      TEMPLATE_NAME, GTK_SORT_ASCENDING);
01036   gtk_tree_sortable_set_sort_column_id
01037     (GTK_TREE_SORTABLE(td->template_list_store),
01038      GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID,
01039      GTK_SORT_ASCENDING);
01040   td->templ_changed = TRUE;
01041 }
01042 
01043 
01044 
01045 void
01046 del_template_cb(GtkButton       *button,
01047                gpointer         user_data)
01048 {
01049   HBCITransDialog *td = user_data;
01050   GtkTreeSelection *selection;
01051   GtkTreeModel *model;
01052   GtkTreeIter iter;
01053 
01054   g_assert(td);
01055 
01056   selection = gtk_tree_view_get_selection(td->template_gtktreeview);
01057   if (!gtk_tree_selection_get_selected (selection, &model, &iter))
01058     return;
01059 
01060   gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
01061   td->templ_changed = TRUE;
01062 }
01063 
01064 
01065 
01066 void gnc_hbci_dialog_xfer_cb(Transaction *trans, gpointer user_data)
01067 {
01068   HBCITransDialog *td = user_data;
01069   g_assert(td);
01070   if (trans) {
01071     td->gnc_trans = trans;
01072     /* Unregister handler for transaction creation callback */
01073     if (td->gnc_trans_dialog)
01074       gnc_xfer_dialog_set_txn_cb(td->gnc_trans_dialog, NULL, NULL);
01075     td->gnc_trans_dialog = NULL;
01076   }
01077   else {
01078     if (td->gnc_trans_dialog) {
01079       gnc_xfer_dialog_set_txn_cb(td->gnc_trans_dialog, NULL, NULL);
01080       td->gnc_trans_dialog = NULL;
01081     }
01082   }
01083   return;
01084 }

Generated on Mon Sep 8 05:03:47 2008 for GnuCash by  doxygen 1.5.2