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(" "); }
void tax_table_delete_table_cb (GtkButton *button, TaxTableWindow *ttw) { g_return_if_fail (ttw); if (!ttw->current_table) return; if (gncTaxTableGetRefcount (ttw->current_table) > 0) { char *message = g_strdup_printf (_("Tax table \"%s\" is in use. You cannot delete it."), gncTaxTableGetName (ttw->current_table)); gnc_error_dialog (ttw->dialog, "%s", message); g_free (message); return; } if (gnc_verify_dialog (ttw->dialog, FALSE, _("Are you sure you want to delete \"%s\"?"), gncTaxTableGetName (ttw->current_table))) { /* Ok, let's remove it */ gnc_suspend_gui_refresh (); gncTaxTableBeginEdit (ttw->current_table); gncTaxTableDestroy (ttw->current_table); ttw->current_table = NULL; ttw->current_entry = NULL; gnc_resume_gui_refresh (); } }
void tax_table_delete_entry_cb (GtkButton *button, TaxTableWindow *ttw) { g_return_if_fail (ttw); if (!ttw->current_table || !ttw->current_entry) return; if (g_list_length (gncTaxTableGetEntries (ttw->current_table)) <= 1) { char *message = _("You cannot remove the last entry from the tax table. " "Try deleting the tax table if you want to do that."); gnc_error_dialog (ttw->dialog, "%s", message); return; } if (gnc_verify_dialog (ttw->dialog, FALSE, "%s", _("Are you sure you want to delete this entry?"))) { /* Ok, let's remove it */ gnc_suspend_gui_refresh (); gncTaxTableBeginEdit (ttw->current_table); gncTaxTableRemoveEntry (ttw->current_table, ttw->current_entry); gncTaxTableEntryDestroy (ttw->current_entry); gncTaxTableChanged (ttw->current_table); gncTaxTableCommitEdit (ttw->current_table); ttw->current_entry = NULL; gnc_resume_gui_refresh (); } }
static gboolean gnc_entry_ledger_check_close_internal (GtkWidget *parent, GncEntryLedger *ledger, gboolean dontask) { const char *message = _("The current entry has been changed. " "Would you like to save it?"); VirtualLocation virt_loc; virt_loc = ledger->table->current_cursor_loc; if (gnc_entry_ledger_traverse (&virt_loc, GNC_TABLE_TRAVERSE_POINTER, ledger)) return FALSE; if (!gnc_entry_ledger_verify_can_save (ledger)) return FALSE; if (dontask || gnc_verify_dialog (parent, TRUE, "%s", message)) gnc_entry_ledger_save (ledger, TRUE); else gnc_entry_ledger_cancel_cursor_changes (ledger); return TRUE; }
gboolean ggg_delete_event_cb(GtkWidget *widget, GdkEvent *event, gpointer user_data) { GncGWENGui *gui = user_data; g_return_val_if_fail(gui, FALSE); ENTER("gui=%p, state=%d", gui, gui->state); if (gui->state == RUNNING) { const char *still_running_msg = _("The Online Banking job is still running; are you " "sure you want to cancel?"); if (!gnc_verify_dialog(gui->dialog, FALSE, "%s", still_running_msg)) return FALSE; set_aborted(gui); } hide_dialog(gui); LEAVE(" "); return TRUE; }
static const AB_TRANSACTION * translist_cb (const AB_TRANSACTION *element, void *user_data) { AB_JOB *job; AB_TRANSACTION *trans = (AB_TRANSACTION*)element; GtkWidget *parent = NULL; struct import_data *data = user_data; struct trans_list_data hbci_userdata; /* This callback in the hbci module will add the imported transaction to gnucash's importer. */ hbci_userdata.gnc_acc = data->gnc_acc; hbci_userdata.importer_generic = data->importer_generic; /* The call will use "trans" only as const* */ gnc_hbci_trans_list_cb((AB_TRANSACTION*) trans, &hbci_userdata); if (data->hbci_account) { /* NEW: The imported transaction has been imported into gnucash. Now also add it as a job to aqbanking. */ AB_Transaction_SetLocalBankCode (trans, AB_Account_GetBankCode (data->hbci_account)); AB_Transaction_SetLocalAccountNumber (trans, AB_Account_GetAccountNumber (data->hbci_account)); AB_Transaction_SetLocalCountry (trans, "DE"); job = gnc_hbci_trans_dialog_enqueue(trans, data->ab, data->hbci_account, SINGLE_DEBITNOTE); /* Check whether we really got a job */ if (!job) { /* Oops, no job, probably not supported by bank. */ 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?"))) { gnc_error_dialog (parent, "Sorry, not implemented yet."); } /* else break; */ } data->job_list = g_list_append(data->job_list, job); } return NULL; }
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?"))) { gnc_ab_set_book_template_list(gnc_account_get_book(gnc_acc), templates); } }
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 }
/************************************************** * csv_export_file_chooser_confirm_cb * * call back for ok button in file chooser widget **************************************************/ void csv_export_file_chooser_confirm_cb (GtkWidget *button, CsvExportInfo *info) { GtkAssistant *assistant = GTK_ASSISTANT(info->window); gint num = gtk_assistant_get_current_page (assistant); GtkWidget *page = gtk_assistant_get_nth_page (assistant, num); gchar *file_name; gtk_assistant_set_page_complete (assistant, page, FALSE); file_name = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(info->file_chooser)); if (file_name) { if (g_file_test (file_name, G_FILE_TEST_EXISTS)) { const char *format = _("The file %s already exists. " "Are you sure you want to overwrite it?"); /* if user says cancel, we should break out */ if (!gnc_verify_dialog (NULL, FALSE, format, file_name)) return; } info->file_name = g_strdup (file_name); gtk_assistant_set_page_complete (assistant, page, TRUE); } if (file_name) { gchar *filepath = gnc_uri_get_path (file_name); gchar *filedir = g_path_get_dirname (filepath); info->starting_dir = g_strdup (filedir); g_free (filedir); g_free (filepath); } g_free (file_name); DEBUG("file_name selected is %s", info->file_name); DEBUG("starting directory is %s", info->starting_dir); /* Step to next page if page is complete */ if(gtk_assistant_get_page_complete (assistant, page)) gtk_assistant_set_current_page (assistant, num + 1); }
/********************************************************************* * custom_report_delete * * this will delete the report, update the reports list and leave the * dialog active for additional usage. *********************************************************************/ static void custom_report_delete (SCM guid, CustomReportDialog *crd) { SCM template_menu_name = scm_c_eval_string("gnc:report-template-menu-name/report-guid"); gchar *report_name; if (scm_is_null (guid)) return; report_name = gnc_scm_to_utf8_string(scm_call_2(template_menu_name, guid, SCM_BOOL_F)); /* we must confirm the user wants to delete their precious custom report! */ if (gnc_verify_dialog( GTK_WINDOW (crd->dialog), FALSE, _("Are you sure you want to delete %s?"), report_name)) { SCM del_report = scm_c_eval_string("gnc:delete-report"); scm_call_1(del_report, guid); update_report_list(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(crd->reportview))), crd); } g_free (report_name); }
static void gnc_plugin_page_sx_list_cmd_delete(GtkAction *action, GncPluginPageSxList *page) { GncPluginPageSxListPrivate *priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page); GtkTreeSelection *selection; GList *selected_paths, *to_delete = NULL; GtkTreeModel *model; selection = gtk_tree_view_get_selection(priv->tree_view); selected_paths = gtk_tree_selection_get_selected_rows(selection, &model); if (g_list_length(selected_paths) == 0) { g_warning("no selection for delete."); return; } to_delete = gnc_g_list_map(selected_paths, (GncGMapFunc)_argument_reorder_fn, priv->tree_view); { GList *list; for (list = to_delete; list != NULL; list = list->next) { g_debug("to-delete [%s]\n", xaccSchedXactionGetName((SchedXaction*)list->data)); } } /* FIXME: Does this always refer to only one transaction? Or could multiple SXs be deleted as well? Ideally, the number of to-be-deleted SXs should be mentioned here; see dialog-sx-since-last-run.cpp:807 */ if (gnc_verify_dialog(NULL, FALSE, "%s", _("Do you really want to delete this scheduled transaction?"))) { g_list_foreach(to_delete, (GFunc)_destroy_sx, NULL); } g_list_free(to_delete); g_list_foreach(selected_paths, (GFunc)gtk_tree_path_free, NULL); g_list_free(selected_paths); }
static void get_input(GncGWENGui *gui, guint32 flags, const gchar *title, const gchar *text, gchar **input, gint min_len, gint max_len) { GladeXML *xml; GtkWidget *dialog; GtkWidget *heading_label; GtkWidget *input_entry; GtkWidget *confirm_entry; GtkWidget *confirm_label; GtkWidget *remember_pin_checkbutton; const gchar *internal_input, *internal_confirmed; gboolean confirm = (flags & GWEN_GUI_INPUT_FLAGS_CONFIRM) != 0; gboolean hidden = (flags & GWEN_GUI_INPUT_FLAGS_SHOW) == 0; gboolean is_tan = (flags & GWEN_GUI_INPUT_FLAGS_TAN) != 0; gint retval; g_return_if_fail(input); g_return_if_fail(max_len >= min_len && max_len > 0); ENTER(" "); /* Set up dialog */ xml = gnc_glade_xml_new("aqbanking.glade", "Password Dialog"); dialog = glade_xml_get_widget(xml, "Password Dialog"); g_object_set_data_full(G_OBJECT(dialog), "xml", xml, g_object_unref); heading_label = glade_xml_get_widget(xml, "heading_label"); input_entry = glade_xml_get_widget(xml, "input_entry"); confirm_entry = glade_xml_get_widget(xml, "confirm_entry"); confirm_label = glade_xml_get_widget(xml, "confirm_label"); remember_pin_checkbutton = glade_xml_get_widget(xml, "remember_pin"); if (is_tan) { gtk_widget_hide(remember_pin_checkbutton); } else { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(remember_pin_checkbutton), gui->cache_passwords); } if (gui->parent) gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(gui->parent)); if (title) gtk_window_set_title(GTK_WINDOW(dialog), title); if (text) { gchar *raw_text = strip_html(g_strdup(text)); gtk_label_set_text(GTK_LABEL(heading_label), raw_text); g_free(raw_text); } if (*input) { gtk_entry_set_text(GTK_ENTRY(input_entry), *input); erase_password(*input); *input = NULL; } if (confirm) { gtk_entry_set_activates_default(GTK_ENTRY(input_entry), FALSE); gtk_entry_set_activates_default(GTK_ENTRY(confirm_entry), TRUE); gtk_entry_set_max_length(GTK_ENTRY(input_entry), max_len); gtk_entry_set_max_length(GTK_ENTRY(confirm_entry), max_len); } else { gtk_entry_set_activates_default(GTK_ENTRY(input_entry), TRUE); gtk_entry_set_max_length(GTK_ENTRY(input_entry), max_len); gtk_widget_hide(confirm_entry); gtk_widget_hide(confirm_label); } gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); /* Ask the user until he enters a valid input or cancels */ while (TRUE) { gboolean remember_pin; if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) break; if (!is_tan) { /* Enable or disable the password cache */ remember_pin = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(remember_pin_checkbutton)); enable_password_cache(gui, remember_pin); gnc_gconf_set_bool(GCONF_SECTION_AQBANKING, KEY_REMEMBER_PIN, remember_pin, NULL); } internal_input = gtk_entry_get_text(GTK_ENTRY(input_entry)); if (strlen(internal_input) < min_len) { gboolean retval; gchar *msg = g_strdup_printf( _("The PIN needs to be at least %d characters \n" "long. Do you want to try again?"), min_len); retval = gnc_verify_dialog(gui->parent, TRUE, "%s", msg); g_free(msg); if (!retval) break; continue; } if (!confirm) { *input = g_strdup(internal_input); break; } internal_confirmed = gtk_entry_get_text(GTK_ENTRY(confirm_entry)); if (strcmp(internal_input, internal_confirmed) == 0) { *input = g_strdup(internal_input); break; } } /* This trashes passwords in the entries' memory as well */ gtk_widget_destroy(dialog); LEAVE("input %s", *input ? "non-NULL" : "NULL"); }
static gboolean gnc_entry_ledger_traverse (VirtualLocation *p_new_virt_loc, gncTableTraversalDir dir, gpointer user_data) { GncEntryLedger *ledger = user_data; GncEntry *entry, *new_entry; gint response; VirtualLocation virt_loc; int changed; char const *cell_name; gboolean exact_traversal; if (!ledger) return FALSE; exact_traversal = (dir == GNC_TABLE_TRAVERSE_POINTER); entry = gnc_entry_ledger_get_current_entry (ledger); if (!entry) return FALSE; /* no changes, make sure we aren't going off the end */ changed = gnc_table_current_cursor_changed (ledger->table, FALSE); if (!changed) return FALSE; virt_loc = *p_new_virt_loc; cell_name = gnc_table_get_current_cell_name (ledger->table); /* See if we are leaving the account field */ do { ComboCell *cell; char *name; char *cell_name = NULL; switch (ledger->type) { case GNCENTRY_INVOICE_ENTRY: case GNCENTRY_INVOICE_VIEWER: case GNCENTRY_CUST_CREDIT_NOTE_ENTRY: case GNCENTRY_CUST_CREDIT_NOTE_VIEWER: cell_name = ENTRY_IACCT_CELL; break; case GNCENTRY_BILL_ENTRY: case GNCENTRY_BILL_VIEWER: case GNCENTRY_EXPVOUCHER_ENTRY: case GNCENTRY_EXPVOUCHER_VIEWER: case GNCENTRY_VEND_CREDIT_NOTE_ENTRY: case GNCENTRY_VEND_CREDIT_NOTE_VIEWER: case GNCENTRY_EMPL_CREDIT_NOTE_ENTRY: case GNCENTRY_EMPL_CREDIT_NOTE_VIEWER: cell_name = ENTRY_BACCT_CELL; break; default: g_warning ("Unhandled ledger type"); break; } if (!cell_name) break; if (!gnc_cell_name_equal (cell_name, cell_name)) break; if (!gnc_table_layout_get_cell_changed (ledger->table->layout, cell_name, FALSE)) break; cell = (ComboCell *) gnc_table_layout_get_cell (ledger->table->layout, cell_name); if (!cell) break; name = cell->cell.value; if (!name || *name == '\0') break; /* Create the account if necessary. Also checks for a placeholder */ if (!gnc_entry_ledger_get_account_by_name (ledger, (BasicCell *) cell, cell->cell.value, &ledger->full_refresh)) return TRUE; } while (FALSE); /* See if we are leaving the TaxTable field */ do { ComboCell *cell; GncTaxTable *table; char *name; if (!gnc_cell_name_equal (cell_name, ENTRY_TAXTABLE_CELL)) break; if (!gnc_table_layout_get_cell_changed (ledger->table->layout, ENTRY_TAXTABLE_CELL, FALSE)) break; cell = (ComboCell *) gnc_table_layout_get_cell (ledger->table->layout, ENTRY_TAXTABLE_CELL); if (!cell) break; name = cell->cell.value; if (!name || *name == '\0') break; table = gncTaxTableLookupByName (ledger->book, cell->cell.value); if (table) break; { const char *format = _("The tax table %s does not exist. " "Would you like to create it?"); if (!gnc_verify_dialog (ledger->parent, TRUE, format, name)) break; } ledger->full_refresh = FALSE; table = gnc_ui_tax_table_new_from_name (ledger->book, name); if (!table) break; ledger->full_refresh = TRUE; name = (char *)gncTaxTableGetName (table); gnc_combo_cell_set_value (cell, name); gnc_basic_cell_set_changed (&cell->cell, TRUE); } while (FALSE); /* See if we are tabbing off the end of the very last line * (i.e. the blank entry) */ do { VirtualLocation virt_loc; if (!changed && !ledger->blank_entry_edited) break; if (dir != GNC_TABLE_TRAVERSE_RIGHT) break; virt_loc = ledger->table->current_cursor_loc; if (gnc_table_move_vertical_position (ledger->table, &virt_loc, 1)) break; virt_loc = ledger->table->current_cursor_loc; if (gnc_table_move_tab (ledger->table, &virt_loc, TRUE)) break; *p_new_virt_loc = ledger->table->current_cursor_loc; /* Yep, we're trying to leave the blank entry -- make sure * we are allowed to do so by verifying the current cursor. * If the current cursor is ok, then move on! */ /* Verify that the cursor is ok. If we can't save the cell, don't move! */ if (!gnc_entry_ledger_verify_can_save (ledger)) { return TRUE; } (p_new_virt_loc->vcell_loc.virt_row)++; p_new_virt_loc->phys_row_offset = 0; p_new_virt_loc->phys_col_offset = 0; ledger->traverse_to_new = TRUE; /* If we're here, we're tabbing off the end of the 'blank entry' */ return FALSE; } while (FALSE); /* Now see if we are changing cursors. If not, we may be able to * auto-complete. */ if (!gnc_table_virtual_cell_out_of_bounds (ledger->table, virt_loc.vcell_loc)) { if (gnc_entry_ledger_auto_completion (ledger, dir, p_new_virt_loc)) return FALSE; } /* Check for going off the end */ gnc_table_find_close_valid_cell (ledger->table, &virt_loc, exact_traversal); /* Same entry, no problem -- we're just moving backwards in the cursor */ new_entry = gnc_entry_ledger_get_entry (ledger, virt_loc.vcell_loc); if (entry == new_entry) { *p_new_virt_loc = virt_loc; return FALSE; } /* If we are here, then we are trying to leave the cursor. Make sure * the cursor we are leaving is valid. If so, ask the user if the * changes should be recorded. If not, don't go anywhere. */ /* Verify this cursor -- if it's not valid, don't let them move on */ if (!gnc_entry_ledger_verify_can_save (ledger)) { *p_new_virt_loc = ledger->table->current_cursor_loc; return TRUE; } /* * XXX GNCENTRY_INVOICE_EDIT processing to be added: * 1) check if the qty field changed. * 2) if so, check if this entry is part of an order. * 3) if so, ask if they want to change the entry or * split the entry into two parts. */ /* Ok, we are changing lines and the current entry has * changed. We only ask them what they want to do in * limited cases -- usually just let the change go through. */ { GtkWidget *dialog; const char *title = _("Save the current entry?"); const char *message = _("The current entry has been changed. However, this entry is " "part of an existing order. Would you like to record the change " "and effectively change your order?"); switch (ledger->type) { case GNCENTRY_INVOICE_ENTRY: case GNCENTRY_CUST_CREDIT_NOTE_ENTRY: if (gncEntryGetOrder (entry) != NULL) { dialog = gtk_message_dialog_new(GTK_WINDOW(ledger->parent), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, "%s", title); gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), "%s", message); gtk_dialog_add_buttons(GTK_DIALOG(dialog), _("_Don't Record"), GTK_RESPONSE_REJECT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, _("_Record"), GTK_RESPONSE_ACCEPT, NULL); response = gnc_dialog_run(GTK_DIALOG(dialog), "invoice_entry_changed"); gtk_widget_destroy(dialog); break; } /* FALL THROUGH */ default: response = GTK_RESPONSE_ACCEPT; break; } } switch (response) { case GTK_RESPONSE_ACCEPT: break; case GTK_RESPONSE_REJECT: { VirtualCellLocation vcell_loc; GncEntry *new_entry; new_entry = gnc_entry_ledger_get_entry (ledger, virt_loc.vcell_loc); gnc_entry_ledger_cancel_cursor_changes (ledger); if (gnc_entry_ledger_find_entry (ledger, new_entry, &vcell_loc)) virt_loc.vcell_loc = vcell_loc; gnc_table_find_close_valid_cell (ledger->table, &virt_loc, exact_traversal); *p_new_virt_loc = virt_loc; } break; case GTK_RESPONSE_CANCEL: default: return TRUE; } return FALSE; }
static AB_IMEXPORTER_ACCOUNTINFO * txn_accountinfo_cb(AB_IMEXPORTER_ACCOUNTINFO *element, gpointer user_data) { GncABImExContextImport *data = user_data; Account *gnc_acc; g_return_val_if_fail(element && data, NULL); if (data->awaiting & IGNORE_TRANSACTIONS) /* Ignore them */ return NULL; if (!AB_ImExporterAccountInfo_GetFirstTransaction(element)) /* No transaction found */ return NULL; else data->awaiting |= FOUND_TRANSACTIONS; if (!(data->awaiting & AWAIT_TRANSACTIONS)) { if (gnc_verify_dialog(data->parent, TRUE, "%s", _("The bank has sent transaction information " "in its response." "\n" "Do you want to import it?"))) { data->awaiting |= AWAIT_TRANSACTIONS; } else { data->awaiting |= IGNORE_TRANSACTIONS; return NULL; } } /* Lookup the corresponding gnucash account */ gnc_acc = gnc_ab_accinfo_to_gnc_acc(element); if (!gnc_acc) return NULL; data->gnc_acc = gnc_acc; if (data->execute_txns) { /* Retrieve the aqbanking account that belongs to this gnucash * account */ data->ab_acc = gnc_ab_get_ab_account(data->api, gnc_acc); if (!data->ab_acc) { gnc_error_dialog(NULL, "%s", _("No Online Banking account found for this " "gnucash account. These transactions will " "not be executed by Online Banking.")); } } else { data->ab_acc = NULL; } if (!data->generic_importer) { data->generic_importer = gnc_gen_trans_list_new(data->parent, NULL, TRUE, 14); if (data->execute_txns) { gnc_gen_trans_list_add_tp_cb(data->generic_importer, gnc_ab_trans_processed_cb, data); } } /* Iterate through all transactions */ AB_ImExporterAccountInfo_TransactionsForEach(element, txn_transaction_cb, data); return NULL; }
gboolean gnc_hbci_Error_retry (GtkWidget *parent, int error, GNCInteractor *inter) { int code = error; switch (code) { #if 0 /* these error codes existed in openhbci, but no longer in aqbanking. Maybe they might get reintroduced later, but maybe not. */ case AB_ERROR_PIN_WRONG: GNCInteractor_erasePIN (inter); return gnc_verify_dialog (parent, TRUE, _("The PIN you entered was wrong.\n" "Do you want to try again?")); case AB_ERROR_PIN_WRONG_0: GNCInteractor_erasePIN (inter); return gnc_verify_dialog (parent, TRUE, _("The PIN you entered was wrong.\n" "ATTENTION: You have zero further wrong retries left!\n" "Do you want to try again?")); case AB_ERROR_CARD_DESTROYED: GNCInteractor_hide (inter); gnc_error_dialog (parent, _("Unfortunately you entered a wrong PIN for too many times. " "Your chip card is therefore destroyed. Aborting.")); return FALSE; case AB_ERROR_FILE_NOT_FOUND: /* g_warning("gnc_hbci_Error_feedback: File not found error.\n"); */ return FALSE; case AB_ERROR_NO_CARD: return gnc_verify_dialog (parent, TRUE, _("No chip card has been found in the chip card reader. " "Do you want to try again?")); case AB_ERROR_JOB_NOT_SUPPORTED: GNCInteractor_hide (inter); gnc_error_dialog (parent, _("Unfortunately this Online Banking job is not supported " "by your bank or for your account. Aborting.")); return FALSE; #endif case AB_ERROR_NETWORK: if (inter) GNCInteractor_hide (inter); gnc_error_dialog (parent, _("The server of your bank refused the Online Banking connection. " "Please try again later. Aborting.")); return FALSE; default: return FALSE; } }
void gnc_ab_maketrans(GtkWidget *parent, Account *gnc_acc, GncABTransType trans_type) { AB_BANKING *api; gboolean online = FALSE; AB_ACCOUNT *ab_acc; GList *templates = NULL; GncABTransDialog *td = NULL; gboolean successful = FALSE; gboolean aborted = FALSE; g_return_if_fail(parent && gnc_acc); /* Get the API */ api = gnc_AB_BANKING_new(); if (!api) { g_warning("gnc_ab_maketrans: Couldn't get AqBanking API"); return; } if (AB_Banking_OnlineInit(api #ifdef AQBANKING_VERSION_4_EXACTLY , 0 #endif ) != 0) { g_warning("gnc_ab_maketrans: Couldn't initialize AqBanking API"); goto cleanup; } online = TRUE; /* Get the AqBanking Account */ ab_acc = gnc_ab_get_ab_account(api, gnc_acc); if (!ab_acc) { g_warning("gnc_ab_gettrans: No AqBanking account found"); gnc_error_dialog(parent, _("No valid online banking account assigned.")); goto cleanup; } /* Get list of template transactions */ templates = gnc_ab_trans_templ_list_new_from_book( gnc_account_get_book(gnc_acc)); /* Create new ABTransDialog */ td = gnc_ab_trans_dialog_new(parent, ab_acc, xaccAccountGetCommoditySCU(gnc_acc), trans_type, templates); templates = NULL; /* Repeat until AqBanking action was successful or user pressed cancel */ do { GncGWENGui *gui = NULL; gint result; gboolean changed; 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; AB_IMEXPORTER_CONTEXT *context = NULL; AB_JOB_STATUS job_status; GncABImExContextImport *ieci = NULL; /* Get a GUI object */ gui = gnc_GWEN_Gui_get(parent); if (!gui) { g_warning("gnc_ab_maketrans: Couldn't initialize Gwenhywfar GUI"); aborted = TRUE; goto repeat; } /* Let the user enter the values */ result = gnc_ab_trans_dialog_run_until_ok(td); /* Save the templates */ templates = gnc_ab_trans_dialog_get_templ(td, &changed); if (changed) save_templates(parent, gnc_acc, templates, (result == GNC_RESPONSE_NOW)); g_list_free(templates); templates = NULL; if (result != GNC_RESPONSE_NOW && result != GNC_RESPONSE_LATER) { aborted = TRUE; goto repeat; } /* 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 #ifndef AQBANKING_VERSION_5_PLUS , 0 #endif )) { 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")); gnc_xfer_dialog_lock_to_account_tree(xfer_dialog); break; case SINGLE_INTERNAL_TRANSFER: gnc_xfer_dialog_set_title( xfer_dialog, _("Online Banking Bank-Internal Transfer")); gnc_xfer_dialog_lock_from_account_tree(xfer_dialog); break; case SEPA_TRANSFER: gnc_xfer_dialog_set_title( xfer_dialog, _("Online Banking European (SEPA) Transfer")); gnc_xfer_dialog_lock_from_account_tree(xfer_dialog); break; case SEPA_DEBITNOTE: gnc_xfer_dialog_set_title( xfer_dialog, _("Online Banking European (SEPA) Debit Note")); gnc_xfer_dialog_lock_to_account_tree(xfer_dialog); break; case SINGLE_TRANSFER: default: gnc_xfer_dialog_set_title( xfer_dialog, _("Online Banking Transaction")); gnc_xfer_dialog_lock_from_account_tree(xfer_dialog); } gnc_xfer_dialog_set_to_show_button_active(xfer_dialog, TRUE); amount = double_to_gnc_numeric( AB_Value_GetValueAsDouble(AB_Transaction_GetValue(ab_trans)), xaccAccountGetCommoditySCU(gnc_acc), GNC_HOW_RND_ROUND_HALF_UP); gnc_xfer_dialog_set_amount(xfer_dialog, amount); gnc_xfer_dialog_set_amount_sensitive(xfer_dialog, FALSE); gnc_xfer_dialog_set_date_sensitive(xfer_dialog, FALSE); 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) { /* Create a context to store possible results */ context = AB_ImExporterContext_new(); gui = gnc_GWEN_Gui_get(parent); if (!gui) { g_warning("gnc_ab_maketrans: Couldn't initialize Gwenhywfar GUI"); aborted = TRUE; goto repeat; } /* Finally, execute the job */ AB_Banking_ExecuteJobs(api, job_list, context #ifndef AQBANKING_VERSION_5_PLUS , 0 #endif ); /* Ignore the return value of AB_Banking_ExecuteJobs(), as the job's * status always describes better whether the job was actually * transferred to and accepted by the bank. See also * http://lists.gnucash.org/pipermail/gnucash-de/2008-September/006389.html */ job_status = AB_Job_GetStatus(job); if (job_status != AB_Job_StatusFinished && job_status != AB_Job_StatusPending) { successful = FALSE; if (!gnc_verify_dialog( parent, FALSE, "%s", _("An error occurred while executing the job. Please check " "the log window for the exact error message.\n" "\n" "Do you want to enter the job again?"))) { aborted = TRUE; } } else { successful = TRUE; } if (successful) { /* Import the results, awaiting nothing */ ieci = gnc_ab_import_context(context, 0, FALSE, NULL, parent); } } /* 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 (ieci) g_free(ieci); if (context) AB_ImExporterContext_free(context); if (job_list) { AB_Job_List2_free(job_list); job_list = NULL; } if (job) { AB_Job_free(job); job = NULL; } if (gui) { gnc_GWEN_Gui_release(gui); gui = NULL; } } while (!successful && !aborted); cleanup: if (td) gnc_ab_trans_dialog_free(td); if (online) #ifdef AQBANKING_VERSION_4_EXACTLY AB_Banking_OnlineFini(api, 0); #else AB_Banking_OnlineFini(api); #endif gnc_AB_BANKING_fini(api); }
static const AB_TRANSACTION * txn_transaction_cb(const AB_TRANSACTION *element, gpointer user_data) { GncABImExContextImport *data = user_data; Transaction *gnc_trans; GncABTransType trans_type; g_return_val_if_fail(element && data, NULL); /* Create a GnuCash transaction from ab_trans */ gnc_trans = gnc_ab_trans_to_gnc(element, data->gnc_acc); if (data->execute_txns && data->ab_acc) { AB_TRANSACTION *ab_trans = AB_Transaction_dup(element); AB_JOB *job; /* NEW: The imported transaction has been imported into gnucash. * Now also add it as a job to aqbanking */ AB_Transaction_SetLocalBankCode( ab_trans, AB_Account_GetBankCode(data->ab_acc)); AB_Transaction_SetLocalAccountNumber( ab_trans, AB_Account_GetAccountNumber(data->ab_acc)); AB_Transaction_SetLocalCountry(ab_trans, "DE"); switch (AB_Transaction_GetType(ab_trans)) { case AB_Transaction_TypeDebitNote: trans_type = SINGLE_DEBITNOTE; break; case AB_Transaction_TypeEuTransfer: trans_type = SEPA_TRANSFER; break; case AB_Transaction_TypeTransaction: /* trans_type = SINGLE_INTERNAL_TRANSFER; * break; */ case AB_Transaction_TypeTransfer: default: trans_type = SINGLE_TRANSFER; } /* switch */ job = gnc_ab_get_trans_job(data->ab_acc, ab_trans, trans_type); /* Check whether we really got a job */ if (!job || AB_Job_CheckAvailability(job #ifndef AQBANKING_VERSION_5_PLUS , 0 #endif )) { /* Oops, no job, probably not supported by bank */ if (gnc_verify_dialog( NULL, FALSE, "%s", _("The backend found an error during the preparation " "of the job. It is not possible to execute this job. \n" "\n" "Most probably 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?"))) { gnc_error_dialog(NULL, "Sorry, not implemented yet. Please check the console or trace file logs to see which job was rejected."); } } else { gnc_gen_trans_list_add_trans_with_ref_id(data->generic_importer, gnc_trans, AB_Job_GetJobId(job)); /* AB_Job_List2_PushBack(data->job_list, job); -> delayed until trans is successfully imported */ g_datalist_set_data(&data->tmp_job_list, gnc_AB_JOB_to_readable_string(job), job); } AB_Transaction_free(ab_trans); } else { /* Instead of xaccTransCommitEdit(gnc_trans) */ gnc_gen_trans_list_add_trans(data->generic_importer, gnc_trans); } return NULL; }
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; /* Check whether the account supports this job */ job = get_available_empty_job(td->ab_acc, td->trans_type); if (!job) { g_warning("gnc_ab_trans_dialog_run_until_ok: Oops, job not available"); 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 AB_IMEXPORTER_ACCOUNTINFO * bal_accountinfo_cb(AB_IMEXPORTER_ACCOUNTINFO *element, gpointer user_data) { GncABImExContextImport *data = user_data; Account *gnc_acc; AB_ACCOUNT_STATUS *item, *best = NULL; const GWEN_TIME *best_time = NULL; const AB_BALANCE *booked_bal, *noted_bal; const AB_VALUE *booked_val = NULL, *noted_val = NULL; gdouble booked_value, noted_value; gnc_numeric value; time64 booked_tt = 0; GtkWidget *dialog; gboolean show_recn_window = FALSE; g_return_val_if_fail(element && data, NULL); if (data->awaiting & IGNORE_BALANCES) /* Ignore them */ return NULL; if (!AB_ImExporterAccountInfo_GetFirstAccountStatus(element)) /* No balance found */ return NULL; else data->awaiting |= FOUND_BALANCES; /* Lookup the most recent ACCOUNT_STATUS available */ item = AB_ImExporterAccountInfo_GetFirstAccountStatus(element); while (item) { const GWEN_TIME *item_time = AB_AccountStatus_GetTime(item); if (!best || GWEN_Time_Diff(best_time, item_time) < 0.0) { best = item; best_time = item_time; } item = AB_ImExporterAccountInfo_GetNextAccountStatus(element); } booked_bal = AB_AccountStatus_GetBookedBalance(best); if (!(data->awaiting & AWAIT_BALANCES)) { /* Ignore zero balances if we don't await a balance */ if (!booked_bal || AB_Value_IsZero(AB_Balance_GetValue(booked_bal))) return NULL; /* Ask the user whether to import unawaited non-zero balance */ if (gnc_verify_dialog(data->parent, TRUE, "%s", _("The bank has sent balance information " "in its response." "\n" "Do you want to import it?"))) { data->awaiting |= AWAIT_BALANCES; } else { data->awaiting |= IGNORE_BALANCES; return NULL; } } /* Lookup the corresponding gnucash account */ gnc_acc = gnc_ab_accinfo_to_gnc_acc(element); if (!gnc_acc) return NULL; data->gnc_acc = gnc_acc; /* Lookup booked balance and time */ if (booked_bal) { const GWEN_TIME *ti = AB_Balance_GetTime(booked_bal); if (ti) { booked_tt = GWEN_Time_toTime_t(ti); } else { /* No time found? Use today because the HBCI query asked for today's * balance. */ booked_tt = gnc_time64_get_day_start(gnc_time(NULL)); } booked_val = AB_Balance_GetValue(booked_bal); if (booked_val) { booked_value = AB_Value_GetValueAsDouble(booked_val); } else { g_warning("bal_accountinfo_cb: booked_val == NULL. Assuming 0"); booked_value = 0.0; } } else { g_warning("bal_accountinfo_cb: booked_bal == NULL. Assuming 0"); booked_tt = 0; booked_value = 0.0; } /* Lookup noted balance */ noted_bal = AB_AccountStatus_GetNotedBalance(best); if (noted_bal) { noted_val = AB_Balance_GetValue(noted_bal); if (noted_val) noted_value = AB_Value_GetValueAsDouble(noted_val); else { g_warning("bal_accountinfo_cb: noted_val == NULL. Assuming 0"); noted_value = 0.0; } } else { g_warning("bal_accountinfo_cb: noted_bal == NULL. Assuming 0"); noted_value = 0.0; } value = double_to_gnc_numeric(booked_value, xaccAccountGetCommoditySCU(gnc_acc), GNC_HOW_RND_ROUND_HALF_UP); if (noted_value == 0.0 && booked_value == 0.0) { dialog = gtk_message_dialog_new( GTK_WINDOW(data->parent), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "%s", /* 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. */ _("The downloaded Online Banking Balance was zero.\n\n" "Either this is the correct balance, or your bank does not " "support Balance download in this Online Banking version. " "In the latter case you should choose a different " "Online Banking version number in the Online Banking " "(AqBanking or HBCI) Setup. After that, try again to " "download the Online Banking Balance.")); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } else { gnc_numeric reconc_balance = xaccAccountGetReconciledBalance(gnc_acc); gchar *booked_str = gnc_AB_VALUE_to_readable_string(booked_val); gchar *message1 = g_strdup_printf( _("Result of Online Banking job: \n" "Account booked balance is %s"), booked_str); gchar *message2 = (noted_value == 0.0) ? g_strdup("") : g_strdup_printf(_("For your information: This account also " "has a noted balance of %s\n"), gnc_AB_VALUE_to_readable_string(noted_val)); if (gnc_numeric_equal(value, reconc_balance)) { const gchar *message3 = _("The booked balance is identical to the current " "reconciled balance of the account."); dialog = gtk_message_dialog_new( GTK_WINDOW(data->parent), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "%s\n%s\n%s", message1, message2, message3); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(GTK_WIDGET(dialog)); } else { const char *message3 = _("Reconcile account now?"); show_recn_window = gnc_verify_dialog(data->parent, TRUE, "%s\n%s\n%s", message1, message2, message3); } g_free(booked_str); g_free(message1); g_free(message2); } /* Show reconciliation window */ if (show_recn_window) recnWindowWithBalance(data->parent, gnc_acc, value, booked_tt); return NULL; }
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 *old_name, *new_name; const gchar *old_account, *new_account; const gchar *old_bankcode, *new_bankcode; const gchar *old_purpose, *new_purpose; const gchar *old_purpose_cont, *new_purpose_cont; GtkWidget *amount_widget; const gchar *old_amount_text; gnc_numeric old_amount, new_amount; 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); /* Get old values */ old_name = gtk_entry_get_text(GTK_ENTRY(td->recp_name_entry)); old_account = gtk_entry_get_text(GTK_ENTRY(td->recp_account_entry)); old_bankcode = gtk_entry_get_text(GTK_ENTRY(td->recp_bankcode_entry)); old_purpose = gtk_entry_get_text(GTK_ENTRY(td->purpose_entry)); old_purpose_cont = gtk_entry_get_text(GTK_ENTRY(td->purpose_cont_entry)); amount_widget = gnc_amount_edit_gtk_entry(GNC_AMOUNT_EDIT(td->amount_edit)); old_amount_text = gtk_entry_get_text(GTK_ENTRY(amount_widget)); old_amount = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(td->amount_edit)); /* Get new values */ new_name = gnc_ab_trans_templ_get_recp_name(templ); new_account = gnc_ab_trans_templ_get_recp_account(templ); new_bankcode = gnc_ab_trans_templ_get_recp_bankcode(templ); new_purpose = gnc_ab_trans_templ_get_purpose(templ); new_purpose_cont = gnc_ab_trans_templ_get_purpose_cont(templ); new_amount = gnc_ab_trans_templ_get_amount(templ); if (!new_name) new_name = ""; if (!new_account) new_account = ""; if (!new_bankcode) new_bankcode = ""; if (!new_purpose) new_purpose = ""; if (!new_purpose_cont) new_purpose_cont = ""; /* Check for differences to avoid overwriting entered text */ if ((*old_name && strcmp(old_name, new_name)) || (*old_account && strcmp(old_account, new_account)) || (*old_bankcode && strcmp(old_bankcode, new_bankcode)) || (*old_purpose && strcmp(old_purpose, new_purpose)) || (*old_purpose_cont && strcmp(old_purpose_cont, new_purpose_cont)) || (*old_amount_text && !gnc_numeric_equal(old_amount, new_amount))) { if (!gnc_verify_dialog( td->parent, FALSE, _("Do you really want to overwrite your changes with the " "contents of the template \"%s\"?"), gnc_ab_trans_templ_get_name(templ))) { LEAVE("aborted"); return; } } /* Fill in */ gtk_entry_set_text(GTK_ENTRY(td->recp_name_entry), new_name); gtk_entry_set_text(GTK_ENTRY(td->recp_account_entry), new_account); gtk_entry_set_text(GTK_ENTRY(td->recp_bankcode_entry), new_bankcode); gtk_entry_set_text(GTK_ENTRY(td->purpose_entry), new_purpose); gtk_entry_set_text(GTK_ENTRY(td->purpose_cont_entry), new_purpose_cont); gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(td->amount_edit), new_amount); LEAVE(" "); }
static guint sxftd_add_template_trans(SXFromTransInfo *sxfti) { Transaction *tr = sxfti->trans; GList *tt_list = NULL; GList *splits, *template_splits = NULL; TTInfo *tti = gnc_ttinfo_malloc(); TTSplitInfo *ttsi; Split *sp; gnc_numeric runningBalance; gnc_numeric split_value; const char *tmpStr; runningBalance = gnc_numeric_zero(); gnc_ttinfo_set_description(tti, xaccTransGetDescription(tr)); gnc_ttinfo_set_num(tti, gnc_get_num_action(tr, NULL)); gnc_ttinfo_set_currency(tti, xaccTransGetCurrency(tr)); for (splits = xaccTransGetSplitList(tr); splits; splits = splits->next) { sp = splits->data; ttsi = gnc_ttsplitinfo_malloc(); gnc_ttsplitinfo_set_action(ttsi, gnc_get_num_action(NULL, sp)); split_value = xaccSplitGetValue(sp); gnc_ttsplitinfo_set_memo(ttsi, xaccSplitGetMemo(sp)); runningBalance = gnc_numeric_add( runningBalance, split_value, 100, (GNC_DENOM_AUTO | GNC_HOW_DENOM_LCD) ); if (gnc_numeric_positive_p(split_value)) { tmpStr = xaccPrintAmount( split_value, gnc_default_print_info(FALSE) ); gnc_ttsplitinfo_set_debit_formula( ttsi, tmpStr ); } else { /* Negate the numeric so it prints w/o the sign at the front. */ tmpStr = xaccPrintAmount( gnc_numeric_neg( split_value ), gnc_default_print_info(FALSE) ); gnc_ttsplitinfo_set_credit_formula( ttsi, tmpStr ); } /* Copy over per-split account info */ gnc_ttsplitinfo_set_account( ttsi, xaccSplitGetAccount( sp ) ); template_splits = g_list_append(template_splits, ttsi); } if ( ! gnc_numeric_zero_p( runningBalance ) && !gnc_verify_dialog( (GtkWidget *)sxfti->dialog, FALSE, "%s", _("The Scheduled Transaction Editor " "cannot automatically balance " "this transaction. " "Should it still be " "entered?") ) ) { return SXFTD_ERRNO_UNBALANCED_XACTION; } gnc_ttinfo_set_template_splits(tti, template_splits); tt_list = g_list_append(tt_list, tti); gnc_suspend_gui_refresh (); xaccSchedXactionSetTemplateTrans(sxfti->sx, tt_list, gnc_get_current_book ()); gnc_resume_gui_refresh (); return 0; }
int ofx_proc_transaction_cb(struct OfxTransactionData data, void * transaction_user_data) { char dest_string[255]; time64 current_time = gnc_time (NULL); Account *account; Account *investment_account = NULL; Account *income_account = NULL; gchar *investment_account_text, *investment_account_onlineid; gnc_commodity *currency = NULL; gnc_commodity *investment_commodity = NULL; gnc_numeric gnc_amount, gnc_units; QofBook *book; Transaction *transaction; Split *split; gchar *notes, *tmp; g_assert(gnc_ofx_importer_gui); if (!data.account_id_valid) { PERR("account ID for this transaction is unavailable!"); return 0; } account = gnc_import_select_account(gnc_gen_trans_list_widget(gnc_ofx_importer_gui), data.account_id, 0, NULL, NULL, ACCT_TYPE_NONE, NULL, NULL); if (account == NULL) { PERR("Unable to find account for id %s", data.account_id); return 0; } /***** Validate the input strings to ensure utf8 *****/ if (data.name_valid) gnc_utf8_strip_invalid(data.name); if (data.memo_valid) gnc_utf8_strip_invalid(data.memo); if (data.check_number_valid) gnc_utf8_strip_invalid(data.check_number); if (data.reference_number_valid) gnc_utf8_strip_invalid(data.reference_number); /***** Create the transaction and setup transaction data *******/ book = gnc_account_get_book(account); transaction = xaccMallocTransaction(book); xaccTransBeginEdit(transaction); /* Note: Unfortunately libofx <= 0.9.5 will not report a missing * date field as an invalid one. Instead, it will report it as * valid and return a completely bogus date. Starting with * libofx-0.9.6 (not yet released as of 2012-09-09), it will still * be reported as valid but at least the date integer itself is * just plain zero. */ if (data.date_posted_valid && (data.date_posted != 0)) { /* The hopeful case: We have a posted_date */ xaccTransSetDatePostedSecsNormalized(transaction, data.date_posted); } else if (data.date_initiated_valid && (data.date_initiated != 0)) { /* No posted date? Maybe we have an initiated_date */ xaccTransSetDatePostedSecsNormalized(transaction, data.date_initiated); } else { /* Uh no, no valid date. As a workaround use today's date */ xaccTransSetDatePostedSecsNormalized(transaction, current_time); } xaccTransSetDateEnteredSecs(transaction, current_time); /* Put transaction name in Description, or memo if name unavailable */ if (data.name_valid) { xaccTransSetDescription(transaction, data.name); } else if (data.memo_valid) { xaccTransSetDescription(transaction, data.memo); } /* Put everything else in the Notes field */ notes = g_strdup_printf("OFX ext. info: "); if (data.transactiontype_valid) { tmp = notes; notes = g_strdup_printf("%s%s%s", tmp, "|Trans type:", gnc_ofx_ttype_to_string(data.transactiontype)); g_free(tmp); } if (data.invtransactiontype_valid) { tmp = notes; notes = g_strdup_printf("%s%s%s", tmp, "|Investment Trans type:", gnc_ofx_invttype_to_str(data.invtransactiontype)); g_free(tmp); } if (data.memo_valid && data.name_valid) /* Copy only if memo wasn't put in Description */ { tmp = notes; notes = g_strdup_printf("%s%s%s", tmp, "|Memo:", data.memo); g_free(tmp); } if (data.date_funds_available_valid) { Timespec ts; timespecFromTime64(&ts, data.date_funds_available); gnc_timespec_to_iso8601_buff (ts, dest_string); tmp = notes; notes = g_strdup_printf("%s%s%s", tmp, "|Date funds available:", dest_string); g_free(tmp); } if (data.server_transaction_id_valid) { tmp = notes; notes = g_strdup_printf("%s%s%s", tmp, "|Server trans ID (conf. number):", data.server_transaction_id); g_free(tmp); } if (data.standard_industrial_code_valid) { tmp = notes; notes = g_strdup_printf("%s%s%ld", tmp, "|Standard Industrial Code:", data.standard_industrial_code); g_free(tmp); } if (data.payee_id_valid) { tmp = notes; notes = g_strdup_printf("%s%s%s", tmp, "|Payee ID:", data.payee_id); g_free(tmp); } //PERR("WRITEME: GnuCash ofx_proc_transaction():Add PAYEE and ADRESS here once supported by libofx! Notes=%s\n", notes); /* Ideally, gnucash should process the corrected transactions */ if (data.fi_id_corrected_valid) { PERR("WRITEME: GnuCash ofx_proc_transaction(): WARNING: This transaction corrected a previous transaction, but we created a new one instead!\n"); tmp = notes; notes = g_strdup_printf("%s%s%s%s", tmp, "|This corrects transaction #", data.fi_id_corrected, "but GnuCash didn't process the correction!"); g_free(tmp); } xaccTransSetNotes(transaction, notes); g_free(notes); if (data.account_ptr && data.account_ptr->currency_valid) { DEBUG("Currency from libofx: %s", data.account_ptr->currency); currency = gnc_commodity_table_lookup( gnc_get_current_commodities (), GNC_COMMODITY_NS_CURRENCY, data.account_ptr->currency); } else { DEBUG("Currency from libofx unavailable, defaulting to account's default"); currency = xaccAccountGetCommodity(account); } xaccTransSetCurrency(transaction, currency); if (data.amount_valid) { if (!data.invtransactiontype_valid) { /***** Process a normal transaction ******/ DEBUG("Adding split; Ordinary banking transaction, money flows from or into the source account"); split = xaccMallocSplit(book); xaccTransAppendSplit(transaction, split); xaccAccountInsertSplit(account, split); gnc_amount = gnc_ofx_numeric_from_double_txn(data.amount, transaction); xaccSplitSetBaseValue(split, gnc_amount, xaccTransGetCurrency(transaction)); /* set tran-num and/or split-action per book option */ if (data.check_number_valid) { gnc_set_num_action(transaction, split, data.check_number, NULL); } else if (data.reference_number_valid) { gnc_set_num_action(transaction, split, data.reference_number, NULL); } /* Also put the ofx transaction's memo in the * split's memo field */ if (data.memo_valid) { xaccSplitSetMemo(split, data.memo); } if (data.fi_id_valid) { gnc_import_set_split_online_id(split, data.fi_id); } } else if (data.unique_id_valid && data.security_data_valid && data.security_data_ptr != NULL && data.security_data_ptr->secname_valid) { gboolean choosing_account = TRUE; /********* Process an investment transaction **********/ /* Note that the ACCT_TYPE_STOCK account type should be replaced with something derived from data.invtranstype*/ // We have an investment transaction. First select the correct commodity. investment_commodity = gnc_import_select_commodity(data.unique_id, FALSE, NULL, NULL); if (investment_commodity != NULL) { // As we now have the commodity, select the account with that commodity. investment_account_text = g_strdup_printf( /* This string is a default account name. It MUST NOT contain the character ':' anywhere in it or in any translations. */ _("Stock account for security \"%s\""), data.security_data_ptr->secname); investment_account_onlineid = g_strdup_printf( "%s%s", data.account_id, data.unique_id); investment_account = gnc_import_select_account(NULL, investment_account_onlineid, 1, investment_account_text, investment_commodity, ACCT_TYPE_STOCK, NULL, NULL); // but use it only if that's really the right commodity if (investment_account && xaccAccountGetCommodity(investment_account) != investment_commodity) investment_account = NULL; // Loop until we either have an account, or the user pressed Cancel while (!investment_account && choosing_account) { // No account with correct commodity automatically found. // But are we in auto-create mode and already know a parent? if (auto_create_commodity && ofx_parent_account) { // Yes, so use that as parent when auto-creating the new account below. investment_account = ofx_parent_account; } else { // Let the user choose an account investment_account = gnc_import_select_account( gnc_gen_trans_list_widget(gnc_ofx_importer_gui), data.unique_id, TRUE, investment_account_text, investment_commodity, ACCT_TYPE_STOCK, NULL, &choosing_account); } // Does the chosen account have the right commodity? if (investment_account && xaccAccountGetCommodity(investment_account) != investment_commodity) { if (auto_create_commodity && xaccAccountTypesCompatible(xaccAccountGetType(investment_account), ACCT_TYPE_STOCK)) { // The user chose an account, but it does // not have the right commodity. Also, // auto-creation is on. Hence, we create a // new child account of the selected one, // and this one will have the right // commodity. Account *parent_account = investment_account; investment_account = gnc_ofx_new_account(investment_account_text, investment_commodity, parent_account, ACCT_TYPE_STOCK); if (investment_account) { gnc_import_set_acc_online_id(investment_account, data.unique_id); choosing_account = FALSE; ofx_parent_account = parent_account; } else { ofx_parent_account = NULL; } } else { // No account with matching commodity. Ask the user // whether to continue or abort. choosing_account = gnc_verify_dialog( gnc_gen_trans_list_widget(gnc_ofx_importer_gui), TRUE, "The chosen account \"%s\" does not have the correct " "currency/security \"%s\" (it has \"%s\" instead). " "This account cannot be used. " "Do you want to choose again?", xaccAccountGetName(investment_account), gnc_commodity_get_fullname(investment_commodity), gnc_commodity_get_fullname(xaccAccountGetCommodity(investment_account))); // We must also delete the online_id that was set in gnc_import_select_account() gnc_import_set_acc_online_id(investment_account, ""); investment_account = NULL; } } } if (!investment_account) { PERR("No investment account found for text: %s\n", investment_account_text); } g_free (investment_account_text); g_free (investment_account_onlineid); investment_account_text = NULL; if (investment_account != NULL && data.unitprice_valid && data.units_valid && ( data.invtransactiontype != OFX_INCOME ) ) { DEBUG("Adding investment split; Money flows from or into the stock account"); split = xaccMallocSplit(book); xaccTransAppendSplit(transaction, split); xaccAccountInsertSplit(investment_account, split); gnc_amount = gnc_ofx_numeric_from_double (ofx_get_investment_amount(&data), investment_commodity); gnc_units = gnc_ofx_numeric_from_double (data.units, investment_commodity); xaccSplitSetAmount(split, gnc_units); xaccSplitSetValue(split, gnc_amount); /* set tran-num and/or split-action per book option */ if (data.check_number_valid) { gnc_set_num_action(transaction, split, data.check_number, NULL); } else if (data.reference_number_valid) { gnc_set_num_action(transaction, split, data.reference_number, NULL); } if (data.security_data_ptr->memo_valid) { xaccSplitSetMemo(split, data.security_data_ptr->memo); } if (data.fi_id_valid) { gnc_import_set_split_online_id(split, data.fi_id); } } else { if (investment_account) PERR("The investment account, units or unitprice was not found for the investment transaction"); } } else { PERR("Commodity not found for the investment transaction"); } if (data.invtransactiontype_valid && investment_account) { if (data.invtransactiontype == OFX_REINVEST || data.invtransactiontype == OFX_INCOME) { DEBUG("Now let's find an account for the destination split"); income_account = gnc_ofx_kvp_get_assoc_account(investment_account); if (income_account == NULL) { DEBUG("Couldn't find an associated income account"); investment_account_text = g_strdup_printf( /* This string is a default account name. It MUST NOT contain the character ':' anywhere in it or in any translations. */ _("Income account for security \"%s\""), data.security_data_ptr->secname); income_account = gnc_import_select_account( gnc_gen_trans_list_widget(gnc_ofx_importer_gui), NULL, 1, investment_account_text, currency, ACCT_TYPE_INCOME, NULL, NULL); gnc_ofx_kvp_set_assoc_account(investment_account, income_account); DEBUG("KVP written"); } else { DEBUG("Found at least one associated income account"); } } if (income_account != NULL && data.invtransactiontype == OFX_REINVEST) { DEBUG("Adding investment split; Money flows from the income account"); split = xaccMallocSplit(book); xaccTransAppendSplit(transaction, split); xaccAccountInsertSplit(income_account, split); gnc_amount = gnc_ofx_numeric_from_double_txn (data.amount, transaction); xaccSplitSetBaseValue(split, gnc_amount, xaccTransGetCurrency(transaction)); // Set split memo from ofx transaction name or memo gnc_ofx_set_split_memo(&data, split); } if (income_account != NULL && data.invtransactiontype == OFX_INCOME) { DEBUG("Adding investment split; Money flows from the income account"); split = xaccMallocSplit(book); xaccTransAppendSplit(transaction, split); xaccAccountInsertSplit(income_account, split); gnc_amount = gnc_ofx_numeric_from_double_txn (-data.amount,/*OFX_INCOME amounts come in as positive numbers*/ transaction); xaccSplitSetBaseValue(split, gnc_amount, xaccTransGetCurrency(transaction)); // Set split memo from ofx transaction name or memo gnc_ofx_set_split_memo(&data, split); } } if (data.invtransactiontype_valid && data.invtransactiontype != OFX_REINVEST) { DEBUG("Adding investment split; Money flows from or to the cash account"); split = xaccMallocSplit(book); xaccTransAppendSplit(transaction, split); xaccAccountInsertSplit(account, split); gnc_amount = gnc_ofx_numeric_from_double_txn( -ofx_get_investment_amount(&data), transaction); xaccSplitSetBaseValue(split, gnc_amount, xaccTransGetCurrency(transaction)); // Set split memo from ofx transaction name or memo gnc_ofx_set_split_memo(&data, split); } } /* Send transaction to importer GUI. */ if (xaccTransCountSplits(transaction) > 0) { DEBUG("%d splits sent to the importer gui", xaccTransCountSplits(transaction)); gnc_gen_trans_list_add_trans (gnc_ofx_importer_gui, transaction); } else { PERR("No splits in transaction (missing account?), ignoring."); xaccTransDestroy(transaction); xaccTransCommitEdit(transaction); } } else { PERR("The transaction doesn't have a valid amount"); xaccTransDestroy(transaction); xaccTransCommitEdit(transaction); } return 0; }//end ofx_proc_transaction()