/** * used to compare 2 iters and sort the by value date or date if not exist * always put the white line below * * \param iter_1 * \param iter_2 * * \return -1 if iter_1 is before iter_2 * */ gint gsb_csv_export_sort_by_value_date_or_date ( gpointer transaction_pointer_1, gpointer transaction_pointer_2 ) { gint transaction_number_1; gint transaction_number_2; const GDate *value_date_1; const GDate *value_date_2; transaction_number_1 = gsb_data_transaction_get_transaction_number ( transaction_pointer_1 ); transaction_number_2 = gsb_data_transaction_get_transaction_number ( transaction_pointer_2 ); value_date_1 = gsb_data_transaction_get_value_date ( transaction_number_1 ); if ( ! value_date_1 ) value_date_1 = gsb_data_transaction_get_date ( transaction_number_1 ); value_date_2 = gsb_data_transaction_get_value_date ( transaction_number_2 ); if ( ! value_date_2 ) value_date_2 = gsb_data_transaction_get_date ( transaction_number_2 ); if ( value_date_1 ) return ( g_date_compare ( value_date_1, value_date_2 ) ); else return -1; }
/** * called by a click on the column, used to sort the list * * \param model * \param iter_1 * \param iter_2 * \param column_number the number of the column (0 to CUSTOM_MODEL_VISIBLE_COLUMNS) we want to sort by * * \return -1 if iter_1 is above iter_2 * */ gint gsb_transactions_list_sort (CustomRecord **a, CustomRecord **b, CustomList *custom_list) { gint account_number; gint return_value; CustomRecord *record_1 = NULL; CustomRecord *record_2 = NULL; account_number = gsb_gui_navigation_get_current_account (); if (account_number == -1) /* normally cannot happen, except come here at the opening * of grisbi, and must return 0 if we don't want a crash */ return 0; /* i don't know why but sometimes there is a comparison between the 2 same rows... */ if (*a == *b) return 0; /* first of all, check the archive */ return_value = gsb_transactions_list_sort_check_archive ( *a, *b ); if (!return_value) { /* check the general tests (white line...) */ /* get the records */ record_1 = *a; record_2 = *b; return_value = gsb_transactions_list_sort_general_test ( record_1, record_2 ); } if (return_value) { /* we have already a returned value, but for archive or general test, * the pos of the row need not to change, so must keep the return_value */ return return_value; } else { /* get the transaction numbers */ gint element_number; gint transaction_number_1 = gsb_data_transaction_get_transaction_number (record_1 -> transaction_pointer); gint transaction_number_2 = gsb_data_transaction_get_transaction_number (record_2 -> transaction_pointer); /* get the element used to sort the list */ element_number = gsb_data_account_get_element_sort ( account_number, custom_list -> sort_col); return_value = gsb_transactions_list_sort_by_no_sort ( transaction_number_1, transaction_number_2, element_number ); } if (custom_list -> sort_order == GTK_SORT_DESCENDING) return_value = -return_value; return return_value; }
/** * export an archive into the csv format * * \param filename name of the csv file * \param archive_number the archive to export * * \return TRUE ok, FALSE problem * */ gboolean gsb_csv_export_archive ( const gchar *filename, gint archive_number ) { FILE *csv_file; GSList *pTransactionList; 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, FALSE); /* set all the transactions for that archive */ pTransactionList = gsb_data_transaction_get_complete_transactions_list (); while ( pTransactionList ) { gint pTransaction = gsb_data_transaction_get_transaction_number (pTransactionList -> data); if (gsb_data_transaction_get_archive_number (pTransaction) == archive_number ) /* export the transaction */ gsb_csv_export_transaction ( pTransaction, csv_file, FALSE); pTransactionList = pTransactionList -> next; } fclose ( csv_file ); return TRUE; }
/** * remove an archive * remove too the archive from the transactions linked to it * * \param archive_number the archive we want to remove * * \return TRUE ok * */ gboolean gsb_data_archive_remove ( gint archive_number ) { struct_archive *archive; GSList *tmp_list; archive = gsb_data_archive_get_structure ( archive_number ); if (!archive) return FALSE; /* remove the archive from the transactions */ tmp_list = gsb_data_transaction_get_complete_transactions_list (); while (tmp_list) { gint transaction_number; transaction_number = gsb_data_transaction_get_transaction_number (tmp_list -> data); if (gsb_data_transaction_get_archive_number (transaction_number) == archive -> archive_number) gsb_data_transaction_set_archive_number ( transaction_number, 0 ); tmp_list = tmp_list -> next; } /* remove the archive from the list */ archive_list = g_slist_remove ( archive_list, archive ); _gsb_data_archive_free (archive); return TRUE; }
/** * remove a reconcile * all the transactions marked by that reconcile will be marked P * and lose the link to that reconcile * * \param reconcile_number the reconcile we want to remove * * \return TRUE ok * */ gboolean gsb_data_reconcile_remove ( gint reconcile_number ) { struct_reconcile *reconcile; GSList *list_tmp; reconcile = gsb_data_reconcile_get_structure ( reconcile_number ); if (!reconcile) return FALSE; reconcile_list = g_list_remove ( reconcile_list, reconcile ); _gsb_data_reconcile_free ( reconcile ); /* remove that reconcile of the transactions */ list_tmp = gsb_data_transaction_get_complete_transactions_list (); while (list_tmp) { gint transaction_number = gsb_data_transaction_get_transaction_number (list_tmp -> data); if ( gsb_data_transaction_get_reconcile_number (transaction_number) == reconcile_number ) { gsb_data_transaction_set_reconcile_number ( transaction_number, 0 ); gsb_data_transaction_set_marked_transaction ( transaction_number, OPERATION_POINTEE ); } list_tmp = list_tmp -> next; } return TRUE; }
/** * remove all the payees wich are not used * * \param button the toolbar button * \param null * * \return the number of payees removed * */ gint gsb_data_payee_remove_unused ( void ) { GSList *tmp_list; GSList *used = NULL; gint nb_removed = 0; /* first we create a list of used categories */ tmp_list = gsb_data_transaction_get_complete_transactions_list (); while (tmp_list) { gint payee_number; payee_number = gsb_data_transaction_get_party_number ( gsb_data_transaction_get_transaction_number (tmp_list -> data)); if (!g_slist_find (used, GINT_TO_POINTER (payee_number))) { used = g_slist_append ( used, GINT_TO_POINTER (payee_number)); } tmp_list = tmp_list -> next; } /* it also scans the list of sheduled transactions. fix bug 538 */ tmp_list = gsb_data_scheduled_get_scheduled_list (); while (tmp_list) { gint payee_number; payee_number = gsb_data_scheduled_get_party_number ( gsb_data_scheduled_get_scheduled_number ( tmp_list -> data)); if (!g_slist_find (used, GINT_TO_POINTER (payee_number))) { used = g_slist_append ( used, GINT_TO_POINTER (payee_number)); } tmp_list = tmp_list -> next; } /* now check each payee to know if it is used */ tmp_list = gsb_data_payee_get_payees_list (); while (tmp_list) { struct_payee *payee = tmp_list -> data; tmp_list = tmp_list -> next; if ( !used || !g_slist_find (used, GINT_TO_POINTER (payee -> payee_number))) { /* payee not used */ payee_buffer = payee; /* increase speed */ gsb_data_payee_remove (payee -> payee_number); nb_removed++; } } return nb_removed; }
/** * 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; }
/** * check for the part wich cannot change : the white line must always be at * the end of the list * and into a transaction, the lines are not sorted in ascending or descending method * * \param model * \param iter_1 * \param iter_2 * * \return 0 if that test cannot say the return_value between the 2 lines, * or the return_value if it's possible here * */ gint gsb_transactions_list_sort_general_test ( CustomRecord *record_1, CustomRecord *record_2 ) { gint return_value = 0; /* check first for the white lines, it's always set at the end */ if ( gsb_data_transaction_get_transaction_number (record_1 -> transaction_pointer) <= 0 ) return_value = 1; else { if (gsb_data_transaction_get_transaction_number (record_2 -> transaction_pointer) <= 0) return_value = -1; } /* check if we are on the same transaction */ if ( record_1 -> transaction_pointer == record_2 -> transaction_pointer ) /* the 2 records belong at the same transaction, * we keep always the order of the lines in transaction */ return_value = record_1->line_in_transaction - record_2->line_in_transaction; return return_value; }
/** * select the transaction by the record * static function * * \param record the CustomRecord to select * * \return TRUE ok, FALSE problem * */ static gboolean transaction_list_select_record ( CustomRecord *record ) { GtkTreePath *path; GtkTreeIter iter; gint i; gint selected_transaction; CustomList *custom_list; custom_list = transaction_model_get_model (); g_return_val_if_fail ( custom_list != NULL, FALSE ); g_return_val_if_fail ( record != NULL, FALSE ); /* get the transaction number */ selected_transaction = gsb_data_transaction_get_transaction_number (record -> transaction_pointer); /* record is the first row of the transaction to select */ custom_list -> selected_row = record; /* get the path of the row we want to select */ path = gtk_tree_path_new (); if ( record -> mother_row ) /* it's a child, need to get the path of the mother */ gtk_tree_path_append_index (path, record -> mother_row -> filtered_pos); gtk_tree_path_append_index (path, record -> filtered_pos); /* colorize the record */ for (i=0 ; i < custom_list -> nb_rows_by_transaction ; i++) { record -> row_bg_save = record -> row_bg; record -> row_bg = gsb_rgba_get_couleur ( "couleur_selection" ); /* inform the world that the row has changed */ iter.user_data = record; gtk_tree_model_row_changed(GTK_TREE_MODEL(custom_list), path, &iter); /* if the selection was a child, we stop now, only 1 line */ if (record -> mother_row) break; /* go to the next row of the transaction */ record = custom_list -> visibles_rows [record -> filtered_pos + 1]; gtk_tree_path_next (path); } /** update account and other stuff */ gsb_transactions_list_selection_changed (selected_transaction); return TRUE; }
/** * return the selected transaction * * \param * * \return the transaction_number or -1 (white line) if problem * */ gint transaction_list_select_get ( void ) { CustomRecord *record; CustomList *custom_list; custom_list = transaction_model_get_model (); g_return_val_if_fail ( custom_list != NULL, FALSE ); record = custom_list -> selected_row; if (!record) return -1; return gsb_data_transaction_get_transaction_number (record -> transaction_pointer); }
/** * associate all transactions without fyear to the corresponding * fyear * * \param * * \return FALSE * */ gboolean gsb_fyear_config_associate_transactions ( void ) { GSList *list_tmp; gint modification_number = 0; if (!question_yes_no_hint ( _("Automatic association of financial years?"), _("This function assigns each transaction without a financial year to the one related to its transaction date. If no financial year matches, the transaction will not be changed."), GTK_RESPONSE_NO )) return FALSE; 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); if (!gsb_data_transaction_get_financial_year_number (transaction_number)) { gint fyear_number; fyear_number = gsb_data_fyear_get_from_date (gsb_data_transaction_get_date (transaction_number)); if (fyear_number) { gsb_data_transaction_set_financial_year_number ( transaction_number, fyear_number ); modification_number++; } } list_tmp = list_tmp -> next; } if (modification_number) { gchar* tmpstr = g_strdup_printf (_("%d transactions associated"), modification_number); dialogue ( tmpstr ); g_free ( tmpstr ); transaction_list_update_element (ELEMENT_EXERCICE); gsb_file_set_modified ( TRUE ); } else dialogue ( _("no transaction to associate")); return FALSE; }
/** * update the counters of the payees * * \param * * \return * */ void gsb_data_payee_update_counters ( void ) { GSList *list_tmp_transactions; gsb_data_payee_reset_counters (); if ( etat.add_archive_in_total_balance ) list_tmp_transactions = gsb_data_transaction_get_complete_transactions_list (); else 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); gsb_data_payee_add_transaction_to_payee ( transaction_number_tmp ); list_tmp_transactions = list_tmp_transactions -> next; } }
/** * move down the selection * this doesn't change the selection in the account, only on the model, * so need to update the account * * \param into_children if TRUE and the current selection has children and is opened, * the selection goes on the first child of that transaction * else it goes directly on the next mother * * \return TRUE : done, FALSE : no change * */ gboolean transaction_list_select_down ( gboolean into_children ) { CustomRecord *record; GtkTreePath *end_path_list; GtkTreePath *path; CustomList *custom_list; custom_list = transaction_model_get_model (); g_return_val_if_fail ( custom_list != NULL, FALSE ); /* the only way to forbid the move is if we are on the white line */ record = custom_list -> selected_row; if (!record) /* there is no selection, should not happen * to avoid to block grisbi, set on the white line */ return transaction_list_select (-1); /* the way is different between the selected transaction is a child or a mother */ if (record -> mother_row) { /* we are on a child, go to the next child or to the next mother */ if (record -> pos == (record -> mother_row -> number_of_children - 1)) /* go to the next mother */ record = custom_list -> visibles_rows[record -> mother_row -> filtered_pos + 1]; else /* go to the next child */ record = record -> mother_row -> children_rows[record -> pos + 1]; } else { /* we are on a mother, go into the first child or the next mother */ /* if we are on the white line, go away */ if (gsb_data_transaction_get_transaction_number (record -> transaction_pointer) == -1) return FALSE; /* if we are on a split, and it is opened, and into_children i set, go * to the first child */ if (record -> number_of_children && into_children) { path = gtk_tree_path_new (); /* set the path on the mother row which have the expander */ gtk_tree_path_append_index (path, record -> children_rows[0] -> mother_row -> filtered_pos); } else path = NULL; if (path && gtk_tree_view_row_expanded (GTK_TREE_VIEW (gsb_transactions_list_get_tree_view ()), path)) { /* go to the first child */ record = record -> children_rows[0]; gtk_tree_path_free (path); } else /* go to the next transaction mother */ record = custom_list -> visibles_rows[record -> filtered_pos + custom_list -> nb_rows_by_transaction]; } /* now can remove the selection and select the new one */ transaction_list_select_unselect (); transaction_list_select_record (record); /* move the tree view to the selection, we need to check the visible range and * all that stuff because gtk_tree_view_scroll_to_cell set the rows at the upper of the tree view * instead of keeping them at the bottom, when transaction goes down beside the bottom of the tree view */ if ( gtk_tree_view_get_visible_range ( GTK_TREE_VIEW (gsb_transactions_list_get_tree_view ()), NULL, &end_path_list )) { path = gtk_tree_path_new (); if (record -> mother_row) { gtk_tree_path_append_index (path, record -> mother_row -> filtered_pos); gtk_tree_path_append_index (path, record -> filtered_pos); } else /* check with the last visible line of the transaction */ gtk_tree_path_append_index (path, record -> transaction_records[custom_list -> nb_rows_by_transaction - 1] -> filtered_pos); if (gtk_tree_path_compare (end_path_list, path) == -1) /* the last line of the transaction is above the last visible row */ gtk_tree_view_scroll_to_cell ( GTK_TREE_VIEW (gsb_transactions_list_get_tree_view ()), path, NULL, TRUE, 1.0, 0.0 ); gtk_tree_path_free (path); gtk_tree_path_free (end_path_list); } return TRUE; }
/** * called to remove a financial year, check before if * some transactions are associated with it and warn if yes * * \param tree_view * * \return FALSE * */ gboolean gsb_fyear_config_remove_fyear ( GtkWidget *tree_view ) { GtkTreeIter iter; GtkTreeModel *model; GtkTreeSelection *selection; gint fyear_number; gboolean warning_showed = FALSE; GSList *tmp_list; selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)); gtk_tree_selection_get_selected ( GTK_TREE_SELECTION (selection), &model, &iter ); gtk_tree_model_get ( GTK_TREE_MODEL (model), &iter, FYEAR_NUMBER_COLUMN, &fyear_number, -1 ); if (!fyear_number) return FALSE; /* first, we check if one transaction uses that financial year */ tmp_list = gsb_data_transaction_get_complete_transactions_list (); while (tmp_list) { gint transaction_number; transaction_number = gsb_data_transaction_get_transaction_number (tmp_list -> data); if ( fyear_number == gsb_data_transaction_get_financial_year_number (transaction_number)) { /* at the beginning warning_showed is FALSE and we show a warning, * if the user doesn't want to continue, we go out of the while so cannot come * here again ; but if he wants to continue, warning_showed is set to TRUE, we delete * the financial year and continue to come here to set the fyear of the * transactions to 0 */ if (warning_showed) gsb_data_transaction_set_financial_year_number (transaction_number, 0); else { gint result; result = question_yes_no_hint ( _("The selected financial year is used in the file"), _("If you really remove it, all the associated transactions will be without financial year.\nAre you sure?"), GTK_RESPONSE_NO ); if (result) { gsb_data_transaction_set_financial_year_number (transaction_number, 0); warning_showed = TRUE; } else break; } } tmp_list = tmp_list -> next; } /* if warning_showed is FALSE, it's because none transaction have that fyear, * or we answer NO to the warning but in that case, tmp_list is non NULL */ if (warning_showed || !tmp_list ) { gsb_data_fyear_remove (fyear_number); gtk_list_store_remove ( GTK_LIST_STORE (model), &iter ); gtk_widget_set_sensitive ( g_object_get_data ( G_OBJECT (model), "paddingbox_details" ), FALSE ); gtk_widget_set_sensitive ( g_object_get_data ( G_OBJECT (model), "remove_fyear_button" ), FALSE ); /* Update various menus */ gsb_fyear_update_fyear_list (); gsb_file_set_modified ( TRUE ); } 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; }
/** * function called to launch the reconcile_config assistant * calculate the number of transactions to link, and refuse to run the assistant if none * * \param * * \return GtkResponseType, the returned value from the assistant * */ GtkResponseType gsb_assistant_reconcile_config_run ( void ) { GtkResponseType return_value; GSList *transactions_list = NULL; GSList *tmp_list; gint transaction_number; GtkWidget *assistant; gchar* tmpstr; 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)) transactions_list = g_slist_append ( transactions_list, GINT_TO_POINTER (transaction_number)); tmp_list = tmp_list -> next; } if (!transactions_list) { dialogue (_("No marked transactions without reconciliation found!")); return GTK_RESPONSE_CANCEL; } /* get the number of transactions to associate, we will decrease it for each association */ transactions_to_link = g_slist_length (transactions_list); /* come here if we have some orphan transactions * this can happen by 2 ways : * for old users of Grisbi, before i don't remember what version, there were no reconcile number, * the reconciled transactions were juste marked R * before the 0.6.0, ctrl R didn't permit to choose a reconciliation * * for the 2nd item, no problem, we show a list of reconciles and the user can choose what reconcile he wants * for the first item the problem is there is no reconcile number to go with that transactions... * so we will use the assistant to * -permit to create a reconcile directly (not possible normaly in the configuration * -permit to choose a reconcile number for each transactions without reconcile * - do an automatic find for reconcile, usefull in the first item, when very much * transactions without reconcile, but we need to make the old reconciles before, * and set the good date for all the reconciles (because grisbi set them automatically * at the first update to grisbi 0.6.0 )*/ /* first, create the assistant */ tmpstr = g_strdup_printf (_("Grisbi found %d marked transactions not associated with a reconciliation number, " "this can happen for old users of Grisbi or from a misuse of the Ctrl-R shortcut.\n\n" "This assistant will help you make the link between such transactions and a reconciliation.\n\n" "Before continuing, you should first check if all the dates of the existing reconciliations are good " "because Grisbi will try to guess them not very precisely " "(you will be able to create new reconciliations in the next step). " "Previous reconciliations will be available too."), transactions_to_link ); assistant = gsb_assistant_new ( _("Associate orphan transactions to a reconciliation"), tmpstr, "reconat.png", NULL ); g_free ( tmpstr ); gsb_assistant_add_page ( assistant, gsb_assistant_reconcile_config_page_menu (assistant), RECONCILE_ASSISTANT_MENU, RECONCILE_ASSISTANT_INTRO, RECONCILE_ASSISTANT_NEW_RECONCILE, NULL ); gsb_assistant_add_page ( assistant, gsb_assistant_reconcile_config_page_new_reconcile (), RECONCILE_ASSISTANT_NEW_RECONCILE, RECONCILE_ASSISTANT_MENU, RECONCILE_ASSISTANT_MENU, NULL ); gsb_assistant_add_page ( assistant, gsb_assistant_reconcile_config_page_automatically_associate (assistant), RECONCILE_ASSISTANT_AUTOMATICALLY_ASSOCIATE, RECONCILE_ASSISTANT_MENU, RECONCILE_ASSISTANT_MENU, G_CALLBACK (gsb_assistant_reconcile_config_update_auto_asso)); gsb_assistant_add_page ( assistant, gsb_assistant_reconcile_config_page_manually_associate (assistant), RECONCILE_ASSISTANT_MANUALLY_ASSOCIATE, RECONCILE_ASSISTANT_MENU, RECONCILE_ASSISTANT_MENU, G_CALLBACK (gsb_assistant_reconcile_config_update_manu_asso)); gsb_assistant_add_page ( assistant, gsb_assistant_reconcile_config_page_success (), RECONCILE_ASSISTANT_SUCCESS, RECONCILE_ASSISTANT_MENU, RECONCILE_ASSISTANT_MENU, NULL ); return_value = gsb_assistant_run (assistant); gtk_widget_destroy (assistant); return return_value; }
/** * print the page * * \param operation GtkPrintOperation * \param context GtkPrintContext * \param page page to print * \param null * * \return FALSE * */ gboolean print_transactions_list_draw_page ( GtkPrintOperation *operation, GtkPrintContext *context, gint page, gpointer null ) { CustomList *custom_list; gboolean color_bg = TRUE; gint line_position = 0; gint transactions_to_draw; devel_debug_int (page); /* draw the title */ if (!page) line_position = print_transactions_list_draw_title (context, line_position); /* draw the columns titles */ if (gsb_data_print_config_get_draw_columns_name ()) line_position = print_transactions_list_draw_columns_title (context, line_position); /* draw the transactions lines */ custom_list = transaction_model_get_model (); if (page) transactions_to_draw = transactions_per_page; else transactions_to_draw = transactions_in_first_page; if (transactions_to_draw > (total_transactions_to_print - total_transactions_printed)) transactions_to_draw = total_transactions_to_print - total_transactions_printed; while (transactions_to_draw) { gint i; CustomRecord *record = NULL; /* begin a transaction : fill the line before the transaction */ line_position = print_transactions_list_draw_line (line_position); /* print the transaction */ for (i=0 ; i<custom_list -> nb_rows_by_transaction ; i++) { record = custom_list -> visibles_rows[current_row_to_print]; /* if it's an archive, check we want it */ if (record -> what_is_line == IS_ARCHIVE && !gsb_data_print_config_get_draw_archives ()) { /* go to the next row but come back to the first line of transaction */ current_row_to_print++; i--; continue; } /* if we use the dates, it's here */ if (gsb_data_print_config_get_draw_interval_dates () && draw_initial_date && draw_final_date && record -> what_is_line == IS_TRANSACTION) { /* we want an interval, so check the transaction */ gint transaction_number; const GDate *date = NULL; transaction_number = gsb_data_transaction_get_transaction_number (record -> transaction_pointer); if (gsb_data_print_config_get_draw_dates_are_value_dates ()) date = gsb_data_transaction_get_value_date (transaction_number); /* if no value date, get the date */ if (!date) date = gsb_data_transaction_get_date (transaction_number); if (g_date_compare (date, draw_initial_date) < 0 || g_date_compare (date, draw_final_date) > 0) { /* the transaction is not into the dates, go to the next transaction */ current_row_to_print = current_row_to_print + custom_list -> nb_rows_by_transaction; i--; continue; } } /* begin the transaction, fill the background */ if (!i) print_transactions_list_draw_background (record, color_bg, line_position ); /* draw the last column */ print_transactions_list_draw_column (page_width, line_position); line_position = print_transactions_list_draw_row (context, record, line_position); current_row_to_print++; /* an archive is 1 line */ if (record -> what_is_line == IS_ARCHIVE) break; } /* we are on the last record of the transaction or archive, * decrease the number of transactions to draw */ if (record -> what_is_line == IS_TRANSACTION) { transactions_to_draw--; total_transactions_printed++; } /* add a space between 2 transactions */ line_position++; color_bg = !color_bg; } /* draw the last line */ print_transactions_list_draw_line (line_position); return FALSE; }
/** * find the number of archives and of transactions, according to the user conf * so if archives are not wanted, the value filled in number_of_archives will be always 0. * * \param number_of_archives a pointer of gint to fill with the number of archives * \param number_of_transactions a pointer to gint to fill with the number of transactions to show * * \return FALSE; * */ gboolean print_transactions_list_get_visibles_lines ( gint *number_of_archives, gint *number_of_transactions ) { gint i; CustomList *custom_list; gint archives_nb = 0; gint transactions_nb = 0; custom_list = transaction_model_get_model (); for (i=0 ; i<custom_list -> num_visibles_rows ; i++) { CustomRecord *record; record = custom_list -> visibles_rows[i]; switch (record -> what_is_line) { case IS_ARCHIVE: if (gsb_data_print_config_get_draw_archives ()) archives_nb++; break; case IS_TRANSACTION: if ( gsb_data_print_config_get_draw_interval_dates () && draw_initial_date && draw_final_date ) { /* we want an interval, so check the transaction */ gint transaction_number; const GDate *date; transaction_number = gsb_data_transaction_get_transaction_number (record -> transaction_pointer); if (gsb_data_print_config_get_draw_dates_are_value_dates ()) { date = gsb_data_transaction_get_value_date (transaction_number); /* if no value date, get the date */ if (!date) date = gsb_data_transaction_get_date (transaction_number); } else date = gsb_data_transaction_get_date (transaction_number); if (date && g_date_compare (date, draw_initial_date) >= 0 && g_date_compare (date, draw_final_date) <= 0) transactions_nb++; } else transactions_nb++; break; } } /* before returning the value, transactions_nb is in fact the number of lines of visibles transactions, * so need to divide by the number of lines for 1 transaction, and remove the white line if necessary */ if ( gsb_data_print_config_get_draw_interval_dates () && draw_initial_date && draw_final_date ) transactions_nb = ( transactions_nb ) / custom_list -> nb_rows_by_transaction; else transactions_nb = (transactions_nb - custom_list -> nb_rows_by_transaction) / custom_list -> nb_rows_by_transaction; *number_of_archives = archives_nb; *number_of_transactions = transactions_nb; return FALSE; }
/** * 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; }
/** * called by menubar to obfuscate the file * * \param * * \return TRUE * */ gboolean file_obfuscate_run ( void ) { GtkWidget *assistant; gint result; gsb_status_message ( _("Obfuscating file...") ); assistant = gsb_assistant_new ( _("Grisbi file obfuscation"), _("This assistant produces anonymized copies of account files, with " "all personal data replaced with harmless random data, in order to " "attach an anonimized copy of your Grisbi file with any bug report " "you submit." "\n\n" "That said, please check that bugs you submit are still valid with " "anonymized version of your files.\n" "\n" "To avoid any problems in your file, after saving the modified file, " "Grisbi will close without letting you saving anything. " "So if you didn't save your changes, please stop this assistant, " "save your work and restart the obfuscation process.\n\n" "In next page, you will be able to select individual features to " "obfuscate or to keep depending on the level of privacy needed."), "bug.png", NULL ); gsb_assistant_add_page ( assistant, file_obfuscate_page_1 (), 1, 0, 2, NULL ); gsb_assistant_add_page ( assistant, file_obfuscate_page_2 (), 2, 1, -1, NULL ); result = gsb_assistant_run ( assistant ); if (result == GTK_RESPONSE_APPLY) { /* obfuscate the file */ GSList *tmp_list; gchar *filename; /* remove the swp file */ gsb_file_util_modify_lock (FALSE); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_accounts_details))) { /* hide the details of account but not the names */ tmp_list = gsb_data_account_get_list_accounts (); while (tmp_list) { gint account_number = gsb_data_account_get_no_account (tmp_list -> data); gsb_data_account_set_id (account_number, g_strdup_printf ("id account %d", account_number)); gsb_data_account_set_comment (account_number, NULL); gsb_data_account_set_holder_name (account_number, NULL); gsb_data_account_set_holder_address (account_number, NULL); gsb_data_account_set_init_balance (account_number, null_real); gsb_data_account_set_mini_balance_wanted (account_number, null_real); gsb_data_account_set_mini_balance_authorized (account_number, null_real); gsb_data_account_set_bank_branch_code (account_number, NULL); gsb_data_account_set_bank_account_number (account_number, NULL); gsb_data_account_set_bank_account_key (account_number, NULL); tmp_list = tmp_list -> next; } } if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_amount))) { /* hide the amounts of transactions */ tmp_list = gsb_data_transaction_get_complete_transactions_list (); while (tmp_list) { gint transaction_number = gsb_data_transaction_get_transaction_number (tmp_list -> data); gsb_data_transaction_set_amount (transaction_number, null_real); gsb_data_transaction_set_voucher (transaction_number, NULL); gsb_data_transaction_set_bank_references (transaction_number, NULL); tmp_list = tmp_list -> next; } /* hide the amounts of scheduled transactions */ tmp_list = gsb_data_scheduled_get_scheduled_list (); while (tmp_list) { gint scheduled_number = gsb_data_scheduled_get_scheduled_number (tmp_list -> data); gsb_data_scheduled_set_amount (scheduled_number, null_real); tmp_list = tmp_list -> next; } } if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_accounts_names))) { /* hide the accounts names */ tmp_list = gsb_data_account_get_list_accounts (); while (tmp_list) { gint account_number = gsb_data_account_get_no_account (tmp_list -> data); gsb_data_account_set_name (account_number, g_strdup_printf ("Account n°%d", account_number)); tmp_list = tmp_list -> next; } } if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_payee))) { /* hide the payees names */ tmp_list = gsb_data_payee_get_payees_list (); while (tmp_list) { gint payee_number = gsb_data_payee_get_no_payee (tmp_list -> data); gsb_data_payee_set_name (payee_number, g_strdup_printf ( "Payee n°%d", payee_number)); gsb_data_payee_set_description (payee_number, NULL); tmp_list = tmp_list -> next; } } if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_categories))) { /* hide the categories */ tmp_list = gsb_data_category_get_categories_list (); while (tmp_list) { GSList *list_sub_categ; gint category_number = gsb_data_category_get_no_category (tmp_list -> data); gsb_data_category_set_name (category_number, g_strdup_printf ( "Category n°%d", category_number)); list_sub_categ = gsb_data_category_get_sub_category_list (category_number); while (list_sub_categ) { gint sub_categ_number = gsb_data_category_get_no_sub_category (list_sub_categ -> data); gsb_data_category_set_sub_category_name (category_number, sub_categ_number, g_strdup_printf ("Sub-category n°%d", sub_categ_number)); list_sub_categ = list_sub_categ -> next; } tmp_list = tmp_list -> next; } } if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_budgets))) { /* hide the budgets */ tmp_list = gsb_data_budget_get_budgets_list (); while (tmp_list) { GSList *list_sub_budget; gint budget_number = gsb_data_budget_get_no_budget (tmp_list -> data); gsb_data_budget_set_name (budget_number, g_strdup_printf ( "Budget n°%d", budget_number)); list_sub_budget = gsb_data_budget_get_sub_budget_list (budget_number); while (list_sub_budget) { gint sub_budget_number = gsb_data_budget_get_no_sub_budget (list_sub_budget -> data); gsb_data_budget_set_sub_budget_name (budget_number, sub_budget_number, g_strdup_printf ("Sub-budget n°%d", sub_budget_number)); list_sub_budget = list_sub_budget -> next; } tmp_list = tmp_list -> next; } } if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_notes))) { /* hide the notes */ tmp_list = gsb_data_transaction_get_complete_transactions_list (); while (tmp_list) { gint transaction_number = gsb_data_transaction_get_transaction_number (tmp_list -> data); gsb_data_transaction_set_notes (transaction_number, NULL); tmp_list = tmp_list -> next; } /* hide the notes of scheduled transactions */ tmp_list = gsb_data_scheduled_get_scheduled_list (); while (tmp_list) { gint scheduled_number = gsb_data_scheduled_get_scheduled_number (tmp_list -> data); gsb_data_scheduled_set_notes (scheduled_number, NULL); tmp_list = tmp_list -> next; } } if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_banks))) { /* hide the banks */ tmp_list = gsb_data_bank_get_bank_list (); while (tmp_list) { gint bank_number = gsb_data_bank_get_no_bank (tmp_list -> data); gsb_data_bank_set_name (bank_number, g_strdup_printf ("Bank n°%d", bank_number)); gsb_data_bank_set_code (bank_number, NULL); gsb_data_bank_set_bank_address (bank_number, NULL); gsb_data_bank_set_bank_tel (bank_number, NULL); gsb_data_bank_set_bank_mail (bank_number, NULL); gsb_data_bank_set_bank_web (bank_number, NULL); gsb_data_bank_set_bank_note (bank_number, NULL); gsb_data_bank_set_correspondent_name (bank_number, NULL); gsb_data_bank_set_correspondent_tel (bank_number, NULL); gsb_data_bank_set_correspondent_mail (bank_number, NULL); gsb_data_bank_set_correspondent_fax (bank_number, NULL); tmp_list = tmp_list -> next; } } if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_reports))) { /* hide the reports names*/ tmp_list = gsb_data_report_get_report_list (); while (tmp_list) { gint report_number = gsb_data_report_get_report_number (tmp_list -> data); gsb_data_report_set_report_name ( report_number, g_strdup_printf ( "Report n°%d", report_number)); tmp_list = tmp_list -> next; } } if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button_reconcile))) { /* hide the reconciles */ GList *reconcile_list; reconcile_list = gsb_data_reconcile_get_reconcile_list (); while (reconcile_list) { gint reconcile_number = gsb_data_reconcile_get_no_reconcile (reconcile_list -> data); gsb_data_reconcile_set_init_balance (reconcile_number, null_real); gsb_data_reconcile_set_final_balance (reconcile_number, null_real); reconcile_list = reconcile_list -> next; } } if (nom_fichier_comptes) { /* remove the .gsb */ nom_fichier_comptes[strlen(nom_fichier_comptes) -4] = 0; filename = g_strconcat ( nom_fichier_comptes, "-obfuscated.gsb", NULL); } else filename = g_strconcat ( my_get_gsb_file_default_dir (), "No_name-obfuscated.gsb", NULL); if (gsb_file_save_save_file (filename, FALSE, FALSE)) dialogue_hint ( g_strdup_printf ( _("Obfuscated file saved as\n'%s'"), filename ), _("Obfuscation succeeded") ); else dialogue_error_hint (g_strdup_printf (_("Grisbi couldn't save the file\n'%s'"), filename ), _("Obfuscation failed") ); /* bye bye */ exit (0); } gtk_widget_destroy ( assistant ); gsb_status_message ( _("Done.") ); 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; }
/** * 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; }
/** * find the iter of the line of the asked transaction * the transaction can be a mother or a child * * \param iter iter to fill * \param transaction_number transaction to search * \param line_in_transaction line of the transaction we want * * \return FALSE not found, TRUE ok * */ gboolean transaction_model_get_transaction_iter ( GtkTreeIter *iter, gint transaction_number, gint line_in_transaction ) { gint i; gint mother_transaction_number = transaction_number; gboolean is_child; CustomRecord *record = NULL; g_return_val_if_fail (iter != NULL, FALSE); g_return_val_if_fail (transaction_number != 0, FALSE); /* the transaction can be a mother or a child, * in all cases, we have to find first the mother (or herself) * because the children are saved into the mother structure */ /* if it's a child, look for the mother first */ is_child = gsb_data_transaction_get_mother_transaction_number (transaction_number) != 0; if (is_child) mother_transaction_number = gsb_data_transaction_get_mother_transaction_number (transaction_number); /* search the mother */ for (i=0 ; i<custom_list -> num_rows ; i++) { record = custom_list -> rows[i]; /* if we are on the good transaction, check the line, or if child can only be that line */ if (record -> what_is_line == IS_TRANSACTION && gsb_data_transaction_get_transaction_number (record -> transaction_pointer) == mother_transaction_number ) { /* ok, found the mother ; if search a child, stop here and continue to search, * if want the mother, need to check if it's the good line */ if (is_child) break; if (record -> line_in_transaction == line_in_transaction) { /* fill the iter */ iter->stamp = custom_list->stamp; iter->user_data = record; return TRUE; } } } /* come here only if it's a child, else, iter not found */ if (!is_child) return FALSE; /* for now, record is the mother, we search the child */ for (i=0 ; i < record -> number_of_children ; i++) { CustomRecord *child_record; child_record = record -> children_rows[i]; if (child_record -> what_is_line == IS_TRANSACTION && gsb_data_transaction_get_transaction_number (child_record -> transaction_pointer) == transaction_number) { /* ok, the child is found ; and only 1 line, so no more check */ /* fill the iter */ iter->stamp = custom_list->stamp; iter->user_data = child_record; return 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; }
/** 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; }