gint gsb_data_mix_get_account_number ( gint transaction_number, gboolean is_transaction ) { if ( is_transaction ) return ( gsb_data_transaction_get_account_number ( transaction_number ) ); else return (gsb_data_scheduled_get_account_number ( transaction_number ) ); }
/** * function called when the user come to the manually association page * update the list of transactions to associate and fill the labels * * \param assistant * \param new_page * * \return FALSE * */ gboolean gsb_assistant_reconcile_config_update_manu_asso ( GtkWidget *assistant, gint new_page ) { gchar *string; GSList *tmp_list; gint transaction_number; GtkListStore *store; /* update the string containing the number of transactions to link */ string = g_strdup_printf (_("Still %d transactions to link with a reconciliation."), transactions_to_link); gtk_label_set_text ( GTK_LABEL (label_transactions_to_link_3), string); g_free (string); gtk_misc_set_alignment ( GTK_MISC (label_transactions_to_link_3), 0, 0.5 ); /* fill the list with the transactions to link */ store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (treeview_transactions_to_link))); gtk_list_store_clear (GTK_LIST_STORE (store)); tmp_list = gsb_data_transaction_get_transactions_list (); while (tmp_list) { transaction_number = gsb_data_transaction_get_transaction_number (tmp_list -> data); if ( gsb_data_transaction_get_marked_transaction (transaction_number) == OPERATION_RAPPROCHEE && !gsb_data_transaction_get_reconcile_number (transaction_number)) { gchar *amount_str; gchar *date_str; GtkTreeIter iter; date_str = gsb_format_gdate (gsb_data_transaction_get_date (transaction_number)); amount_str = utils_real_get_string (gsb_data_transaction_get_amount (transaction_number)); gtk_list_store_append ( GTK_LIST_STORE (store), &iter ); gtk_list_store_set ( GTK_LIST_STORE (store), &iter, TRANSACTION_DATE, date_str, TRANSACTION_PAYEE, gsb_data_payee_get_name (gsb_data_transaction_get_party_number (transaction_number), TRUE), TRANSACTION_AMOUNT, amount_str, TRANSACTION_ACCOUNT, gsb_data_account_get_name (gsb_data_transaction_get_account_number (transaction_number)), TRANSACTION_NUMBER, transaction_number, -1 ); g_free (amount_str); g_free (date_str); } tmp_list = tmp_list -> next; } return FALSE; }
/** * finish the reconciliation, * called by a click on the finish button * * \param button * \param null * * \return FALSE */ gboolean gsb_reconcile_finish_reconciliation ( GtkWidget *button, gpointer null ) { GSList *list_tmp_transactions; GDate *date; gint account_number; gint reconcile_number; gsb_real real; gchar* tmpstr; account_number = gsb_gui_navigation_get_current_account (); if ( gsb_real_sub ( gsb_real_add ( utils_real_get_from_string (gtk_entry_get_text ( GTK_ENTRY ( reconcile_initial_balance_entry ))), gsb_data_account_calculate_waiting_marked_balance (account_number)), utils_real_get_from_string (gtk_entry_get_text ( GTK_ENTRY ( reconcile_final_balance_entry )))).mantissa != 0 ) { dialogue_warning_hint ( _("There is a variance in balances, check that both final balance and initial balance minus marked transactions are equal."), _("Reconciliation can't be completed.") ); return FALSE; } /* get and check the reconcile name */ reconcile_number = gsb_data_reconcile_get_number_by_name (gtk_entry_get_text ( GTK_ENTRY ( reconcile_number_entry ))); if (reconcile_number) { dialogue_warning_hint ( _("There is already a reconcile with that name, you must use another name or let it free.\nIf the reconcile name is ending by a number,\nit will be automatically incremented."), _("Reconciliation can't be completed.") ); return FALSE; } /* get and save the date */ date = gsb_calendar_entry_get_date (reconcile_new_date_entry); if (!date) { gchar* tmpstr = g_strdup_printf ( _("Invalid date: '%s'"), gtk_entry_get_text ( GTK_ENTRY ( reconcile_new_date_entry ))); dialogue_warning_hint ( tmpstr, _("Reconciliation can't be completed.") ); g_free ( tmpstr ); return FALSE; } if (!strlen (gtk_entry_get_text ( GTK_ENTRY ( reconcile_number_entry )))) { dialogue_warning_hint ( _("You need to set a name to the reconciliation ; at least, set a number,\nit will be automatically incremented later"), _("Reconciliation can't be completed.") ); return FALSE; } /* restore the good sort of the list */ if (transaction_list_sort_get_reconcile_sort ()) { gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON (reconcile_sort_list_button), FALSE ); gsb_reconcile_list_button_clicked (reconcile_sort_list_button, NULL); } tmpstr = g_strdup_printf ( _("Last statement: %s"), gsb_format_gdate (date)); gtk_label_set_text ( GTK_LABEL ( label_last_statement ), tmpstr); g_free ( tmpstr ); /* create the new reconcile structure */ reconcile_number = gsb_data_reconcile_new (gtk_entry_get_text (GTK_ENTRY (reconcile_number_entry))); gsb_data_reconcile_set_account ( reconcile_number, account_number ); /* set the variables of the reconcile */ gsb_data_reconcile_set_final_date ( reconcile_number, date ); g_date_free (date); date = gsb_parse_date_string (gtk_label_get_text (GTK_LABEL (reconcile_last_date_label))); gsb_data_reconcile_set_init_date ( reconcile_number, date ); g_free (date); real = utils_real_get_from_string ( gtk_entry_get_text ( GTK_ENTRY ( reconcile_initial_balance_entry ) ) ); gsb_data_reconcile_set_init_balance ( reconcile_number, real ); real = utils_real_get_from_string ( gtk_entry_get_text ( GTK_ENTRY ( reconcile_final_balance_entry ) ) ); gsb_data_reconcile_set_final_balance ( reconcile_number, real ); /* modify the reconciled transactions */ list_tmp_transactions = gsb_data_transaction_get_transactions_list (); while ( list_tmp_transactions ) { gint transaction_number_tmp; transaction_number_tmp = gsb_data_transaction_get_transaction_number ( list_tmp_transactions -> data); if ( gsb_data_transaction_get_account_number (transaction_number_tmp) == account_number && ( gsb_data_transaction_get_marked_transaction (transaction_number_tmp) == OPERATION_POINTEE || gsb_data_transaction_get_marked_transaction (transaction_number_tmp) == OPERATION_TELERAPPROCHEE )) { gsb_data_transaction_set_marked_transaction ( transaction_number_tmp, OPERATION_RAPPROCHEE ); gsb_data_transaction_set_reconcile_number ( transaction_number_tmp, reconcile_number ); } list_tmp_transactions = list_tmp_transactions -> next; } /* update the P and T to R in the list */ transaction_list_update_element (ELEMENT_MARK); run.mise_a_jour_liste_comptes_accueil = TRUE; /* go back to the normal transactions list */ gsb_reconcile_cancel (NULL, NULL); /* reset records in run: to do after gsb_reconcile_cancel */ g_free (run.reconcile_final_balance); if (run.reconcile_new_date) g_date_free (run.reconcile_new_date); run.reconcile_final_balance = NULL; run.reconcile_new_date = NULL; run.reconcile_account_number = -1; gsb_file_set_modified ( TRUE ); if ( reconcile_save_last_scheduled_convert ) { gsb_gui_navigation_set_selection ( GSB_SCHEDULER_PAGE, 0, NULL ); gsb_scheduler_list_select ( reconcile_save_last_scheduled_convert ); gsb_scheduler_list_edit_transaction ( reconcile_save_last_scheduled_convert ); reconcile_save_last_scheduled_convert = 0; } return FALSE; }
/** * function called when the user come to the automatically association page * fill the label and show the button if possible * * \param assistant * \param new_page * * \return FALSE * */ gboolean gsb_assistant_reconcile_config_update_auto_asso ( GtkWidget *assistant, gint new_page ) { gchar *string; GSList *tmp_list; gint associate_number; /* update the string containing the number of transactions to link */ string = g_strdup_printf (_("Still %d transactions to link with a reconciliation."), transactions_to_link); gtk_label_set_text ( GTK_LABEL (label_transactions_to_link_2), string); g_free (string); gtk_misc_set_alignment ( GTK_MISC (label_transactions_to_link_2), 0, 0.5 ); /* calculate how many transactions can be associated automatically, * to avoid to do that 2 times, we set each transactions in a structure with * the associated number of bank reconciliation */ if (list_association) { g_slist_free (list_association); list_association = NULL; } tmp_list = gsb_data_transaction_get_transactions_list (); while (tmp_list) { gint transaction_number; transaction_number = gsb_data_transaction_get_transaction_number (tmp_list -> data); if (gsb_data_transaction_get_marked_transaction (transaction_number) == OPERATION_RAPPROCHEE && !gsb_data_transaction_get_reconcile_number (transaction_number)) { /* ok we are on a marked R transaction without reconcile number, * we search for that reconcile */ gint reconcile_number; reconcile_number = gsb_data_reconcile_get_number_by_date (gsb_data_transaction_get_date (transaction_number), gsb_data_transaction_get_account_number (transaction_number)); if (reconcile_number) { struct association_transaction_reconcile *association; association = g_malloc0 (sizeof (struct association_transaction_reconcile)); if (!association) { dialogue_error_memory (); return FALSE; } association -> transaction_number = transaction_number; association -> reconcile_number = reconcile_number; list_association = g_slist_append ( list_association, association ); } } tmp_list = tmp_list -> next; } /* set the number of possible links */ associate_number = g_slist_length (list_association); if (associate_number) { string = g_strdup_printf (_("Grisbi can associate %d transactions to a reconciliation.\n" "Please click on the launch button to create the links."), associate_number); gtk_widget_set_sensitive ( button_run_association, TRUE ); } else { string = my_strdup (_("There is no transaction that Grisbi can link.\n" "Check if you created all the necesssary reconciliations.")); gtk_widget_set_sensitive ( button_run_association, FALSE ); } gtk_label_set_text ( GTK_LABEL (label_possible_association), string); g_free (string); return FALSE; }
/** * callback called by the button to launch the automatic association * between transactions and reconcile * * \param button * \param assistant * * \return FALSE * */ static gboolean gsb_assistant_reconcile_config_lauch_manu_asso ( GtkWidget *button, GtkWidget *assistant ) { GList *tmp_list; GtkTreeIter iter; GtkTreeModel *model; GtkTreeSelection *selection; GList *path_list; gint account_number = -1; GtkWidget *dialog; GtkWidget *label; GtkWidget *scrolled_window; GtkWidget *dialog_tree_view; GtkListStore *dialog_store; gint return_value; gint i; enum dialog_column { DIALOG_NAME = 0, DIALOG_INIT_DATE, DIALOG_FINAL_DATE, DIALOG_RECONCILE_NUMBER, DIALOG_NB_COL }; gint selected_reconcile_number; gint transaction_number; /* get the selection */ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview_transactions_to_link)); /* get the selected transactions */ path_list = gtk_tree_selection_get_selected_rows ( GTK_TREE_SELECTION (selection), &model ); if (!path_list) return FALSE; /* ok, we have a selection, before continuing, * we check that all the transactions are on the same account */ tmp_list = path_list; while (tmp_list) { GtkTreePath *path; path = tmp_list -> data; if (gtk_tree_model_get_iter ( GTK_TREE_MODEL (model), &iter, path )) { gtk_tree_model_get ( GTK_TREE_MODEL (model), &iter, TRANSACTION_NUMBER, &transaction_number, -1 ); if (account_number == -1) account_number = gsb_data_transaction_get_account_number (transaction_number); else { if (gsb_data_transaction_get_account_number (transaction_number) != account_number) { dialogue_error (_("All the selected transactions have to belong to the same account !")); /* erase the path_list */ g_list_foreach (path_list, (GFunc) gtk_tree_path_free, NULL); g_list_free (path_list); return FALSE; } } } tmp_list = tmp_list -> next; } if (account_number == -1) { /* erase the path_list */ g_list_foreach (path_list, (GFunc) gtk_tree_path_free, NULL); g_list_free (path_list); return FALSE; } /* ok, all the transactions belong to the same account, we can * show a dialog to select the reconcile */ dialog = gtk_dialog_new_with_buttons ( _("Selection of a reconciliation"), GTK_WINDOW ( assistant ), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, "gtk-cancel", GTK_RESPONSE_CANCEL, "gtk-ok", GTK_RESPONSE_OK, NULL ); gtk_window_set_default_size ( GTK_WINDOW ( dialog ), 770, 412 ); gtk_window_set_position ( GTK_WINDOW ( dialog ), GTK_WIN_POS_CENTER_ON_PARENT ); gtk_window_set_resizable ( GTK_WINDOW ( dialog ), TRUE ); gtk_container_set_border_width ( GTK_CONTAINER ( dialog ), 12 ); label = gtk_label_new ( _("Select the reconciliation to associate to the selected transactions: ") ); gtk_misc_set_alignment ( GTK_MISC ( label ), 0.0, 0.0 ); gtk_box_pack_start ( GTK_BOX ( dialog_get_content_area ( dialog ) ), label, FALSE, FALSE, 10 ); /* make the list */ scrolled_window = gtk_scrolled_window_new (FALSE, FALSE); gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC ); gtk_box_pack_start ( GTK_BOX ( dialog_get_content_area ( dialog ) ), scrolled_window, TRUE, TRUE, 0 ); dialog_store = gtk_list_store_new ( DIALOG_NB_COL, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT ); dialog_tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (dialog_store)); g_object_unref (G_OBJECT(dialog_store)); gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (dialog_tree_view), TRUE); gtk_container_add ( GTK_CONTAINER (scrolled_window), dialog_tree_view ); /* set the columns */ for (i=DIALOG_NAME ; i<DIALOG_RECONCILE_NUMBER ; i++) { GtkTreeViewColumn *column; GtkCellRenderer *cell; gchar *titles[] = { _("Reconciliation reference"), _("Initial date"), _("Final date") }; gfloat alignment[] = { COLUMN_LEFT, COLUMN_CENTER, COLUMN_CENTER }; cell = gtk_cell_renderer_text_new (); g_object_set ( G_OBJECT (cell), "xalign", alignment[i], NULL ); column = gtk_tree_view_column_new (); gtk_tree_view_column_set_sizing ( column, GTK_TREE_VIEW_COLUMN_AUTOSIZE ); gtk_tree_view_column_set_alignment ( column, alignment[i] ); gtk_tree_view_column_pack_start ( column, cell, TRUE ); gtk_tree_view_column_set_title ( column, titles[i] ); gtk_tree_view_column_set_attributes (column, cell, "text", i, NULL); gtk_tree_view_column_set_expand ( column, TRUE ); gtk_tree_view_column_set_resizable ( column, TRUE ); gtk_tree_view_append_column ( GTK_TREE_VIEW(dialog_tree_view), column); } /* fill the tree view */ tmp_list = gsb_data_reconcile_get_reconcile_list (); while (tmp_list) { gint reconcile_number; reconcile_number = gsb_data_reconcile_get_no_reconcile (tmp_list -> data); if (gsb_data_reconcile_get_account (reconcile_number) == account_number) { gchar *init_date_str; gchar *final_date_str; init_date_str = gsb_format_gdate (gsb_data_reconcile_get_init_date (reconcile_number)); final_date_str = gsb_format_gdate (gsb_data_reconcile_get_final_date (reconcile_number)); gtk_list_store_append ( GTK_LIST_STORE (dialog_store), &iter ); gtk_list_store_set ( GTK_LIST_STORE (dialog_store), &iter, DIALOG_NAME, gsb_data_reconcile_get_name (reconcile_number), DIALOG_INIT_DATE, init_date_str, DIALOG_FINAL_DATE, final_date_str, DIALOG_RECONCILE_NUMBER, reconcile_number, -1 ); g_free (init_date_str); g_free (final_date_str); } tmp_list = tmp_list -> next; } gtk_widget_show_all (dialog); /* launch the dialog */ return_value = gtk_dialog_run (GTK_DIALOG (dialog)); if (return_value != GTK_RESPONSE_OK) { gtk_widget_destroy (dialog); return FALSE; } /* we get the selected reconcile */ if (!gtk_tree_selection_get_selected ( gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog_tree_view)), NULL, &iter )) { dialogue_warning (_("No selection found, the transactions are not modified.")); gtk_widget_destroy (dialog); return FALSE; } gtk_tree_model_get ( GTK_TREE_MODEL (dialog_store), &iter, DIALOG_RECONCILE_NUMBER, &selected_reconcile_number, -1 ); /* ok we have the reconcile number, we can destroy the dialog */ gtk_widget_destroy (dialog); /* and now, fill the selected transactions with that reconcile number */ tmp_list = g_list_last (path_list); while (tmp_list) { GtkTreePath *path; path = tmp_list -> data; if (gtk_tree_model_get_iter ( GTK_TREE_MODEL (model), &iter, path )) { gtk_tree_model_get ( GTK_TREE_MODEL (model), &iter, TRANSACTION_NUMBER, &transaction_number, -1 ); gtk_list_store_remove ( GTK_LIST_STORE (model), &iter ); gsb_data_transaction_set_reconcile_number ( transaction_number, selected_reconcile_number ); transactions_to_link--; } tmp_list = tmp_list -> prev; } /* erase the path_list */ g_list_foreach (path_list, (GFunc) gtk_tree_path_free, NULL); g_list_free (path_list); /* now there is 2 way : * either transactions_to_link is 0, we go directly to the succes page * either it's not null, and the user should create more reconciles */ if (transactions_to_link) { gchar *string; /* update the labels */ string = g_strdup_printf (_("Still %d transactions to link with a reconciliation."), transactions_to_link); gtk_label_set_text ( GTK_LABEL (label_transactions_to_link_1), string); gtk_label_set_text ( GTK_LABEL (label_transactions_to_link_3), string); g_free (string); gtk_widget_grab_focus (treeview_transactions_to_link); } else { /* go to the success page */ gsb_assistant_set_next ( assistant, RECONCILE_ASSISTANT_MANUALLY_ASSOCIATE, RECONCILE_ASSISTANT_SUCCESS ); gsb_assistant_next_page (assistant); } return FALSE; }
/** * set the selection on the given transaction * * \param transaction_number the transaction to select * * \return FALSE if not possible (not visible), TRUE if ok * */ gboolean transaction_list_select ( gint transaction_number ) { CustomRecord *record = NULL; gboolean return_value; GtkTreePath *path; CustomList *custom_list; custom_list = transaction_model_get_model (); g_return_val_if_fail ( custom_list != NULL, FALSE ); /* fixes bug 1875 */ if (custom_list->num_visibles_rows == 0) return FALSE; /* if the selection didn't change, do nothing */ if ( gsb_data_transaction_get_transaction_number (custom_list -> selected_row) == transaction_number ) return FALSE; /* first, we un-select the last transaction */ if (custom_list -> selected_row) transaction_list_select_unselect (); /* if we want the white line, this will increase a little the speed */ if (transaction_number == -1) { record = custom_list -> visibles_rows [custom_list -> num_visibles_rows - custom_list -> nb_rows_by_transaction]; if (gsb_data_transaction_get_transaction_number (record -> transaction_pointer) != -1) record = NULL; } if (!record) { GtkTreeIter iter; if (!transaction_model_get_transaction_iter ( &iter, transaction_number, 0 )) return FALSE; record = iter.user_data; } /* si l'opération n'est pas visible on la rend visible */ if ( ( record -> mother_row && record -> mother_row -> filtered_pos == -1 ) || record -> filtered_pos == -1 ) { gint account_number; account_number = gsb_data_transaction_get_account_number ( transaction_number ); gsb_data_account_set_r ( account_number, TRUE ); gsb_menu_update_view_menu ( account_number ); mise_a_jour_affichage_r ( TRUE ); } return_value = transaction_list_select_record (record); /* if we are on a child, open the expander if necessary */ path = gtk_tree_path_new (); if (record -> mother_row) { gtk_tree_path_append_index (path, record -> mother_row -> filtered_pos); gtk_tree_view_expand_row ( GTK_TREE_VIEW (gsb_transactions_list_get_tree_view ()), path, FALSE ); } else gtk_tree_path_append_index (path, record -> filtered_pos); /* move the tree view to the selection */ gtk_tree_view_scroll_to_cell ( GTK_TREE_VIEW (gsb_transactions_list_get_tree_view ()), path, NULL, FALSE, 0.0, 0.0 ); gtk_tree_path_free (path); return return_value; }
/** that function delete the current account selected in the account properties * \param none * \return FALSE FALSE * */ gboolean gsb_account_delete ( void ) { gint deleted_account; gint page_number; GSList *list_tmp; gchar* tmpstr; deleted_account = gsb_gui_navigation_get_current_account (); tmpstr = g_strdup_printf (_("Delete account \"%s\"?"), gsb_data_account_get_name ( deleted_account ) ) ; if ( !question_yes_no_hint ( tmpstr, _("This will irreversibly remove this account and all operations " "that were previously contained. There is no undo for this. " "Usually it's a better way to close an account."), GTK_RESPONSE_NO )) { g_free ( tmpstr ); return FALSE; } g_free ( tmpstr ); /* if the last account, close the file */ if ( gsb_data_account_get_accounts_amount () == 1 ) { gsb_file_set_modified ( FALSE ); gsb_file_close (); return FALSE; } /* delete the schedules transactions on that account */ list_tmp = gsb_data_scheduled_get_scheduled_list (); while (list_tmp) { gint scheduled_number; scheduled_number = gsb_data_scheduled_get_scheduled_number ( list_tmp -> data ); if ( gsb_data_scheduled_get_account_number (scheduled_number) == deleted_account ) gsb_data_scheduled_remove_scheduled (scheduled_number); list_tmp = list_tmp -> next; } /* remove all the transactions of that account */ list_tmp = gsb_data_transaction_get_complete_transactions_list (); while (list_tmp) { gint transaction_number; transaction_number = gsb_data_transaction_get_transaction_number ( list_tmp -> data ); /* better to go to the next transaction now */ list_tmp = list_tmp -> next; if (gsb_data_transaction_get_account_number (transaction_number) == deleted_account) { gint contra_transaction_number; /* we are on a transaction on the deleted account, we delete that transaction, * but if it's a transfer, modify the contra-transaction to set transfer to deleted account */ contra_transaction_number = gsb_data_transaction_get_contra_transaction_number ( transaction_number); if (contra_transaction_number > 0) /* it's a transfer, modify the contra-transaction */ gsb_data_transaction_set_contra_transaction_number ( contra_transaction_number, -1); /* now can remove the transaction */ gsb_data_transaction_remove_transaction_without_check ( transaction_number ); } } /* delete the payment_number */ list_tmp = gsb_data_account_get_sort_list ( deleted_account ); while (list_tmp) { gpointer ptr; gint payment_number; ptr = list_tmp -> data; payment_number = GPOINTER_TO_INT ( ptr ); gsb_data_payment_remove ( payment_number ); list_tmp = list_tmp -> next; } /* delete the account */ gsb_data_account_delete ( deleted_account ); /* check gsb_gui_navigation_get_current_account () and gsb_gui_navigation_get_current_account ()_onglet and put them * on the first account if they are on the deleted account */ if ( gsb_gui_navigation_get_current_account () == deleted_account ) { GtkWidget *notebook_general; /* update the transaction list */ notebook_general = gsb_gui_get_general_notebook ( ); page_number = gtk_notebook_get_current_page ( GTK_NOTEBOOK ( notebook_general ) ); navigation_change_account ( gsb_data_account_first_number () ); gtk_notebook_set_current_page ( GTK_NOTEBOOK ( notebook_general ), page_number ); } /* update the buttons lists */ gsb_menu_update_accounts_in_menus(); /* Replace trees contents. */ categories_fill_list (); budgetary_lines_fill_list (); payees_fill_list (); /* update the categories in lists */ transaction_list_update_element (ELEMENT_CATEGORY); /* update the name of accounts in form */ gsb_account_update_combo_list ( gsb_form_scheduler_get_element_widget (SCHEDULED_FORM_ACCOUNT), FALSE ); gsb_scheduler_list_fill_list (gsb_scheduler_list_get_tree_view ()); mise_a_jour_liste_echeances_manuelles_accueil = 1; mise_a_jour_liste_comptes_accueil = 1; mise_a_jour_soldes_minimaux = 1; mise_a_jour_fin_comptes_passifs = 1; /* Update navigation pane. */ gsb_gui_navigation_remove_account ( deleted_account ); gsb_file_set_modified ( TRUE ); return FALSE; }
/** * create a qif export, according to the filename, the account * and eventually, limit the export to the archive if exists * this will export all the transactions of the account (except if we ask for an archive...) * including the archived transactions * * \param filename that file will be checked and ask to overwrite if needed * \param account_nb * \param archive_number if 0, just export in qif the account transactions ; if non 0, export just the transactions for that archive and account * * \return TRUE ok, FALSE pb */ gboolean qif_export ( const gchar *filename, gint account_nb, gint archive_number ) { FILE * fichier_qif; GSList *list_tmp_transactions; gint beginning; gint floating_point; gchar* tmpstr; if (!gsb_file_util_test_overwrite (filename)) return FALSE; if ( !( fichier_qif = utf8_fopen ( filename, "w" ) )) { dialogue_error_hint ( g_strerror(errno), g_strdup_printf ( _("Error opening file '%s'"), filename ) ); return FALSE; } /* get the floating point of the currency of the amount, * ie the number of digits after the . */ floating_point = gsb_data_currency_get_floating_point (gsb_data_account_get_currency (account_nb)); /* kind of account */ if ( gsb_data_account_get_kind (account_nb) == GSB_TYPE_CASH ) fprintf ( fichier_qif, "!Type:Cash\n" ); else if ( gsb_data_account_get_kind (account_nb) == GSB_TYPE_LIABILITIES || gsb_data_account_get_kind (account_nb) == GSB_TYPE_ASSET ) fprintf ( fichier_qif, "!Type:Oth L\n" ); else fprintf ( fichier_qif, "!Type:Bank\n" ); list_tmp_transactions = gsb_data_transaction_get_complete_transactions_list (); beginning = 1; while ( list_tmp_transactions ) { gint transaction_number_tmp; transaction_number_tmp = gsb_data_transaction_get_transaction_number (list_tmp_transactions -> data); if ( gsb_data_transaction_get_account_number (transaction_number_tmp) == account_nb && (!archive_number || gsb_data_transaction_get_archive_number (transaction_number_tmp) == archive_number)) { if ( beginning ) { /* this is the beginning of the qif file, we set some beginnings things */ fprintf ( fichier_qif, "D%d/%d/%d\n", g_date_get_day (gsb_data_transaction_get_date (transaction_number_tmp)), g_date_get_month (gsb_data_transaction_get_date (transaction_number_tmp)), g_date_get_year (gsb_data_transaction_get_date (transaction_number_tmp))); /* met le solde initial */ tmpstr = utils_real_get_string (gsb_data_account_get_init_balance (account_nb, -1)); fprintf ( fichier_qif, "T%s\n", tmpstr); g_free ( tmpstr ); fprintf ( fichier_qif, "CX\nPOpening Balance\n" ); /* met le nom du imported_account */ fprintf ( fichier_qif, "L%s\n^\n", g_strconcat ( "[", gsb_data_account_get_name (account_nb), "]", NULL ) ); beginning = 0; } /* si c'est une opé de ventil, on la saute pas elle sera recherchée quand */ /* son opé ventilée sera exportée */ if ( !gsb_data_transaction_get_mother_transaction_number ( transaction_number_tmp)) { /* met la date */ fprintf ( fichier_qif, "D%d/%d/%d\n", g_date_get_day (gsb_data_transaction_get_date (transaction_number_tmp)), g_date_get_month (gsb_data_transaction_get_date (transaction_number_tmp)), g_date_get_year (gsb_data_transaction_get_date (transaction_number_tmp))); /* met le pointage */ if ( gsb_data_transaction_get_marked_transaction ( transaction_number_tmp)== OPERATION_POINTEE || gsb_data_transaction_get_marked_transaction ( transaction_number_tmp)== OPERATION_TELERAPPROCHEE ) fprintf ( fichier_qif, "C*\n" ); else if ( gsb_data_transaction_get_marked_transaction ( transaction_number_tmp)== OPERATION_RAPPROCHEE ) fprintf ( fichier_qif, "CX\n" ); /* met les notes */ if ( gsb_data_transaction_get_notes ( transaction_number_tmp)) fprintf ( fichier_qif, "M%s\n", gsb_data_transaction_get_notes ( transaction_number_tmp)); /* met le montant, transforme la devise si necessaire */ tmpstr = utils_real_get_string (gsb_data_transaction_get_adjusted_amount ( transaction_number_tmp, floating_point)); fprintf ( fichier_qif, "T%s\n", tmpstr); g_free ( tmpstr ); /* met le chèque si c'est un type à numérotation automatique */ if ( gsb_data_payment_get_automatic_numbering (gsb_data_transaction_get_method_of_payment_number (transaction_number_tmp))) fprintf ( fichier_qif, "N%s\n", gsb_data_transaction_get_method_of_payment_content ( transaction_number_tmp)); /* met le tiers */ fprintf ( fichier_qif, "P%s\n", gsb_data_payee_get_name ( gsb_data_transaction_get_party_number ( transaction_number_tmp), FALSE )); /* on met soit un virement, soit une ventil, soit les catégories */ /* si c'est une imported_splitted, on recherche toutes les opés de cette imported_splitted */ /* et les met à la suite */ /* la catégorie de l'opé sera celle de la première opé de imported_splitted */ if ( gsb_data_transaction_get_split_of_transaction ( transaction_number_tmp)) { /* it's a split of transactions, look for the children and append them */ gint mother_transaction_category_written; GSList *list_tmp_transactions_2; mother_transaction_category_written = 0; list_tmp_transactions_2 = gsb_data_transaction_get_transactions_list (); while ( list_tmp_transactions_2 ) { gint transaction_number_tmp_2; transaction_number_tmp_2 = gsb_data_transaction_get_transaction_number (list_tmp_transactions_2 -> data); if (gsb_data_transaction_get_mother_transaction_number (transaction_number_tmp_2) == transaction_number_tmp) { /* we are on a child, for the first one, we set the mother category */ /* the child can only be a normal category or a transfer */ if ( gsb_data_transaction_get_contra_transaction_number (transaction_number_tmp_2) > 0) { /* the child is a transfer */ if ( !mother_transaction_category_written ) { fprintf ( fichier_qif, "L%s\n", g_strconcat ( "[", gsb_data_account_get_name (gsb_data_transaction_get_contra_transaction_account (transaction_number_tmp_2)), "]", NULL )); mother_transaction_category_written = 1; } fprintf ( fichier_qif, "S%s\n", g_strconcat ( "[", gsb_data_account_get_name (gsb_data_transaction_get_contra_transaction_account ( transaction_number_tmp_2)), "]", NULL )); } else { /* it's a category : sub-category */ if ( !mother_transaction_category_written ) { fprintf ( fichier_qif, "L%s\n", gsb_data_category_get_name (gsb_data_transaction_get_category_number (transaction_number_tmp_2), gsb_data_transaction_get_sub_category_number (transaction_number_tmp_2), _("No category defined"))); mother_transaction_category_written = 1; } fprintf ( fichier_qif, "S%s\n", gsb_data_category_get_name (gsb_data_transaction_get_category_number (transaction_number_tmp_2), gsb_data_transaction_get_sub_category_number (transaction_number_tmp_2), _("No category defined"))); } /* set the notes of the split child */ if ( gsb_data_transaction_get_notes (transaction_number_tmp_2)) fprintf ( fichier_qif, "E%s\n", gsb_data_transaction_get_notes (transaction_number_tmp_2)); /* set the amount of the split child */ tmpstr = utils_real_get_string (gsb_data_transaction_get_adjusted_amount (transaction_number_tmp_2, floating_point)); fprintf ( fichier_qif, "$%s\n", tmpstr); g_free ( tmpstr ); } list_tmp_transactions_2 = list_tmp_transactions_2 -> next; } } else { /* if it's a transfer, the contra-account must exist, else we do * as for a normal category */ if ( gsb_data_transaction_get_contra_transaction_number (transaction_number_tmp) > 0 ) { /* it's a transfer */ fprintf ( fichier_qif, "L%s\n", g_strconcat ( "[", gsb_data_account_get_name (gsb_data_transaction_get_contra_transaction_account ( transaction_number_tmp)), "]", NULL )); } else { /* it's a normal category */ fprintf ( fichier_qif, "L%s\n", gsb_data_category_get_name (gsb_data_transaction_get_category_number (transaction_number_tmp), gsb_data_transaction_get_sub_category_number (transaction_number_tmp), FALSE )); } } fprintf ( fichier_qif, "^\n" ); } } list_tmp_transactions = list_tmp_transactions -> next; } if ( beginning ) { /* there is no transaction in the account, so do the opening of the account, bug no date */ /* met le solde initial */ gchar* tmpstr = utils_real_get_string (gsb_data_account_get_init_balance (account_nb, -1)); fprintf ( fichier_qif, "T%s\n", tmpstr); g_free ( tmpstr ); fprintf ( fichier_qif, "CX\nPOpening Balance\n" ); /* met le nom du imported_account */ fprintf ( fichier_qif, "L%s\n^\n", g_strconcat ( "[", gsb_data_account_get_name (account_nb), "]", NULL ) ); } fclose ( fichier_qif ); return TRUE; }
/** * export a transaction given in param in the file given in param * * \param transaction_number * \param csv_file * \param print_balance will set a balance for each transaction in the csv file * not set for archive export, set (but usefull ?) for account export * * \return TRUE ok, FALSE problem * */ static gboolean gsb_csv_export_transaction ( gint transaction_number, FILE *csv_file, gboolean print_balance ) { gsb_real amount; gint return_exponent; gint account_number; gchar* tmpstr; const GDate *value_date, *date; gint payment_method; account_number = gsb_data_transaction_get_account_number (transaction_number); /* Si c'est une ventilation d'opération (càd une opération fille), elle n'est pas traitée à la base du "if" mais plus loin, quand son opé ventilée sera exportée */ if ( gsb_data_transaction_get_mother_transaction_number (transaction_number) ) return TRUE; return_exponent = gsb_data_currency_get_floating_point ( gsb_data_account_get_currency (account_number)); /* met la date */ date = gsb_data_transaction_get_date ( transaction_number ); if ( date ) { CSV_CLEAR_FIELD (csv_field_date); csv_field_date = g_strdup_printf ("%d/%d/%d", g_date_get_day ( date ), g_date_get_month ( date ), g_date_get_year ( date ) ); } value_date = gsb_data_transaction_get_value_date ( transaction_number ); if ( value_date ) { CSV_CLEAR_FIELD (csv_field_date_val); csv_field_date_val = g_strdup_printf ("%d/%d/%d", g_date_get_day ( value_date ), g_date_get_month ( value_date ), g_date_get_year ( value_date ) ); } /* met le pointage */ CSV_CLEAR_FIELD (csv_field_pointage); switch ( gsb_data_transaction_get_marked_transaction ( transaction_number ) ) { case OPERATION_NORMALE: csv_field_pointage = my_strdup (""); break; case OPERATION_POINTEE: csv_field_pointage = my_strdup ("P"); break; case OPERATION_TELERAPPROCHEE: csv_field_pointage = my_strdup ("T"); break; case OPERATION_RAPPROCHEE: csv_field_pointage = my_strdup ("R"); break; } /* met les notes */ CSV_CLEAR_FIELD(csv_field_notes); if ( gsb_data_transaction_get_notes ( transaction_number ) ) csv_field_notes = my_strdup (gsb_data_transaction_get_notes ( transaction_number )); /* met le tiers */ CSV_CLEAR_FIELD(csv_field_tiers); csv_field_tiers = g_strdup ( gsb_data_payee_get_name ( gsb_data_transaction_get_party_number ( transaction_number ), FALSE ) ); /* met le numero du rapprochement */ if ( gsb_data_transaction_get_reconcile_number ( transaction_number ) ) { CSV_CLEAR_FIELD (csv_field_rappro); csv_field_rappro = my_strdup ( gsb_data_reconcile_get_name ( gsb_data_transaction_get_reconcile_number ( transaction_number ) ) ); } /* Met les informations bancaires de l'opération. Elles n'existent qu'au niveau de l'opération mère */ CSV_CLEAR_FIELD(csv_field_info_bank); if ( gsb_data_transaction_get_bank_references ( transaction_number ) ) { csv_field_info_bank = my_strdup ( gsb_data_transaction_get_bank_references ( transaction_number ) ); } /* met le montant, transforme la devise si necessaire */ amount = gsb_data_transaction_get_adjusted_amount ( transaction_number, return_exponent); CSV_CLEAR_FIELD (csv_field_credit); if (amount.mantissa >= 0 ) csv_field_credit = utils_real_get_string (amount); else csv_field_debit = utils_real_get_string (gsb_real_abs (amount)); /* met le cheque si c'est un type à numerotation automatique */ payment_method = gsb_data_transaction_get_method_of_payment_number ( transaction_number ); CSV_CLEAR_FIELD (csv_field_cheque); if (gsb_data_payment_get_automatic_numbering (payment_method)) csv_field_cheque = my_strdup ( gsb_data_transaction_get_method_of_payment_content ( transaction_number ) ); if ( gsb_data_transaction_get_budgetary_number ( transaction_number ) != -1 ) { CSV_CLEAR_FIELD (csv_field_imput); csv_field_imput = my_strdup ( gsb_data_budget_get_name ( gsb_data_transaction_get_budgetary_number ( transaction_number ), 0, "" ) ); if ( gsb_data_transaction_get_sub_budgetary_number ( transaction_number ) != -1 ) { CSV_CLEAR_FIELD (csv_field_sous_imput); csv_field_sous_imput = my_strdup ( gsb_data_budget_get_sub_budget_name ( gsb_data_transaction_get_budgetary_number ( transaction_number ), gsb_data_transaction_get_sub_budgetary_number ( transaction_number ), NULL ) ); } } /* Piece comptable */ CSV_CLEAR_FIELD (csv_field_piece); csv_field_piece = my_strdup ( gsb_data_transaction_get_voucher ( transaction_number ) ); /* Balance */ if (print_balance) { current_balance = gsb_real_add ( current_balance, amount ); CSV_CLEAR_FIELD (csv_field_solde); csv_field_solde = utils_real_get_string (current_balance); } /* Number */ CSV_CLEAR_FIELD (csv_field_operation); csv_field_operation = g_strdup_printf("%d", transaction_number ); /* Account name */ CSV_CLEAR_FIELD (csv_field_account); csv_field_account = my_strdup (gsb_data_account_get_name (account_number)); /* Financial Year */ if ( gsb_data_transaction_get_financial_year_number ( transaction_number ) != -1 ) { CSV_CLEAR_FIELD (csv_field_exercice ); csv_field_exercice = my_strdup (gsb_data_fyear_get_name(gsb_data_transaction_get_financial_year_number ( transaction_number ))); } /* on met soit un virement, soit une ventilation, soit les catégories */ /* Si c'est une opération ventilée, on recherche toutes les ventilations de cette opération et on les traite immédiatement. */ /* et les met à la suite */ /* la catégorie de l'opé sera celle de la première opé de ventilation */ if ( gsb_data_transaction_get_split_of_transaction ( transaction_number ) ) { GSList *pSplitTransactionList; CSV_CLEAR_FIELD (csv_field_categ); csv_field_categ = my_strdup (_("Split of transaction")); csv_add_record(csv_file,FALSE, print_balance); pSplitTransactionList = gsb_data_transaction_get_transactions_list (); while ( pSplitTransactionList ) { gint pSplitTransaction; pSplitTransaction = gsb_data_transaction_get_transaction_number ( pSplitTransactionList -> data ); if ( gsb_data_transaction_get_account_number ( pSplitTransaction ) == gsb_data_transaction_get_account_number (transaction_number) && gsb_data_transaction_get_mother_transaction_number ( pSplitTransaction ) == transaction_number ) { /* on commence par mettre la catég et sous categ de l'opé et de l'opé de ventilation */ CSV_CLEAR_FIELD (csv_field_ventil); csv_field_ventil = my_strdup (_("B")); /* -> mark */ CSV_CLEAR_FIELD (csv_field_operation); csv_field_operation = g_strdup_printf("%d", pSplitTransaction ); if ( gsb_data_transaction_get_contra_transaction_number ( pSplitTransaction ) > 0) { /* c'est un virement */ CSV_CLEAR_FIELD (csv_field_categ); csv_field_categ = my_strdup (_("Transfer")); tmpstr = g_strconcat ( "[", gsb_data_account_get_name ( gsb_data_transaction_get_contra_transaction_account ( pSplitTransaction ) ), "]", NULL ); /* TODO dOm : is it necessary to duplicate memory with my_strdup since it was already newly allocated memory ? */ CSV_CLEAR_FIELD (csv_field_sous_categ); csv_field_sous_categ = my_strdup (tmpstr); g_free ( tmpstr ); } else { if ( gsb_data_transaction_get_category_number ( pSplitTransaction ) != -1 ) { CSV_CLEAR_FIELD (csv_field_categ); csv_field_categ = my_strdup ( gsb_data_category_get_name ( gsb_data_transaction_get_category_number ( pSplitTransaction ), 0, "" ) ); if ( gsb_data_transaction_get_sub_category_number ( pSplitTransaction ) != -1 ) { CSV_CLEAR_FIELD (csv_field_sous_categ); csv_field_sous_categ = my_strdup ( gsb_data_category_get_sub_category_name ( gsb_data_transaction_get_category_number ( pSplitTransaction ), gsb_data_transaction_get_sub_category_number ( pSplitTransaction ), NULL ) ); } } } /* met les notes de la ventilation */ if ( gsb_data_transaction_get_notes ( pSplitTransaction ) ) { CSV_CLEAR_FIELD (csv_field_notes); csv_field_notes = my_strdup (gsb_data_transaction_get_notes ( pSplitTransaction )); } /* met le montant de la ventilation */ amount = gsb_data_transaction_get_adjusted_amount ( pSplitTransaction, return_exponent ); CSV_CLEAR_FIELD (csv_field_montant); csv_field_montant = utils_real_get_string (amount); /* met le rapprochement */ if ( gsb_data_transaction_get_reconcile_number ( pSplitTransaction ) ) { CSV_CLEAR_FIELD (csv_field_rappro); csv_field_rappro = my_strdup ( gsb_data_reconcile_get_name ( gsb_data_transaction_get_reconcile_number ( pSplitTransaction ) ) ); } /* met le chèque si c'est un type à numéotation automatique */ payment_method = gsb_data_transaction_get_method_of_payment_number ( pSplitTransaction ); if (gsb_data_payment_get_automatic_numbering (payment_method)) { CSV_CLEAR_FIELD (csv_field_cheque); csv_field_cheque = my_strdup ( gsb_data_transaction_get_method_of_payment_content ( pSplitTransaction ) ); } /* Budgetary lines */ if ( gsb_data_transaction_get_budgetary_number ( pSplitTransaction ) != -1 ) { CSV_CLEAR_FIELD (csv_field_imput); csv_field_imput = my_strdup ( gsb_data_budget_get_name ( gsb_data_transaction_get_budgetary_number ( pSplitTransaction ), 0, "" ) ); if ( gsb_data_transaction_get_sub_budgetary_number ( pSplitTransaction ) != -1 ) { CSV_CLEAR_FIELD (csv_field_sous_imput); csv_field_sous_imput = my_strdup ( gsb_data_budget_get_sub_budget_name ( gsb_data_transaction_get_budgetary_number ( pSplitTransaction ), gsb_data_transaction_get_sub_budgetary_number ( pSplitTransaction ), NULL ) ); } } /* Piece comptable */ CSV_CLEAR_FIELD (csv_field_piece); csv_field_piece = my_strdup ( gsb_data_transaction_get_voucher ( pSplitTransaction ) ); /* Financial Year */ if ( gsb_data_transaction_get_financial_year_number ( pSplitTransaction ) != -1 ) { CSV_CLEAR_FIELD (csv_field_exercice ); csv_field_exercice = my_strdup (gsb_data_fyear_get_name(gsb_data_transaction_get_financial_year_number ( pSplitTransaction ))); } csv_add_record(csv_file,FALSE, print_balance); } pSplitTransactionList = pSplitTransactionList -> next; } csv_clear_fields(TRUE); } else { gchar *tmpstr; gint contra_transaction_number = gsb_data_transaction_get_contra_transaction_number ( transaction_number ); switch (contra_transaction_number) { case 0: /* normal category */ if ( gsb_data_transaction_get_category_number ( transaction_number ) != -1 ) { CSV_CLEAR_FIELD (csv_field_categ); csv_field_categ = my_strdup ( gsb_data_category_get_name ( gsb_data_transaction_get_category_number ( transaction_number ), 0, "" ) ); if ( gsb_data_transaction_get_sub_category_number ( transaction_number ) != -1 ) { CSV_CLEAR_FIELD (csv_field_sous_categ); csv_field_sous_categ = my_strdup ( gsb_data_category_get_sub_category_name ( gsb_data_transaction_get_category_number ( transaction_number ), gsb_data_transaction_get_sub_category_number ( transaction_number ), NULL ) ); } } break; case -1: /* transfer to deleted account */ CSV_CLEAR_FIELD (csv_field_categ); csv_field_categ = my_strdup (_("Transfer")); tmpstr = g_strconcat ( "[", _("Deleted account"), "]", NULL ); /* TODO dOm : is it necessary to duplicate memory with my_strdup since it was already newly allocated memory ? */ CSV_CLEAR_FIELD (csv_field_sous_categ); csv_field_sous_categ = my_strdup (tmpstr); g_free ( tmpstr ); break; default: /* transfer */ CSV_CLEAR_FIELD (csv_field_categ); csv_field_categ = my_strdup (_("Transfer")); tmpstr = g_strconcat ( "[", gsb_data_account_get_name ( gsb_data_transaction_get_contra_transaction_account ( transaction_number ) ), "]", NULL ); /* TODO dOm : is it necessary to duplicate memory with my_strdup since it was already newly allocated memory ? */ CSV_CLEAR_FIELD (csv_field_sous_categ); csv_field_sous_categ = my_strdup (tmpstr); g_free ( tmpstr ); } csv_add_record(csv_file,TRUE, print_balance); } return TRUE; }
/** * export an account into a csv file * * \param filename * \param account_nb the account to export * * \return TRUE if ok, FALSE if problem * */ gboolean gsb_csv_export_account ( const gchar *filename, gint account_number ) { FILE *csv_file; GSList *pTransactionList; GSList *tmp_list; csv_file = gsb_csv_export_open_file ( filename ); if ( !csv_file ) return FALSE; if ( g_csv_with_title_line ) gsb_csv_export_title_line ( csv_file, TRUE ); /* set the initial balance */ if ( csv_field_tiers ) g_free ( csv_field_tiers ); csv_field_tiers = g_strconcat (_("Initial balance") , " [", gsb_data_account_get_name ( account_number ), "]", NULL ); /* set the initial current_balance, * as we will write all the non archived transactions, * we need to get the initial balance of the account, without the archived transactions */ current_balance = gsb_data_account_get_init_balance ( account_number, -1); tmp_list = gsb_data_archive_store_get_archives_list ( ); while ( tmp_list ) { gint archive_store_number; archive_store_number = gsb_data_archive_store_get_number ( tmp_list -> data ); if ( gsb_data_archive_store_get_account_number ( archive_store_number ) == account_number ) current_balance = gsb_real_add ( current_balance, gsb_data_archive_store_get_balance ( archive_store_number ) ); tmp_list = tmp_list -> next; } /* ok the balance is now good, can write it */ CSV_CLEAR_FIELD ( csv_field_solde ); csv_field_solde = utils_real_get_string ( current_balance ); if ( current_balance.mantissa >= 0 ) { CSV_CLEAR_FIELD ( csv_field_credit ); csv_field_credit = utils_real_get_string ( current_balance ); } else { CSV_CLEAR_FIELD ( csv_field_debit ); csv_field_debit = utils_real_get_string ( gsb_real_abs ( current_balance ) ); } csv_add_record ( csv_file, TRUE, TRUE ); /* export the transactions */ pTransactionList = gsb_data_transaction_get_transactions_list ( ); tmp_list = g_slist_sort ( g_slist_copy ( pTransactionList ), (GCompareFunc) gsb_csv_export_sort_by_value_date_or_date ); while ( tmp_list ) { gint pTransaction; pTransaction = gsb_data_transaction_get_transaction_number ( tmp_list -> data ); if ( gsb_data_transaction_get_account_number ( pTransaction ) == account_number ) { /* export the transaction */ /* for now, print the balance. is this usefull ? */ gsb_csv_export_transaction ( pTransaction, csv_file, TRUE); } tmp_list = tmp_list -> next; } fclose ( csv_file ); g_slist_free ( tmp_list ); /* return */ return TRUE; }