GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gnc-ab-transfer.c
1 /*
2  * gnc-ab-transfer.c --
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, contact:
16  *
17  * Free Software Foundation Voice: +1-617-542-5942
18  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
19  * Boston, MA 02110-1301, USA [email protected]
20  */
21 
32 #include "config.h"
33 
34 #include <glib/gi18n.h>
35 #include <gtk/gtk.h>
36 #include <aqbanking/banking.h>
37 
38 #include "Transaction.h"
39 #include "dialog-transfer.h"
40 #include "gnc-ab-transfer.h"
41 #include "gnc-ab-kvp.h"
42 #include "gnc-ab-utils.h"
43 #include "gnc-ab-trans-templ.h"
44 #include "gnc-gwen-gui.h"
45 #include "gnc-ui.h"
46 
47 /* This static indicates the debugging module that this .o belongs to. */
48 G_GNUC_UNUSED static QofLogModule log_module = G_LOG_DOMAIN;
49 
50 static void save_templates(GtkWidget *parent, Account *gnc_acc, GList *templates,
51  gboolean dont_ask);
52 static void txn_created_cb(Transaction *trans, gpointer user_data);
53 
54 static void
55 save_templates(GtkWidget *parent, Account *gnc_acc, GList *templates,
56  gboolean dont_ask)
57 {
58  g_return_if_fail(gnc_acc);
59  if (dont_ask || gnc_verify_dialog(
60  parent, FALSE, "%s",
61  _("You have changed the list of online transfer templates, "
62  "but you cancelled the transfer dialog. "
63  "Do you nevertheless want to store the changes?")))
64  {
65  GList *kvp_list = gnc_ab_trans_templ_list_to_kvp_list(templates);
66  gnc_ab_set_book_template_list(gnc_account_get_book(gnc_acc), kvp_list);
67  }
68 }
69 
70 static void
71 txn_created_cb(Transaction *trans, gpointer user_data)
72 {
73  Transaction **trans_loc = user_data;
74 
75  if (!trans) return;
76  g_return_if_fail(trans_loc);
77  *trans_loc = trans;
78 }
79 
80 void
81 gnc_ab_maketrans(GtkWidget *parent, Account *gnc_acc,
82  GncABTransType trans_type)
83 {
84  AB_BANKING *api;
85  gboolean online = FALSE;
86  AB_ACCOUNT *ab_acc;
87  GList *templates = NULL;
88  GncABTransDialog *td = NULL;
89  gboolean successful = FALSE;
90  gboolean aborted = FALSE;
91 
92  g_return_if_fail(parent && gnc_acc);
93 
94  /* Get the API */
95  api = gnc_AB_BANKING_new();
96  if (!api)
97  {
98  g_warning("gnc_ab_maketrans: Couldn't get AqBanking API");
99  return;
100  }
101  if (AB_Banking_OnlineInit(api
102 #ifdef AQBANKING_VERSION_4_EXACTLY
103  , 0
104 #endif
105  ) != 0)
106  {
107  g_warning("gnc_ab_maketrans: Couldn't initialize AqBanking API");
108  goto cleanup;
109  }
110  online = TRUE;
111 
112  /* Get the AqBanking Account */
113  ab_acc = gnc_ab_get_ab_account(api, gnc_acc);
114  if (!ab_acc)
115  {
116  g_warning("gnc_ab_gettrans: No AqBanking account found");
117  gnc_error_dialog(parent, _("No valid online banking account assigned."));
118  goto cleanup;
119  }
120 
121  /* Get list of template transactions */
123  gnc_ab_get_book_template_list(gnc_account_get_book(gnc_acc)));
124 
125  /* Create new ABTransDialog */
126  td = gnc_ab_trans_dialog_new(parent, ab_acc,
128  trans_type, templates);
129  templates = NULL;
130 
131  /* Repeat until AqBanking action was successful or user pressed cancel */
132  do
133  {
134  GncGWENGui *gui = NULL;
135  gint result;
136  gboolean changed;
137  const AB_TRANSACTION *ab_trans;
138  AB_JOB *job = NULL;
139  AB_JOB_LIST2 *job_list = NULL;
140  XferDialog *xfer_dialog = NULL;
141  gnc_numeric amount;
142  gchar *description;
143  gchar *memo;
144  Transaction *gnc_trans = NULL;
145  AB_IMEXPORTER_CONTEXT *context = NULL;
146  AB_JOB_STATUS job_status;
147  GncABImExContextImport *ieci = NULL;
148 
149  /* Get a GUI object */
150  gui = gnc_GWEN_Gui_get(parent);
151  if (!gui)
152  {
153  g_warning("gnc_ab_maketrans: Couldn't initialize Gwenhywfar GUI");
154  aborted = TRUE;
155  goto repeat;
156  }
157 
158  /* Let the user enter the values */
160 
161  /* Save the templates */
162  templates = gnc_ab_trans_dialog_get_templ(td, &changed);
163  if (changed)
164  save_templates(parent, gnc_acc, templates,
165  (result == GNC_RESPONSE_NOW));
166  g_list_free(templates);
167  templates = NULL;
168 
169  if (result != GNC_RESPONSE_NOW && result != GNC_RESPONSE_LATER)
170  {
171  aborted = TRUE;
172  goto repeat;
173  }
174 
175  /* Get a job and enqueue it */
176  ab_trans = gnc_ab_trans_dialog_get_ab_trans(td);
177  job = gnc_ab_trans_dialog_get_job(td);
178  if (!job || AB_Job_CheckAvailability(job
179 #ifndef AQBANKING_VERSION_5_PLUS
180  , 0
181 #endif
182  ))
183  {
184  if (!gnc_verify_dialog(
185  parent, FALSE, "%s",
186  _("The backend found an error during the preparation "
187  "of the job. It is not possible to execute this job. \n"
188  "\n"
189  "Most probable the bank does not support your chosen "
190  "job or your Online Banking account does not have the permission "
191  "to execute this job. More error messages might be "
192  "visible on your console log.\n"
193  "\n"
194  "Do you want to enter the job again?")))
195  aborted = TRUE;
196  goto repeat;
197  }
198  job_list = AB_Job_List2_new();
199  AB_Job_List2_PushBack(job_list, job);
200 
201  /* Setup a Transfer Dialog for the GnuCash transaction */
202  xfer_dialog = gnc_xfer_dialog(gnc_ab_trans_dialog_get_parent(td),
203  gnc_acc);
204  switch (trans_type)
205  {
206  case SINGLE_DEBITNOTE:
207  gnc_xfer_dialog_set_title(
208  xfer_dialog, _("Online Banking Direct Debit Note"));
209  gnc_xfer_dialog_lock_to_account_tree(xfer_dialog);
210  break;
211  case SINGLE_INTERNAL_TRANSFER:
212  gnc_xfer_dialog_set_title(
213  xfer_dialog, _("Online Banking Bank-Internal Transfer"));
214  gnc_xfer_dialog_lock_from_account_tree(xfer_dialog);
215  break;
216  case SEPA_TRANSFER:
217  gnc_xfer_dialog_set_title(
218  xfer_dialog, _("Online Banking European (SEPA) Transfer"));
219  gnc_xfer_dialog_lock_from_account_tree(xfer_dialog);
220  break;
221  case SEPA_DEBITNOTE:
222  gnc_xfer_dialog_set_title(
223  xfer_dialog, _("Online Banking European (SEPA) Debit Note"));
224  gnc_xfer_dialog_lock_to_account_tree(xfer_dialog);
225  break;
226  case SINGLE_TRANSFER:
227  default:
228  gnc_xfer_dialog_set_title(
229  xfer_dialog, _("Online Banking Transaction"));
230  gnc_xfer_dialog_lock_from_account_tree(xfer_dialog);
231  }
232  gnc_xfer_dialog_set_to_show_button_active(xfer_dialog, TRUE);
233 
234  amount = double_to_gnc_numeric(
235  AB_Value_GetValueAsDouble(AB_Transaction_GetValue(ab_trans)),
238  gnc_xfer_dialog_set_amount(xfer_dialog, amount);
239  gnc_xfer_dialog_set_amount_sensitive(xfer_dialog, FALSE);
240  gnc_xfer_dialog_set_date_sensitive(xfer_dialog, FALSE);
241 
242  description = gnc_ab_description_to_gnc(ab_trans);
243  gnc_xfer_dialog_set_description(xfer_dialog, description);
244  g_free(description);
245 
246  memo = gnc_ab_memo_to_gnc(ab_trans);
247  gnc_xfer_dialog_set_memo(xfer_dialog, memo);
248  g_free(memo);
249 
250  gnc_xfer_dialog_set_txn_cb(xfer_dialog, txn_created_cb, &gnc_trans);
251 
252  /* And run it */
253  successful = gnc_xfer_dialog_run_until_done(xfer_dialog);
254 
255  /* On cancel, go back to the AB transaction dialog */
256  if (!successful || !gnc_trans)
257  {
258  successful = FALSE;
259  goto repeat;
260  }
261 
262  if (result == GNC_RESPONSE_NOW)
263  {
264  /* Create a context to store possible results */
265  context = AB_ImExporterContext_new();
266 
267  gui = gnc_GWEN_Gui_get(parent);
268  if (!gui)
269  {
270  g_warning("gnc_ab_maketrans: Couldn't initialize Gwenhywfar GUI");
271  aborted = TRUE;
272  goto repeat;
273  }
274 
275  /* Finally, execute the job */
276  AB_Banking_ExecuteJobs(api, job_list, context
277 #ifndef AQBANKING_VERSION_5_PLUS
278  , 0
279 #endif
280  );
281 
282  /* Ignore the return value of AB_Banking_ExecuteJobs(), as the job's
283  * status always describes better whether the job was actually
284  * transferred to and accepted by the bank. See also
285  * http://lists.gnucash.org/pipermail/gnucash-de/2008-September/006389.html
286  */
287  job_status = AB_Job_GetStatus(job);
288  if (job_status != AB_Job_StatusFinished
289  && job_status != AB_Job_StatusPending)
290  {
291  successful = FALSE;
292  if (!gnc_verify_dialog(
293  parent, FALSE, "%s",
294  _("An error occurred while executing the job. Please check "
295  "the log window for the exact error message.\n"
296  "\n"
297  "Do you want to enter the job again?")))
298  {
299  aborted = TRUE;
300  }
301  }
302  else
303  {
304  successful = TRUE;
305  }
306 
307  if (successful)
308  {
309  /* Import the results, awaiting nothing */
310  ieci = gnc_ab_import_context(context, 0, FALSE, NULL, parent);
311  }
312  }
313  /* Simply ignore any other case */
314 
315 repeat:
316  /* Clean up */
317  if (gnc_trans && !successful)
318  {
319  xaccTransBeginEdit(gnc_trans);
320  xaccTransDestroy(gnc_trans);
321  xaccTransCommitEdit(gnc_trans);
322  gnc_trans = NULL;
323  }
324  if (ieci)
325  g_free(ieci);
326  if (context)
327  AB_ImExporterContext_free(context);
328  if (job_list)
329  {
330  AB_Job_List2_free(job_list);
331  job_list = NULL;
332  }
333  if (job)
334  {
335  AB_Job_free(job);
336  job = NULL;
337  }
338  if (gui)
339  {
341  gui = NULL;
342  }
343 
344  }
345  while (!successful && !aborted);
346 
347 cleanup:
348  if (td)
350  if (online)
351 #ifdef AQBANKING_VERSION_4_EXACTLY
352  AB_Banking_OnlineFini(api, 0);
353 #else
354  AB_Banking_OnlineFini(api);
355 #endif
356  gnc_AB_BANKING_fini(api);
357 }
GncABTransDialog * gnc_ab_trans_dialog_new(GtkWidget *parent, AB_ACCOUNT *ab_acc, gint commodity_scu, GncABTransType trans_type, GList *templates)
Templates for AqBanking transactions.
gnc_numeric double_to_gnc_numeric(double n, gint64 denom, gint how)
#define G_LOG_DOMAIN
Functions providing the SX List as a plugin page.
int xaccAccountGetCommoditySCU(const Account *acc)
Definition: Account.c:2458
gchar * gnc_ab_description_to_gnc(const AB_TRANSACTION *ab_trans)
Definition: gnc-ab-utils.c:383
gchar * gnc_ab_memo_to_gnc(const AB_TRANSACTION *ab_trans)
Definition: gnc-ab-utils.c:419
AB_JOB * gnc_ab_trans_dialog_get_job(const GncABTransDialog *td)
GncGWENGui * gnc_GWEN_Gui_get(GtkWidget *parent)
Definition: gnc-gwen-gui.c:311
void xaccTransDestroy(Transaction *trans)
Definition: Transaction.c:1402
GList * gnc_ab_trans_templ_list_to_kvp_list(GList *k)
Dialog for AqBanking transaction data.
void gnc_GWEN_Gui_release(GncGWENGui *gui)
Definition: gnc-gwen-gui.c:346
GList * gnc_ab_trans_dialog_get_templ(const GncABTransDialog *td, gboolean *changed)
AB_BANKING * gnc_AB_BANKING_new(void)
Definition: gnc-ab-utils.c:137
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
void gnc_ab_set_book_template_list(QofBook *b, GList *template_list)
Definition: gnc-ab-kvp.c:138
gint gnc_AB_BANKING_fini(AB_BANKING *api)
Definition: gnc-ab-utils.c:237
AB_ACCOUNT * gnc_ab_get_ab_account(const AB_BANKING *api, Account *gnc_acc)
Definition: gnc-ab-utils.c:264
GncABImExContextImport * gnc_ab_import_context(AB_IMEXPORTER_CONTEXT *context, guint awaiting, gboolean execute_txns, AB_BANKING *api, GtkWidget *parent)
void gnc_ab_trans_dialog_free(GncABTransDialog *td)
const AB_TRANSACTION * gnc_ab_trans_dialog_get_ab_trans(const GncABTransDialog *td)
GList * gnc_ab_trans_templ_list_new_from_kvp_list(GList *v)
GtkWidget * gnc_ab_trans_dialog_get_parent(const GncABTransDialog *td)
AqBanking KVP handling.
GUI callbacks for AqBanking.
GList * gnc_ab_get_book_template_list(QofBook *b)
Definition: gnc-ab-kvp.c:130
API for Transactions and Splits (journal entries)
gint gnc_ab_trans_dialog_run_until_ok(GncABTransDialog *td)
AqBanking utility functions.
const gchar * QofLogModule
Definition: qofid.h:89
void gnc_ab_maketrans(GtkWidget *parent, Account *gnc_acc, GncABTransType trans_type)