/** * Return the real in a formatted string with an optional currency * symbol, according to the locale regarding decimal separator, * thousands separator and positive or negative sign. * * \param number Number to format. * \param currency_number the currency we want to adapt the number, 0 for no adaptation * \param show_symbol TRUE to add the currency symbol in the string * * \return A newly allocated string of the number (this * function will never return NULL) */ gchar *utils_real_get_string_with_currency ( gsb_real number, gint currency_number, gboolean show_symbol ) { struct lconv *locale = gsb_locale_get_locale ( ); gint floating_point; const gchar *currency_symbol = (currency_number && show_symbol) ? gsb_data_currency_get_code_or_isocode (currency_number) : NULL; /* First of all if number = 0 I return 0 with the symbol of the currency if necessary */ if (number.mantissa == 0) { if (currency_symbol && locale -> p_cs_precedes) return g_strdup_printf ( "%s %s", currency_symbol, "0" ); else if (currency_symbol && ! locale -> p_cs_precedes) return g_strdup_printf ( "%s %s", "0", currency_symbol ); else return g_strdup ("0"); } else if ( (number.exponent < 0) || (number.exponent > EXPONENT_MAX ) || (number.mantissa == error_real.mantissa) ) return g_strdup ( ERROR_REAL_STRING ); /* first we need to adapt the exponent to the currency */ /* if the exponent of the real is not the same of the currency, need to adapt it */ floating_point = gsb_data_currency_get_floating_point ( currency_number ); if ( currency_number && number.exponent != floating_point ) number = gsb_real_adjust_exponent ( number, floating_point ); return gsb_real_raw_format_string ( number, locale, currency_symbol ); }
gboolean gsb_account_new ( kind_account account_type, gint currency_number, gint bank_number, gsb_real init_amount, const gchar *name, gchar *name_icon ) { gint account_number; GtkWidget *notebook_general; /* create the new account */ account_number = gsb_data_account_new (account_type); if ( account_number == -1 ) { dialogue_error_memory (); return FALSE; } /* set the default method of payment */ gsb_data_payment_create_default (account_number); /* set the icon_name */ if ( name_icon ) gsb_data_account_set_name_icon ( account_number, name_icon ); gsb_data_account_set_currency ( account_number, currency_number); gsb_data_account_set_bank (account_number, bank_number); gsb_data_account_set_init_balance (account_number, init_amount); gsb_data_account_set_mini_balance_wanted ( account_number, gsb_real_new ( 0, gsb_data_currency_get_floating_point (currency_number) ) ); gsb_data_account_set_mini_balance_authorized (account_number, gsb_real_new ( 0, gsb_data_currency_get_floating_point (currency_number) ) ); gsb_data_account_set_name (account_number, name); /* update the combofix for categ */ gsb_category_update_combofix ( FALSE ); /* update the name of accounts in form */ gsb_account_update_combo_list ( gsb_form_scheduler_get_element_widget (SCHEDULED_FORM_ACCOUNT), FALSE ); /* update the main page */ mise_a_jour_liste_comptes_accueil = 1; /* update the accounts lists */ gsb_menu_update_accounts_in_menus (); /* do the next part only if the widgets are created * (can come here at the end of the new file assistant...) */ notebook_general = gsb_gui_get_general_notebook ( ); if (notebook_general) { /* Add an entry in navigation pane. */ gsb_gui_navigation_add_account ( account_number, TRUE ); /* Go to accounts properties */ gtk_notebook_set_current_page ( GTK_NOTEBOOK ( notebook_general ), GSB_ACCOUNT_PAGE ); gtk_notebook_set_current_page ( GTK_NOTEBOOK ( account_page ), GSB_PROPERTIES_PAGE ); gsb_account_property_fill_page (); } gsb_file_set_modified ( TRUE ); return TRUE; }
/** * 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; }