34 #include <glib/gi18n.h> 35 #include <gwenhywfar/gwenhywfar.h> 36 #include <aqbanking/banking.h> 37 #include <aqbanking/types/balance.h> 38 #if (AQBANKING_VERSION_INT >= 60400) 39 #include <aqbanking/types/refaccount.h> 40 #include <gnc-aqbanking-templates.h> 42 #include "window-reconcile.h" 54 #include "engine-helpers.h" 55 #include <aqbanking/gui/abgui.h> 58 G_GNUC_UNUSED
static QofLogModule log_module =
G_LOG_DOMAIN;
61 static AB_BANKING *gnc_AB_BANKING = NULL;
62 static gint gnc_AB_BANKING_refcount = 0;
64 static gpointer join_ab_strings_cb (
const gchar *str, gpointer user_data);
65 static Account *gnc_ab_accinfo_to_gnc_acc (GtkWidget *parent,
66 AB_IMEXPORTER_ACCOUNTINFO *account_info);
67 static Account *gnc_ab_txn_to_gnc_acc (GtkWidget *parent,
68 const AB_TRANSACTION *transaction);
69 static const AB_TRANSACTION *txn_transaction_cb (
const AB_TRANSACTION *element,
71 static AB_IMEXPORTER_ACCOUNTINFO *txn_accountinfo_cb (AB_IMEXPORTER_ACCOUNTINFO *element,
73 static AB_IMEXPORTER_ACCOUNTINFO *bal_accountinfo_cb (AB_IMEXPORTER_ACCOUNTINFO *element,
81 GNC_AB_ACCOUNT_SPEC *ab_acc;
82 gboolean execute_txns;
85 GNC_AB_JOB_LIST2 *job_list;
86 GNCImportMainMatcher *generic_importer;
90 static inline gboolean is_leap_year (
int year)
92 return (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0 ));
96 gnc_gwen_date_to_time64 (
const GNC_GWEN_DATE* date)
98 int day = GWEN_Date_GetDay (date);
99 int month = GWEN_Date_GetMonth (date);
100 int year = GWEN_Date_GetYear (date);
107 while (month == 2 && day <= 30 && day > (is_leap_year (year) ? 29 : 28))
115 gchar* gwen_logging = g_strdup (g_getenv (
"GWEN_LOGLEVEL"));
116 gchar* aqb_logging = g_strdup (g_getenv (
"AQBANKING_LOGLEVEL"));
126 GWEN_Logger_SetLevel (NULL, GWEN_LoggerLevel_Info);
127 GWEN_Logger_SetLevel (GWEN_LOGDOMAIN, GWEN_LoggerLevel_Info);
130 GWEN_Logger_SetLevel (AQBANKING_LOGDOMAIN, GWEN_LoggerLevel_Debug);
136 GWEN_Logger_SetLevel (NULL, GWEN_LoggerLevel_Error);
137 GWEN_Logger_SetLevel (GWEN_LOGDOMAIN, GWEN_LoggerLevel_Error);
140 GWEN_Logger_SetLevel (AQBANKING_LOGDOMAIN, GWEN_LoggerLevel_Warning);
142 g_free (gwen_logging);
143 g_free (aqb_logging);
152 GWEN_Logger_SetLevel (NULL, GWEN_LoggerLevel_Error);
153 GWEN_Logger_SetLevel (GWEN_LOGDOMAIN, GWEN_LoggerLevel_Warning);
154 GWEN_Logger_SetLevel (AQBANKING_LOGDOMAIN, GWEN_LoggerLevel_Warning);
160 static GWEN_GUI *gnc_gwengui_extended_by_ABBanking;
170 api = gnc_AB_BANKING;
173 if (gnc_AB_BANKING_refcount == 0)
174 g_return_val_if_fail (AB_Banking_Init (api) == 0, NULL);
179 api = AB_Banking_new (PROJECT_NAME, NULL, 0);
180 g_return_val_if_fail (api, NULL);
188 AB_Banking_RuntimeConfig_SetCharValue (api,
"fintsRegistrationKey",
"412748A1836CDD07181CE1910");
189 AB_Banking_RuntimeConfig_SetCharValue (api,
"fintsApplicationVersionString", PROJECT_VERSION);
192 g_return_val_if_fail (AB_Banking_Init (api) == 0, NULL);
193 gnc_gwengui_extended_by_ABBanking = GWEN_Gui_GetGui ();
194 AB_Gui_Extend (gnc_gwengui_extended_by_ABBanking, api);
197 gnc_AB_BANKING = api;
198 gnc_AB_BANKING_refcount = 0;
201 gnc_AB_BANKING_refcount++;
210 api = gnc_AB_BANKING;
214 if (api == gnc_AB_BANKING)
216 gnc_AB_BANKING = NULL;
220 AB_Banking_free (api);
228 if (api == gnc_AB_BANKING)
230 if (--gnc_AB_BANKING_refcount == 0)
232 if (gnc_gwengui_extended_by_ABBanking)
233 AB_Gui_Unextend (gnc_gwengui_extended_by_ABBanking);
234 gnc_gwengui_extended_by_ABBanking = NULL;
235 return AB_Banking_Fini (api);
240 if (gnc_gwengui_extended_by_ABBanking)
241 AB_Gui_Unextend (gnc_gwengui_extended_by_ABBanking);
242 gnc_gwengui_extended_by_ABBanking = NULL;
243 return AB_Banking_Fini (api);
248 GNC_AB_ACCOUNT_SPEC *
251 GNC_AB_ACCOUNT_SPEC *ab_account = NULL;
252 const gchar *bankcode = NULL;
253 const gchar *accountid = NULL;
254 guint32 account_uid = 0;
264 rv = AB_Banking_GetAccountSpecByUniqueId (api, account_uid, &ab_account);
266 if ( (rv<0 || !ab_account) && bankcode && *bankcode &&
267 accountid && *accountid)
272 PINFO(
"gnc_ab_get_ab_account: No AB_ACCOUNT found for UID %d, " 273 "trying bank code\n", account_uid);
286 return g_strdup_printf (
"%.2f %s",
287 AB_Value_GetValueAsDouble (value),
288 AB_Value_GetCurrency (value));
290 return g_strdup_printf (
"%.2f", 0.0);
305 while (accountnumber && *accountnumber ==
'0')
308 online_id = g_strconcat (bankcode ? bankcode :
"",
309 accountnumber ? accountnumber :
"",
320 join_ab_strings_cb (
const gchar *str, gpointer user_data)
322 gchar **acc = user_data;
328 tmp = g_utf8_normalize (str, -1, G_NORMALIZE_NFC);
334 if (!strstr (*acc, tmp))
336 gchar *join = g_strjoin (
" ", *acc, tmp, (gchar*) NULL);
352 const char* ab_remote_name;
353 gchar *gnc_other_name = NULL;
355 g_return_val_if_fail (ab_trans, NULL);
357 ab_remote_name = AB_Transaction_GetRemoteName (ab_trans);
359 gnc_other_name = g_strdup(ab_remote_name);
360 if (!gnc_other_name || !*gnc_other_name)
362 g_free (gnc_other_name);
363 gnc_other_name = NULL;
366 return gnc_other_name;
372 GWEN_STRINGLIST *ab_purpose;
373 const char *ab_transactionText = NULL;
374 gchar *gnc_description = NULL;
376 g_return_val_if_fail (ab_trans, g_strdup (
""));
378 if (!is_ofx &&
gnc_prefs_get_bool (GNC_PREFS_GROUP_AQBANKING, GNC_PREF_USE_TRANSACTION_TXT))
383 ab_transactionText = AB_Transaction_GetTransactionText (ab_trans);
384 if (ab_transactionText && *ab_transactionText)
385 gnc_description = g_utf8_normalize (ab_transactionText, -1, G_NORMALIZE_NFC);
388 ab_purpose = AB_Transaction_GetPurposeAsStringList (ab_trans);
390 GWEN_StringList_ForEach (ab_purpose, join_ab_strings_cb,
393 GWEN_StringList_free (ab_purpose);
395 return gnc_description;
405 ab_ultimate_creditor_debtor_to_gnc (
const AB_TRANSACTION *ab_trans,
408 const gchar* ultimate;
413 ultimate = AB_Transaction_GetUltimateCreditor (ab_trans);
415 if (!ultimate || !*ultimate)
416 ultimate = AB_Transaction_GetUltimateDebtor (ab_trans);
418 if (!ultimate || !*ultimate)
421 return g_strdup (ultimate);
432 acc = g_list_prepend (acc, ab_ultimate_creditor_debtor_to_gnc (ab_trans, is_ofx));
435 g_list_free_full (acc, g_free);
436 return retval ? retval : g_strdup (_(
"Unspecified"));
442 const gchar *ab_remote_accountnumber =
443 AB_Transaction_GetRemoteAccountNumber (ab_trans);
444 const gchar *ab_remote_bankcode =
445 AB_Transaction_GetRemoteBankCode (ab_trans);
447 gchar *ab_other_accountid;
448 gchar *ab_other_bankcode;
450 gboolean have_accountid;
451 gboolean have_bankcode;
456 if (!ab_remote_accountnumber)
457 ab_remote_accountnumber = AB_Transaction_GetRemoteIban (ab_trans);
458 if (!ab_remote_bankcode)
459 ab_remote_bankcode = AB_Transaction_GetRemoteBic (ab_trans);
461 ab_other_accountid = g_strdup (ab_remote_accountnumber ? ab_remote_accountnumber :
"");
462 ab_other_bankcode = g_strdup (ab_remote_bankcode ? ab_remote_bankcode :
"");
469 g_strstrip (ab_other_accountid);
470 g_strstrip (ab_other_bankcode);
473 have_accountid = ab_other_accountid && *ab_other_accountid;
474 have_bankcode = ab_other_bankcode && *ab_other_bankcode;
476 if ( have_accountid || have_bankcode )
478 retval = g_strdup_printf (
"%s %s %s %s",
479 have_accountid ? _(
"Account") :
"",
480 have_accountid ? ab_other_accountid :
"",
481 have_bankcode ? _(
"Bank") :
"",
482 have_bankcode ? ab_other_bankcode :
"" 488 retval = g_strdup (
"");
491 g_free (ab_other_accountid);
492 g_free (ab_other_bankcode);
501 Transaction *gnc_trans;
503 const GNC_GWEN_DATE *value_date, *post_date;
510 g_return_val_if_fail (ab_trans && gnc_acc, NULL);
513 book = gnc_account_get_book (gnc_acc);
528 value_date = AB_Transaction_GetValutaDate (ab_trans);
530 post_time = gnc_gwen_date_to_time64 (value_date);
531 else if ((post_date = AB_Transaction_GetDate (ab_trans)))
532 post_time = gnc_gwen_date_to_time64 (post_date);
535 g_warning (
"transaction_cb: Import had no transaction date");
548 fitid = AB_Transaction_GetFiId (ab_trans);
553 g_free (description);
561 xaccSplitSetParent (split, gnc_trans);
562 xaccSplitSetAccount (split, gnc_acc);
566 custref = AB_Transaction_GetCustomerReference (ab_trans);
567 if (custref && *custref && g_ascii_strncasecmp (custref,
"NONREF", 6) != 0)
568 gnc_set_num_action (gnc_trans, split, custref, NULL);
572 gnc_import_set_split_online_id (split, fitid);
577 const AB_VALUE *ab_value = AB_Transaction_GetValue (ab_trans);
578 double d_value = ab_value ? AB_Value_GetValueAsDouble (ab_value) : 0.0;
579 AB_TRANSACTION_TYPE ab_type = AB_Transaction_GetType (ab_trans);
580 gnc_numeric gnc_amount;
586 if (d_value > 0.0 && ab_type == AB_Transaction_TypeTransfer)
594 g_warning (
"transaction_cb: Oops, value was NULL. Using 0");
615 gnc_ab_accinfo_to_gnc_acc (GtkWidget *parent, AB_IMEXPORTER_ACCOUNTINFO *acc_info)
617 const gchar *bankcode, *accountnumber;
621 g_return_val_if_fail (acc_info, NULL);
623 bankcode = AB_ImExporterAccountInfo_GetBankCode (acc_info);
624 accountnumber = AB_ImExporterAccountInfo_GetAccountNumber (acc_info);
627 AB_ImExporterAccountInfo_GetAccountName (acc_info),
631 g_warning (
"gnc_ab_accinfo_to_gnc_acc: Could not determine source account" 632 " for online_id %s", online_id);
649 gnc_ab_txn_to_gnc_acc (GtkWidget *parent,
const AB_TRANSACTION *transaction)
651 const gchar *bankcode, *accountnumber;
655 g_return_val_if_fail(transaction, NULL);
657 bankcode = AB_Transaction_GetLocalBankCode (transaction);
658 accountnumber = AB_Transaction_GetLocalAccountNumber (transaction);
659 if (!bankcode && !accountnumber)
666 AB_Transaction_GetLocalName (transaction),
670 g_warning (
"gnc_ab_txn_to_gnc_acc: Could not determine source account" 671 " for online_id %s", online_id);
678 static const AB_TRANSACTION *
679 txn_transaction_cb (
const AB_TRANSACTION *element, gpointer user_data)
681 GncABImExContextImport *data = user_data;
682 Transaction *gnc_trans;
683 GncABTransType trans_type;
686 g_return_val_if_fail (element && data, NULL);
689 txnacc = gnc_ab_txn_to_gnc_acc (GTK_WIDGET(data->parent), element);
692 if (data->execute_txns && data->ab_acc)
694 AB_TRANSACTION *ab_trans = AB_Transaction_dup (element);
699 AB_Transaction_SetLocalBankCode (
700 ab_trans, AB_AccountSpec_GetBankCode (data->ab_acc));
701 AB_Transaction_SetLocalAccountNumber (
702 ab_trans, AB_AccountSpec_GetAccountNumber (data->ab_acc));
703 AB_Transaction_SetLocalCountry (ab_trans,
"DE");
706 switch (AB_Transaction_GetType (ab_trans))
708 case AB_Transaction_TypeDebitNote:
709 trans_type = SINGLE_DEBITNOTE;
711 case AB_Transaction_TypeTransaction:
714 case AB_Transaction_TypeTransfer:
716 trans_type = SEPA_TRANSFER;
723 if (!job || AB_AccountSpec_GetTransactionLimitsForCommand (data->ab_acc, AB_Transaction_GetCommand (job)) == NULL)
726 if (gnc_verify_dialog (
727 GTK_WINDOW(data->parent), FALSE,
"%s",
728 _(
"The backend found an error during the preparation " 729 "of the job. It is not possible to execute this job.\n" 731 "Most probably the bank does not support your chosen " 732 "job or your Online Banking account does not have the permission " 733 "to execute this job. More error messages might be " 734 "visible on your console log.\n" 736 "Do you want to enter the job again?")))
738 gnc_error_dialog (GTK_WINDOW(data->parent),
739 "Sorry, not implemented yet. Please check the console or trace file logs to see which job was rejected.");
746 AB_Transaction_GetUniqueId (job));
750 AB_Transaction_free (ab_trans);
761 static void gnc_ab_trans_processed_cb (GNCImportTransInfo *trans_info,
765 GncABImExContextImport *data = user_data;
767 GNC_AB_JOB *job = g_datalist_get_data (&data->tmp_job_list, jobname);
771 AB_Transaction_List2_PushBack (data->job_list, job);
775 AB_Transaction_free (job);
778 g_datalist_remove_data (&data->tmp_job_list, jobname);
796 return g_strdup_printf (
"job_%lu", job_id);
801 static AB_IMEXPORTER_ACCOUNTINFO *
802 txn_accountinfo_cb (AB_IMEXPORTER_ACCOUNTINFO *element, gpointer user_data)
804 GncABImExContextImport *data = user_data;
807 g_return_val_if_fail (element && data, NULL);
809 if (data->awaiting & IGNORE_TRANSACTIONS)
813 if (!AB_ImExporterAccountInfo_GetFirstTransaction (element, AB_Transaction_TypeStatement, 0))
817 data->awaiting |= FOUND_TRANSACTIONS;
819 if (!(data->awaiting & AWAIT_TRANSACTIONS))
821 if (gnc_verify_dialog (GTK_WINDOW(data->parent), TRUE,
"%s",
822 _(
"The bank has sent transaction information " 825 "Do you want to import it?")))
827 data->awaiting |= AWAIT_TRANSACTIONS;
831 data->awaiting |= IGNORE_TRANSACTIONS;
837 gnc_acc = gnc_ab_accinfo_to_gnc_acc (GTK_WIDGET(data->parent), element);
838 if (!gnc_acc)
return NULL;
839 data->gnc_acc = gnc_acc;
841 if (data->execute_txns)
848 gnc_error_dialog (GTK_WINDOW(data->parent),
"%s",
849 _(
"No Online Banking account found for this " 850 "gnucash account. These transactions will " 851 "not be executed by Online Banking."));
859 if (!data->generic_importer)
863 if (data->execute_txns)
866 gnc_ab_trans_processed_cb, data);
872 AB_TRANSACTION_LIST *ab_trans_list = AB_ImExporterAccountInfo_GetTransactionList (element);
874 AB_Transaction_List_ForEachByType (ab_trans_list,
875 txn_transaction_cb, data,
876 AB_Transaction_TypeStatement, 0);
881 static AB_IMEXPORTER_ACCOUNTINFO *
882 bal_accountinfo_cb (AB_IMEXPORTER_ACCOUNTINFO *element, gpointer user_data)
884 GncABImExContextImport *data = user_data;
886 const AB_BALANCE *booked_bal, *noted_bal;
887 const AB_VALUE *booked_val = NULL, *noted_val = NULL;
888 gdouble booked_value, noted_value;
892 gboolean show_recn_window = FALSE;
894 g_return_val_if_fail (element && data, NULL);
896 if (data->awaiting & IGNORE_BALANCES)
900 if (!AB_ImExporterAccountInfo_GetFirstBalance (element))
904 data->awaiting |= FOUND_BALANCES;
907 booked_bal = AB_Balance_List_GetLatestByType (AB_ImExporterAccountInfo_GetBalanceList (element),
908 AB_Balance_TypeBooked);
910 if (!(data->awaiting & AWAIT_BALANCES))
912 GtkWindow *parent = data->generic_importer ?
914 GTK_WINDOW(data->parent);
915 const char* balance_msg =
916 _(
"The bank has sent balance information in its response.\n" 917 "Do you want to import it?");
919 if (!booked_bal || AB_Value_IsZero (AB_Balance_GetValue (booked_bal)))
923 if (gnc_verify_dialog (parent, TRUE,
"%s", balance_msg))
925 data->awaiting |= AWAIT_BALANCES;
929 data->awaiting |= IGNORE_BALANCES;
935 gnc_acc = gnc_ab_accinfo_to_gnc_acc (GTK_WIDGET(data->parent), element);
936 if (!gnc_acc)
return NULL;
937 data->gnc_acc = gnc_acc;
942 const GWEN_DATE *ti = AB_Balance_GetDate (booked_bal);
945 booked_tt = gnc_gwen_date_to_time64 (ti);
953 booked_val = AB_Balance_GetValue (booked_bal);
956 booked_value = AB_Value_GetValueAsDouble (booked_val);
960 g_warning (
"bal_accountinfo_cb: booked_val == NULL. Assuming 0");
966 g_warning (
"bal_accountinfo_cb: booked_bal == NULL. Assuming 0");
972 noted_bal = AB_Balance_List_GetLatestByType (AB_ImExporterAccountInfo_GetBalanceList (element),
973 AB_Balance_TypeNoted);
976 noted_val = AB_Balance_GetValue (noted_bal);
978 noted_value = AB_Value_GetValueAsDouble (noted_val);
981 g_warning (
"bal_accountinfo_cb: noted_val == NULL. Assuming 0");
987 g_warning (
"bal_accountinfo_cb: noted_bal == NULL. Assuming 0");
994 if (noted_value == 0.0 && booked_value == 0.0)
996 dialog = gtk_message_dialog_new (
997 GTK_WINDOW(data->parent),
998 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
1009 _(
"The downloaded Online Banking Balance was zero.\n\n" 1010 "Either this is the correct balance, or your bank does not " 1011 "support Balance download in this Online Banking version. " 1012 "In the latter case you should choose a different " 1013 "Online Banking version number in the Online Banking " 1014 "(AqBanking or HBCI) Setup. After that, try again to " 1015 "download the Online Banking Balance."));
1016 gtk_dialog_run (GTK_DIALOG(dialog));
1017 gtk_widget_destroy (dialog);
1025 gchar *message1 = g_strdup_printf (
1026 _(
"Result of Online Banking job:\n" 1027 "Account booked balance is %s"),
1030 (noted_value == 0.0) ?
1032 g_strdup_printf (_(
"For your information: This account also " 1033 "has a noted balance of %s\n"),
1038 const gchar *message3 =
1039 _(
"The booked balance is identical to the current " 1040 "reconciled balance of the account.");
1041 dialog = gtk_message_dialog_new (
1042 GTK_WINDOW(data->parent),
1043 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
1047 message1, message2, message3);
1048 gtk_dialog_run (GTK_DIALOG(dialog));
1049 gtk_widget_destroy (GTK_WIDGET(dialog));
1054 const char *message3 = _(
"Reconcile account now?");
1056 show_recn_window = gnc_verify_dialog (GTK_WINDOW(data->parent), TRUE,
"%s\n%s\n%s",
1057 message1, message2, message3);
1059 g_free (booked_str);
1065 if (show_recn_window)
1066 recnWindowWithBalance (GTK_WIDGET(data->parent), gnc_acc, value, booked_tt);
1071 GncABImExContextImport *
1073 guint awaiting, gboolean execute_txns,
1074 AB_BANKING *api, GtkWidget *parent)
1076 GncABImExContextImport *data = g_new (GncABImExContextImport, 1);
1077 AB_IMEXPORTER_ACCOUNTINFO_LIST *ab_ail;
1078 g_return_val_if_fail (context, NULL);
1080 g_return_val_if_fail (!(awaiting & AWAIT_BALANCES)
1081 || !(awaiting & IGNORE_BALANCES),
1083 g_return_val_if_fail (!(awaiting & AWAIT_TRANSACTIONS)
1084 || !(awaiting & IGNORE_TRANSACTIONS),
1087 g_return_val_if_fail (awaiting & AWAIT_TRANSACTIONS || !execute_txns, NULL);
1089 g_return_val_if_fail (!execute_txns || api, NULL);
1091 data->awaiting = awaiting;
1092 data->txn_found = FALSE;
1093 data->execute_txns = execute_txns;
1095 data->parent = parent;
1096 data->job_list = AB_Transaction_List2_new ();
1097 data->tmp_job_list = NULL;
1098 data->generic_importer = NULL;
1100 g_datalist_init (&data->tmp_job_list);
1103 ab_ail = AB_ImExporterContext_GetAccountInfoList (context);
1104 if (ab_ail && AB_ImExporterAccountInfo_List_GetCount (ab_ail))
1106 if (!(awaiting & IGNORE_TRANSACTIONS))
1107 AB_ImExporterAccountInfo_List_ForEach (ab_ail,
1112 if (data->generic_importer)
1116 if (!(awaiting & IGNORE_BALANCES))
1117 AB_ImExporterAccountInfo_List_ForEach (ab_ail,
1124 AB_MESSAGE * bankmsg = AB_ImExporterContext_GetFirstMessage (context);
1127 const char* subject = AB_Message_GetSubject (bankmsg);
1128 const char* text = AB_Message_GetText (bankmsg);
1129 gnc_info_dialog (GTK_WINDOW(data->parent),
"%s\n%s %s\n%s",
1130 _(
"The bank has sent a message in its response."),
1135 bankmsg = AB_Message_List_Next (bankmsg);
1145 g_return_val_if_fail (ieci, 0);
1147 return ieci->awaiting;
1153 g_return_val_if_fail (ieci, NULL);
1155 return ieci->job_list;
1161 g_return_val_if_fail (ieci, FALSE);
1170 GWEN_DB_NODE *perm_certs = NULL;
1173 g_return_val_if_fail (banking, NULL);
1174 rv = AB_Banking_LoadSharedConfig (banking,
"certs", &perm_certs);
1176 g_return_val_if_fail (rv >= 0, NULL);
1180 #if (AQBANKING_VERSION_INT >= 60400) 1182 gnc_ab_trans_templ_list_new_from_ref_accounts (GNC_AB_ACCOUNT_SPEC *ab_acc)
1184 GList *retval = NULL;
1185 AB_REFERENCE_ACCOUNT *ra;
1186 AB_REFERENCE_ACCOUNT_LIST *ral;
1187 GWEN_BUFFER *accNameForTemplate = GWEN_Buffer_new (0,120,0,0);
1188 gnc_numeric zero = gnc_numeric_zero ();
1191 ral = AB_AccountSpec_GetRefAccountList (ab_acc);
1192 ra = AB_ReferenceAccount_List_First (ral);
1198 const char *iban = AB_ReferenceAccount_GetIban (ra);
1199 const char *accName = AB_ReferenceAccount_GetAccountName (ra);
1200 GWEN_Buffer_Reset (accNameForTemplate);
1203 GWEN_Buffer_AppendString (accNameForTemplate, accName);
1204 GWEN_Buffer_AppendString (accNameForTemplate,
": ");
1206 GWEN_Buffer_AppendString (accNameForTemplate, iban);
1212 retval = g_list_prepend (retval, new_templ);
1213 ra = AB_ReferenceAccount_List_Next (ra);
1215 retval = g_list_reverse (retval);
1217 GWEN_Buffer_free (accNameForTemplate);
1225 return left ? (right ? g_strcmp0 (left->name, right->name) : -1) :
1232 GList* desc_list = NULL;
1233 GWEN_PLUGIN_DESCRIPTION_LIST2 *il =
1234 AB_Banking_GetImExporterDescrs (api);
1235 GWEN_PLUGIN_DESCRIPTION_LIST2_ITERATOR *ilit;
1236 g_return_val_if_fail (il, NULL);
1237 ilit = GWEN_PluginDescription_List2_First(il);
1239 for (GWEN_PLUGIN_DESCRIPTION *pd =
1240 GWEN_PluginDescription_List2Iterator_Data(ilit);
1242 pd = GWEN_PluginDescription_List2Iterator_Next(ilit))
1247 node->name = g_strdup(GWEN_PluginDescription_GetName(pd));
1248 node->descr = g_strdup(GWEN_PluginDescription_GetShortDescr(pd));
1249 desc_list = g_list_prepend (desc_list, node);
1251 GWEN_PluginDescription_List2_free(il);
1252 return g_list_sort (desc_list, (GCompareFunc)ab_node_pair_compare);
1258 GList* prof_list = NULL;
1259 GWEN_DB_NODE* db = AB_Banking_GetImExporterProfiles(api, importer_name);
1260 g_return_val_if_fail (db, NULL);
1262 for (GWEN_DB_NODE *profile = GWEN_DB_GetFirstGroup(db); profile;
1263 profile = GWEN_DB_GetNextGroup(profile))
1266 if (!profile)
continue;
1267 node->name = g_strdup(GWEN_DB_GetCharValue(profile,
"name", 0, NULL));
1268 node->descr = g_strdup(GWEN_DB_GetCharValue(profile,
"shortDescr", 0, NULL));
1269 prof_list = g_list_prepend (prof_list, node);
1271 return g_list_sort (prof_list, (GCompareFunc)ab_node_pair_compare);
Dialog for AqBanking transaction data.
guint32 gnc_ab_get_account_uid(const Account *a)
Return the unique id for the AB_BANKING account in the Account a.
gchar * gnc_ab_create_online_id(const gchar *bankcode, const gchar *accountnumber)
Creates an online ID from bank code and account number.
gchar * gnc_ab_get_remote_name(const AB_TRANSACTION *ab_trans)
Retrieve the merged "remote name" fields from a transaction.
GList * gnc_ab_imexporter_list(AB_BANKING *api)
Retrieve the available AQBanking importers.
Transaction * xaccMallocTransaction(QofBook *book)
The xaccMallocTransaction() will malloc memory and initialize it.
gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b)
Equivalence predicate: Returns TRUE (1) if a and b represent the same number.
void xaccSplitSetBaseValue(Split *s, gnc_numeric value, const gnc_commodity *base_currency)
Depending on the base_currency, set either the value or the amount of this split or both: If the base...
void xaccTransSetDatePostedSecsNormalized(Transaction *trans, time64 time)
This function sets the posted date of the transaction, specified by a time64 (see ctime(3))...
time64 gnc_dmy2time64_neutral(gint day, gint month, gint year)
Converts a day, month, and year to a time64 representing 11:00:00 UTC 11:00:00 UTC falls on the same ...
gnc_numeric double_to_gnc_numeric(double n, gint64 denom, gint how)
Convert a floating-point number to a gnc_numeric.
void gnc_gen_trans_list_show_all(GNCImportMainMatcher *info)
Shows widgets.
void gnc_GWEN_Gui_shutdown(void)
Free all memory related to both the full-blown and minimalistic GUI objects.
#define G_LOG_DOMAIN
Functions providing the SX List as a plugin page.
#define PINFO(format, args...)
Print an informational note.
int xaccAccountGetCommoditySCU(const Account *acc)
Return the SCU for the account.
gchar * gnc_ab_get_purpose(const AB_TRANSACTION *ab_trans, gboolean is_ofx)
Retrieve the merged purpose fields from a transaction.
void gnc_ab_trans_templ_set_amount(GncABTransTempl *t, gnc_numeric amount)
Replace the amount stored in a template.
gchar * gnc_AB_VALUE_to_readable_string(const AB_VALUE *value)
Print the value of value with two decimal places and value's currency appended, or 0...
void xaccTransSetDescription(Transaction *trans, const char *desc)
Sets the transaction Description.
gchar * gnc_AB_JOB_ID_to_string(gulong job_id)
Return the job_id as string.
Transaction matcher main window.
void gnc_utf8_strip_invalid_and_controls(gchar *str)
Strip any non-utf8 characters and any control characters (everything < 0x20, , , ...
gchar * gnc_ab_memo_to_gnc(const AB_TRANSACTION *ab_trans)
Create the appropriate memo field for a GnuCash Split by the information given in the AB_TRANSACTION ...
Account * gnc_import_select_account(GtkWidget *parent, const gchar *account_online_id_value, gboolean prompt_on_no_match, const gchar *account_human_description, const gnc_commodity *new_account_default_commodity, GNCAccountType new_account_default_type, Account *default_selection, gboolean *ok_pressed)
Must be called with a string containing a unique identifier for the account.
gboolean gnc_ab_ieci_run_matcher(GncABImExContextImport *ieci)
Run the generic transaction matcher dialog.
void gnc_gen_trans_list_add_tp_cb(GNCImportMainMatcher *info, GNCTransactionProcessedCB trans_processed_cb, gpointer user_data)
Add transaction processed callback to the transaction importer.
void gnc_ab_trans_templ_set_recp_account(GncABTransTempl *t, const gchar *recp_account)
Replace the Account Number of the recipient stored in a template.
Generic and very flexible account matcher/picker.
GNC_AB_JOB_LIST2 * gnc_ab_ieci_get_job_list(GncABImExContextImport *ieci)
Extract the job list from data.
void gnc_ab_trans_templ_set_name(GncABTransTempl *t, const gchar *name)
Set the name of a template.
guint32 gnc_import_TransInfo_get_ref_id(const GNCImportTransInfo *info)
Returns the reference id for this TransInfo.
const gchar * gnc_ab_get_account_bankcode(const Account *a)
Return the bankcode string in the Account a.
void gnc_gen_trans_list_add_trans(GNCImportMainMatcher *gui, Transaction *trans)
Add a newly imported Transaction to the Transaction Importer.
GWEN_DB_NODE * gnc_ab_get_permanent_certs(void)
get the GWEN_DB_NODE from AqBanking configuration files
void xaccTransSetCurrency(Transaction *trans, gnc_commodity *curr)
Set a new currency on a transaction.
void gnc_ab_trans_templ_set_recp_name(GncABTransTempl *t, const gchar *recp_name)
Replace the Account Number of the recipient stored in a template.
void gnc_ab_trans_templ_set_recp_bankcode(GncABTransTempl *t, const gchar *recp_bankcode)
Replace the Bank Code of the recipient stored in a template.
GncABTransTempl * gnc_ab_trans_templ_new()
Create a template with unset contents.
gchar * gnc_ab_description_to_gnc(const AB_TRANSACTION *ab_trans, gboolean is_ofx)
Create the appropriate description field for a GnuCash Transaction by the information given in the AB...
GtkWidget * gnc_gen_trans_list_widget(GNCImportMainMatcher *info)
Returns the widget of this dialog.
Transaction * gnc_ab_trans_to_gnc(const AB_TRANSACTION *ab_trans, Account *gnc_acc)
Create an unbalanced and dirty GnuCash transaction with a split to gnc_acc from the information avail...
void xaccSplitSetMemo(Split *split, const char *memo)
The memo is an arbitrary string associated with a split.
gchar * gnc_AB_JOB_to_readable_string(const GNC_AB_JOB *job)
Return the job as string.
GNCImportMainMatcher * gnc_gen_trans_list_new(GtkWidget *parent, const gchar *heading, bool all_from_same_account, gint match_date_hardlimit, bool show_all)
Create a new generic transaction dialog window and return it.
AB_BANKING * gnc_AB_BANKING_new(void)
If there is a cached AB_BANKING object, return it initialized.
void gnc_utf8_strip_invalid(gchar *str)
Strip any non-UTF-8 characters from a string.
void xaccTransBeginEdit(Transaction *trans)
The xaccTransBeginEdit() method must be called before any changes are made to a transaction or any of...
gnc_numeric xaccAccountGetReconciledBalance(const Account *acc)
Get the current balance of the account, only including reconciled transactions.
GList * gnc_ab_imexporter_profile_list(AB_BANKING *api, const char *importer_name)
Retrieve the available format templates for an AQBanking importer.
gint gnc_AB_BANKING_fini(AB_BANKING *api)
Finish the AB_BANKING api.
Split * xaccMallocSplit(QofBook *book)
Constructor.
gchar * gnc_g_list_stringjoin_nodups(GList *list_of_strings, const gchar *sep)
Like stringjoin but ensures that the string to be added isn't already part of the return string...
Generic api to store and retrieve preferences.
void gnc_gen_trans_list_add_trans_with_ref_id(GNCImportMainMatcher *gui, Transaction *trans, guint32 ref_id)
Add a newly imported Transaction to the Transaction Importer and provide an external reference id for...
GNC_AB_JOB * gnc_ab_get_trans_job(GNC_AB_ACCOUNT_SPEC *ab_acc, const AB_TRANSACTION *ab_trans, GncABTransType trans_type)
Return the AqBanking job associated with the transaction.
void gnc_AB_BANKING_delete(AB_BANKING *api)
Delete the AB_BANKING api.
void gnc_GWEN_Fini(void)
Finalize the gwenhywfar library.
GncABImExContextImport * gnc_ab_import_context(AB_IMEXPORTER_CONTEXT *context, guint awaiting, gboolean execute_txns, AB_BANKING *api, GtkWidget *parent)
Import balances and transactions found in a AB_IMEXPORTER_CONTEXT into GnuCash.
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account's commodity.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
bool gnc_gen_trans_list_run(GNCImportMainMatcher *info)
Run this dialog and return only after the user pressed Ok, Cancel, or closed the window.
Utility functions for writing import modules.
Round to the nearest integer, rounding away from zero when there are two equidistant nearest integers...
GNC_AB_ACCOUNT_SPEC * gnc_ab_get_ab_account(const AB_BANKING *api, Account *gnc_acc)
Get the corresponding AqBanking account to the GnuCash account gnc_acc.
time64 gnc_time(time64 *tbuf)
get the current time
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
const gchar * gnc_ab_get_account_accountid(const Account *a)
Return accountid string in the Account a.
void xaccTransSetDateEnteredSecs(Transaction *trans, time64 secs)
Modify the date of when the transaction was entered.
void gnc_GWEN_Init(void)
Initialize the gwenhywfar library by calling GWEN_Init() and setting up gwenhywfar logging...
GUI callbacks for AqBanking.
guint gnc_ab_ieci_get_found(GncABImExContextImport *ieci)
Extract awaiting from data.
API for Transactions and Splits (journal entries)
void gnc_GWEN_Gui_log_init(void)
Hook our logging into the gwenhywfar logging framework by creating a minimalistic GWEN_GUI with only ...
AqBanking utility functions.
time64 gnc_time64_get_day_neutral(time64 time_val)
The gnc_time64_get_day_neutral() routine will take the given time in seconds and adjust it to 10:59:0...