/** * Add the given transaction to a budget in the counters if no budget * is specified, add it to the blank budget. * * \param transaction_number Transaction we want to work with. * \param budget_id Budget to add transaction into total. * \param sub_budget_id Sub-budget to add transaction into total. */ void gsb_data_budget_add_transaction_to_budget ( gint transaction_number, gint budget_id, gint sub_budget_id ) { struct_budget *budget; struct_sub_budget *sub_budget; budget = gsb_data_budget_get_structure ( budget_id ); sub_budget = gsb_data_budget_get_sub_budget_structure ( budget_id , sub_budget_id ); /* should not happen, this is if the transaction has a budget wich doesn't exist * we show a debug warning and get without budget */ if (!budget) { gchar *tmpstr; tmpstr = g_strdup_printf ( _("The transaction %d has a budget n°%d and sub-budget n°%d but they don't exist."), transaction_number, budget_id, sub_budget_id ); warning_debug (tmpstr); g_free (tmpstr); budget = empty_budget; } /* now budget is on the budget structure or on empty_budget */ if ( budget ) { budget -> budget_nb_transactions ++; if ( ! gsb_data_transaction_get_split_of_transaction ( transaction_number ) ) budget -> budget_balance = gsb_real_add ( budget -> budget_balance, gsb_data_transaction_get_adjusted_amount_for_currency ( transaction_number, budgetary_line_tree_currency (), -1)); } /* if we are on empty_budget, no sub-budget */ if (budget == empty_budget) return; if ( sub_budget ) { sub_budget -> sub_budget_nb_transactions ++; if ( ! gsb_data_transaction_get_split_of_transaction ( transaction_number ) ) sub_budget -> sub_budget_balance = gsb_real_add ( sub_budget -> sub_budget_balance, gsb_data_transaction_get_adjusted_amount_for_currency ( transaction_number, budgetary_line_tree_currency (), -1)); } else { budget -> budget_nb_direct_transactions ++; if ( ! gsb_data_transaction_get_split_of_transaction ( transaction_number ) ) budget -> budget_direct_balance = gsb_real_add ( budget -> budget_direct_balance, gsb_data_transaction_get_adjusted_amount_for_currency ( transaction_number, budgetary_line_tree_currency (), -1)); } }
/** * add the given transaction to its payee in the counters * if the transaction has no payee, add it to the blank payee * * \param transaction_number the transaction we want to work with * * \return * */ void gsb_data_payee_add_transaction_to_payee ( gint transaction_number ) { struct_payee *payee; payee = gsb_data_payee_get_structure ( gsb_data_transaction_get_party_number (transaction_number)); /* if no payee in that transaction, and it's neither a split, neither a transfer, * we work with empty_payee */ /* should not happen, this is if the transaction has a payee wich doesn't exists * we show a debug warning and get without payee */ if (!payee) { gchar *tmpstr; tmpstr = g_strdup_printf ( _("The transaction %d has a payee n°%d but it doesn't exist."), transaction_number, gsb_data_transaction_get_party_number (transaction_number)); warning_debug (tmpstr); g_free (tmpstr); payee = empty_payee; } payee -> payee_nb_transactions ++; if ( ! gsb_data_transaction_get_split_of_transaction ( transaction_number ) ) payee -> payee_balance = gsb_real_add ( payee -> payee_balance, gsb_data_transaction_get_adjusted_amount_for_currency ( transaction_number, payee_tree_currency (), -1)); }
gboolean csv_import_parse_credit ( struct struct_ope_importation * ope, gchar * string ) { if ( !string ) return FALSE; if ( strlen ( string ) > 0 ) { ope -> montant = gsb_real_add ( ope -> montant, utils_real_get_from_string (string)); } return TRUE; }
void gsb_real_cunit__gsb_real_add ( void ) { GsbReal a = {1, 0}; GsbReal b = {31415, 4}; GsbReal r = gsb_real_add(a, b); CU_ASSERT_EQUAL(41415, r.mantissa); CU_ASSERT_EQUAL(4, r.exponent); a.mantissa = 0x7FFFFFFE; a.exponent = 0; b.mantissa = 1; b.exponent = 0; r = gsb_real_add(a, b); CU_ASSERT_EQUAL(0x7FFFFFFF, r.mantissa); CU_ASSERT_EQUAL(0, r.exponent); a.mantissa = 0x7FFFFFFF; a.exponent = 0; b.mantissa = 2; b.exponent = 0; r = gsb_real_add(a, b); CU_ASSERT_EQUAL(0x80000001, r.mantissa); CU_ASSERT_EQUAL(0, r.exponent); a.mantissa = 0x80000001; a.exponent = 0; b.mantissa = -2; b.exponent = 0; r = gsb_real_add(a, b); CU_ASSERT_EQUAL(0x7FFFFFFF, r.mantissa); CU_ASSERT_EQUAL(0, r.exponent); a.mantissa = G_MININT64; a.exponent = 0; b.mantissa = 100; b.exponent = 0; r = gsb_real_add(a, b); CU_ASSERT_EQUAL(G_MININT64, r.mantissa); CU_ASSERT_EQUAL(0, r.exponent); a.mantissa = 100; a.exponent = 0; b.mantissa = G_MININT64; b.exponent = 0; r = gsb_real_add(a, b); CU_ASSERT_EQUAL(G_MININT64, r.mantissa); CU_ASSERT_EQUAL(0, r.exponent); }
/** * update the labels according to the value in the account structure and the entries * so all the calculs must have been done before (for marked transactions) * * \param entry not used * \param null not used * * \return FALSE * */ gboolean gsb_reconcile_update_amounts ( GtkWidget *entry, gpointer null ) { gsb_real amount; gint account_number; gint currency_number; const gchar *initial_balance; const gchar *final_balance; gchar *tmp_string; gchar* tmpstr; gboolean valide = FALSE; /* first get the current account number */ account_number = gsb_gui_navigation_get_current_account (); /* fill the labels corresponding to the balances */ initial_balance = gtk_entry_get_text ( GTK_ENTRY (reconcile_initial_balance_entry) ); gtk_label_set_text ( GTK_LABEL ( reconcile_initial_balance_label ), initial_balance ); if ( entry ) { valide = gsb_form_widget_get_valide_amout_entry ( gtk_entry_get_text ( GTK_ENTRY ( entry ) ) ); if ( valide ) { /* the entry is valid, make it normal */ gtk_widget_modify_base ( entry, GTK_STATE_NORMAL, NULL ); } else { /* the entry is not valid, make it red */ gtk_widget_modify_base ( entry, GTK_STATE_NORMAL, gsb_color_get_couleur ( "entry_error_color" ) ); return FALSE; } } currency_number = gsb_data_account_get_currency ( account_number ); amount = utils_real_get_calculate_entry ( reconcile_final_balance_entry ); final_balance = utils_real_get_string_with_currency ( amount, currency_number, FALSE ); gtk_label_set_text ( GTK_LABEL ( reconcile_final_balance_label ), final_balance ); /* set the marked balance amount, * this is what we mark as P while reconciling, so it's the total marked balance * - the initial marked balance */ tmp_string = utils_real_get_string_with_currency ( gsb_data_account_calculate_waiting_marked_balance ( account_number ), currency_number, FALSE ); gtk_label_set_text ( GTK_LABEL ( reconcile_marked_balance_label ), tmp_string ); g_free (tmp_string); /* calculate the variation balance and show it */ amount = gsb_real_sub ( gsb_real_add ( utils_real_get_from_string ( initial_balance ), gsb_data_account_calculate_waiting_marked_balance ( account_number ) ), utils_real_get_from_string ( final_balance ) ); tmpstr = utils_real_get_string_with_currency ( amount, currency_number, FALSE ); gtk_label_set_text ( GTK_LABEL ( reconcile_variation_balance_label ), tmpstr); g_free ( tmpstr ); if ( amount.mantissa ) gtk_widget_set_sensitive ( GTK_WIDGET ( reconcile_ok_button ), FALSE ); else gtk_widget_set_sensitive ( GTK_WIDGET ( reconcile_ok_button ), 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; }
/** * Parse XML transaction node and fill a ImportTransaction with results. * * \param transaction_node XML transaction node to parse. */ void recuperation_donnees_gnucash_transaction ( xmlNodePtr transaction_node ) { struct ImportTransaction * transaction; struct ImportAccount * account = NULL; struct gnucash_split * split; gchar * date_string, *space, *tiers; GDate * date; xmlNodePtr splits, split_node, date_node; GSList * split_list = NULL; GsbReal total = { 0 , 0 }; /* Transaction amount, category, account, etc.. */ splits = get_child ( transaction_node, "splits" ); split_node = splits -> children; while ( split_node ) { struct ImportAccount * split_account = NULL; struct gnucash_category * categ = NULL; gint p_r = OPERATION_NORMALE; GsbReal amount; /** * Gnucash transactions are in fact "splits", much like grisbi's * splits of transactions. We need to parse all splits and * see whether they are transfers to real accounts or transfers * to category accounts. In that case, we only create one * transactions. The other is discarded as grisbi is not a * double part financial engine. */ if ( node_strcmp ( split_node, "split" ) ) { gchar * account_name = NULL, * categ_name = NULL; split_account = find_imported_account_by_uid ( child_content ( split_node, "account" ) ); categ = find_imported_categ_by_uid ( child_content ( split_node, "account" ) ); amount = gnucash_value ( child_content(split_node, "value") ); if ( categ ) categ_name = categ -> name; if ( split_account ) { /* All of this stuff is here since we are dealing with the account split, not the category one */ account_name = split_account -> nom_de_compte; total = gsb_real_add ( total, amount ); if ( strcmp(child_content(split_node, "reconciled-state"), "n") ) p_r = OPERATION_RAPPROCHEE; } split = find_split ( split_list, amount, split_account, categ ); if ( split ) { update_split ( split, amount, account_name, categ_name ); } else { split = new_split ( amount, account_name, categ_name ); split_list = g_slist_append ( split_list, split ); split -> notes = child_content(split_node, "memo"); } if ( p_r != OPERATION_NORMALE ) split -> p_r = p_r; } split_node = split_node -> next; } if ( ! split_list ) return; /* Transaction date */ date_node = get_child ( transaction_node, "date-posted" ); date_string = child_content (date_node, "date"); space = strchr ( date_string, ' ' ); if ( space ) *space = 0; date = g_date_new (); g_date_set_parse ( date, date_string ); if ( !g_date_valid ( date )) fprintf ( stderr, "grisbi: Can't parse date %s\n", date_string ); /* Tiers */ tiers = child_content ( transaction_node, "description" ); /* Create transaction */ split = split_list -> data; transaction = new_transaction_from_split ( split, tiers, date ); transaction -> operation_ventilee = 0; transaction -> ope_de_ventilation = 0; account = find_imported_account_by_name ( split -> account ); if ( account ) account -> operations_importees = g_slist_append ( account -> operations_importees, transaction ); /** Splits of transactions are handled the same way, we process them if we find more than one split in transaction node. */ if ( g_slist_length ( split_list ) > 1 ) { transaction -> operation_ventilee = 1; transaction -> montant = total; while ( split_list ) { split = split_list -> data; account = NULL; transaction = new_transaction_from_split ( split, tiers, date ); transaction -> ope_de_ventilation = 1; account = find_imported_account_by_name ( split -> account ); if ( account ) account -> operations_importees = g_slist_append ( account -> operations_importees, transaction ); split_list = split_list -> next; } } }
/** * export a transaction given in param in the file given in param * * \param transaction_number * \param csv_file * \param print_balance will set a balance for each transaction in the csv file * not set for archive export, set (but usefull ?) for account export * * \return TRUE ok, FALSE problem * */ static gboolean gsb_csv_export_transaction ( gint transaction_number, FILE *csv_file, gboolean print_balance ) { gsb_real amount; gint return_exponent; gint account_number; gchar* tmpstr; const GDate *value_date, *date; gint payment_method; account_number = gsb_data_transaction_get_account_number (transaction_number); /* Si c'est une ventilation d'opération (càd une opération fille), elle n'est pas traitée à la base du "if" mais plus loin, quand son opé ventilée sera exportée */ if ( gsb_data_transaction_get_mother_transaction_number (transaction_number) ) return TRUE; return_exponent = gsb_data_currency_get_floating_point ( gsb_data_account_get_currency (account_number)); /* met la date */ date = gsb_data_transaction_get_date ( transaction_number ); if ( date ) { CSV_CLEAR_FIELD (csv_field_date); csv_field_date = g_strdup_printf ("%d/%d/%d", g_date_get_day ( date ), g_date_get_month ( date ), g_date_get_year ( date ) ); } value_date = gsb_data_transaction_get_value_date ( transaction_number ); if ( value_date ) { CSV_CLEAR_FIELD (csv_field_date_val); csv_field_date_val = g_strdup_printf ("%d/%d/%d", g_date_get_day ( value_date ), g_date_get_month ( value_date ), g_date_get_year ( value_date ) ); } /* met le pointage */ CSV_CLEAR_FIELD (csv_field_pointage); switch ( gsb_data_transaction_get_marked_transaction ( transaction_number ) ) { case OPERATION_NORMALE: csv_field_pointage = my_strdup (""); break; case OPERATION_POINTEE: csv_field_pointage = my_strdup ("P"); break; case OPERATION_TELERAPPROCHEE: csv_field_pointage = my_strdup ("T"); break; case OPERATION_RAPPROCHEE: csv_field_pointage = my_strdup ("R"); break; } /* met les notes */ CSV_CLEAR_FIELD(csv_field_notes); if ( gsb_data_transaction_get_notes ( transaction_number ) ) csv_field_notes = my_strdup (gsb_data_transaction_get_notes ( transaction_number )); /* met le tiers */ CSV_CLEAR_FIELD(csv_field_tiers); csv_field_tiers = g_strdup ( gsb_data_payee_get_name ( gsb_data_transaction_get_party_number ( transaction_number ), FALSE ) ); /* met le numero du rapprochement */ if ( gsb_data_transaction_get_reconcile_number ( transaction_number ) ) { CSV_CLEAR_FIELD (csv_field_rappro); csv_field_rappro = my_strdup ( gsb_data_reconcile_get_name ( gsb_data_transaction_get_reconcile_number ( transaction_number ) ) ); } /* Met les informations bancaires de l'opération. Elles n'existent qu'au niveau de l'opération mère */ CSV_CLEAR_FIELD(csv_field_info_bank); if ( gsb_data_transaction_get_bank_references ( transaction_number ) ) { csv_field_info_bank = my_strdup ( gsb_data_transaction_get_bank_references ( transaction_number ) ); } /* met le montant, transforme la devise si necessaire */ amount = gsb_data_transaction_get_adjusted_amount ( transaction_number, return_exponent); CSV_CLEAR_FIELD (csv_field_credit); if (amount.mantissa >= 0 ) csv_field_credit = utils_real_get_string (amount); else csv_field_debit = utils_real_get_string (gsb_real_abs (amount)); /* met le cheque si c'est un type à numerotation automatique */ payment_method = gsb_data_transaction_get_method_of_payment_number ( transaction_number ); CSV_CLEAR_FIELD (csv_field_cheque); if (gsb_data_payment_get_automatic_numbering (payment_method)) csv_field_cheque = my_strdup ( gsb_data_transaction_get_method_of_payment_content ( transaction_number ) ); if ( gsb_data_transaction_get_budgetary_number ( transaction_number ) != -1 ) { CSV_CLEAR_FIELD (csv_field_imput); csv_field_imput = my_strdup ( gsb_data_budget_get_name ( gsb_data_transaction_get_budgetary_number ( transaction_number ), 0, "" ) ); if ( gsb_data_transaction_get_sub_budgetary_number ( transaction_number ) != -1 ) { CSV_CLEAR_FIELD (csv_field_sous_imput); csv_field_sous_imput = my_strdup ( gsb_data_budget_get_sub_budget_name ( gsb_data_transaction_get_budgetary_number ( transaction_number ), gsb_data_transaction_get_sub_budgetary_number ( transaction_number ), NULL ) ); } } /* Piece comptable */ CSV_CLEAR_FIELD (csv_field_piece); csv_field_piece = my_strdup ( gsb_data_transaction_get_voucher ( transaction_number ) ); /* Balance */ if (print_balance) { current_balance = gsb_real_add ( current_balance, amount ); CSV_CLEAR_FIELD (csv_field_solde); csv_field_solde = utils_real_get_string (current_balance); } /* Number */ CSV_CLEAR_FIELD (csv_field_operation); csv_field_operation = g_strdup_printf("%d", transaction_number ); /* Account name */ CSV_CLEAR_FIELD (csv_field_account); csv_field_account = my_strdup (gsb_data_account_get_name (account_number)); /* Financial Year */ if ( gsb_data_transaction_get_financial_year_number ( transaction_number ) != -1 ) { CSV_CLEAR_FIELD (csv_field_exercice ); csv_field_exercice = my_strdup (gsb_data_fyear_get_name(gsb_data_transaction_get_financial_year_number ( transaction_number ))); } /* on met soit un virement, soit une ventilation, soit les catégories */ /* Si c'est une opération ventilée, on recherche toutes les ventilations de cette opération et on les traite immédiatement. */ /* et les met à la suite */ /* la catégorie de l'opé sera celle de la première opé de ventilation */ if ( gsb_data_transaction_get_split_of_transaction ( transaction_number ) ) { GSList *pSplitTransactionList; CSV_CLEAR_FIELD (csv_field_categ); csv_field_categ = my_strdup (_("Split of transaction")); csv_add_record(csv_file,FALSE, print_balance); pSplitTransactionList = gsb_data_transaction_get_transactions_list (); while ( pSplitTransactionList ) { gint pSplitTransaction; pSplitTransaction = gsb_data_transaction_get_transaction_number ( pSplitTransactionList -> data ); if ( gsb_data_transaction_get_account_number ( pSplitTransaction ) == gsb_data_transaction_get_account_number (transaction_number) && gsb_data_transaction_get_mother_transaction_number ( pSplitTransaction ) == transaction_number ) { /* on commence par mettre la catég et sous categ de l'opé et de l'opé de ventilation */ CSV_CLEAR_FIELD (csv_field_ventil); csv_field_ventil = my_strdup (_("B")); /* -> mark */ CSV_CLEAR_FIELD (csv_field_operation); csv_field_operation = g_strdup_printf("%d", pSplitTransaction ); if ( gsb_data_transaction_get_contra_transaction_number ( pSplitTransaction ) > 0) { /* c'est un virement */ CSV_CLEAR_FIELD (csv_field_categ); csv_field_categ = my_strdup (_("Transfer")); tmpstr = g_strconcat ( "[", gsb_data_account_get_name ( gsb_data_transaction_get_contra_transaction_account ( pSplitTransaction ) ), "]", NULL ); /* TODO dOm : is it necessary to duplicate memory with my_strdup since it was already newly allocated memory ? */ CSV_CLEAR_FIELD (csv_field_sous_categ); csv_field_sous_categ = my_strdup (tmpstr); g_free ( tmpstr ); } else { if ( gsb_data_transaction_get_category_number ( pSplitTransaction ) != -1 ) { CSV_CLEAR_FIELD (csv_field_categ); csv_field_categ = my_strdup ( gsb_data_category_get_name ( gsb_data_transaction_get_category_number ( pSplitTransaction ), 0, "" ) ); if ( gsb_data_transaction_get_sub_category_number ( pSplitTransaction ) != -1 ) { CSV_CLEAR_FIELD (csv_field_sous_categ); csv_field_sous_categ = my_strdup ( gsb_data_category_get_sub_category_name ( gsb_data_transaction_get_category_number ( pSplitTransaction ), gsb_data_transaction_get_sub_category_number ( pSplitTransaction ), NULL ) ); } } } /* met les notes de la ventilation */ if ( gsb_data_transaction_get_notes ( pSplitTransaction ) ) { CSV_CLEAR_FIELD (csv_field_notes); csv_field_notes = my_strdup (gsb_data_transaction_get_notes ( pSplitTransaction )); } /* met le montant de la ventilation */ amount = gsb_data_transaction_get_adjusted_amount ( pSplitTransaction, return_exponent ); CSV_CLEAR_FIELD (csv_field_montant); csv_field_montant = utils_real_get_string (amount); /* met le rapprochement */ if ( gsb_data_transaction_get_reconcile_number ( pSplitTransaction ) ) { CSV_CLEAR_FIELD (csv_field_rappro); csv_field_rappro = my_strdup ( gsb_data_reconcile_get_name ( gsb_data_transaction_get_reconcile_number ( pSplitTransaction ) ) ); } /* met le chèque si c'est un type à numéotation automatique */ payment_method = gsb_data_transaction_get_method_of_payment_number ( pSplitTransaction ); if (gsb_data_payment_get_automatic_numbering (payment_method)) { CSV_CLEAR_FIELD (csv_field_cheque); csv_field_cheque = my_strdup ( gsb_data_transaction_get_method_of_payment_content ( pSplitTransaction ) ); } /* Budgetary lines */ if ( gsb_data_transaction_get_budgetary_number ( pSplitTransaction ) != -1 ) { CSV_CLEAR_FIELD (csv_field_imput); csv_field_imput = my_strdup ( gsb_data_budget_get_name ( gsb_data_transaction_get_budgetary_number ( pSplitTransaction ), 0, "" ) ); if ( gsb_data_transaction_get_sub_budgetary_number ( pSplitTransaction ) != -1 ) { CSV_CLEAR_FIELD (csv_field_sous_imput); csv_field_sous_imput = my_strdup ( gsb_data_budget_get_sub_budget_name ( gsb_data_transaction_get_budgetary_number ( pSplitTransaction ), gsb_data_transaction_get_sub_budgetary_number ( pSplitTransaction ), NULL ) ); } } /* Piece comptable */ CSV_CLEAR_FIELD (csv_field_piece); csv_field_piece = my_strdup ( gsb_data_transaction_get_voucher ( pSplitTransaction ) ); /* Financial Year */ if ( gsb_data_transaction_get_financial_year_number ( pSplitTransaction ) != -1 ) { CSV_CLEAR_FIELD (csv_field_exercice ); csv_field_exercice = my_strdup (gsb_data_fyear_get_name(gsb_data_transaction_get_financial_year_number ( pSplitTransaction ))); } csv_add_record(csv_file,FALSE, print_balance); } pSplitTransactionList = pSplitTransactionList -> next; } csv_clear_fields(TRUE); } else { gchar *tmpstr; gint contra_transaction_number = gsb_data_transaction_get_contra_transaction_number ( transaction_number ); switch (contra_transaction_number) { case 0: /* normal category */ if ( gsb_data_transaction_get_category_number ( transaction_number ) != -1 ) { CSV_CLEAR_FIELD (csv_field_categ); csv_field_categ = my_strdup ( gsb_data_category_get_name ( gsb_data_transaction_get_category_number ( transaction_number ), 0, "" ) ); if ( gsb_data_transaction_get_sub_category_number ( transaction_number ) != -1 ) { CSV_CLEAR_FIELD (csv_field_sous_categ); csv_field_sous_categ = my_strdup ( gsb_data_category_get_sub_category_name ( gsb_data_transaction_get_category_number ( transaction_number ), gsb_data_transaction_get_sub_category_number ( transaction_number ), NULL ) ); } } break; case -1: /* transfer to deleted account */ CSV_CLEAR_FIELD (csv_field_categ); csv_field_categ = my_strdup (_("Transfer")); tmpstr = g_strconcat ( "[", _("Deleted account"), "]", NULL ); /* TODO dOm : is it necessary to duplicate memory with my_strdup since it was already newly allocated memory ? */ CSV_CLEAR_FIELD (csv_field_sous_categ); csv_field_sous_categ = my_strdup (tmpstr); g_free ( tmpstr ); break; default: /* transfer */ CSV_CLEAR_FIELD (csv_field_categ); csv_field_categ = my_strdup (_("Transfer")); tmpstr = g_strconcat ( "[", gsb_data_account_get_name ( gsb_data_transaction_get_contra_transaction_account ( transaction_number ) ), "]", NULL ); /* TODO dOm : is it necessary to duplicate memory with my_strdup since it was already newly allocated memory ? */ CSV_CLEAR_FIELD (csv_field_sous_categ); csv_field_sous_categ = my_strdup (tmpstr); g_free ( tmpstr ); } csv_add_record(csv_file,TRUE, print_balance); } return TRUE; }
/** * export an account into a csv file * * \param filename * \param account_nb the account to export * * \return TRUE if ok, FALSE if problem * */ gboolean gsb_csv_export_account ( const gchar *filename, gint account_number ) { FILE *csv_file; GSList *pTransactionList; GSList *tmp_list; csv_file = gsb_csv_export_open_file ( filename ); if ( !csv_file ) return FALSE; if ( g_csv_with_title_line ) gsb_csv_export_title_line ( csv_file, TRUE ); /* set the initial balance */ if ( csv_field_tiers ) g_free ( csv_field_tiers ); csv_field_tiers = g_strconcat (_("Initial balance") , " [", gsb_data_account_get_name ( account_number ), "]", NULL ); /* set the initial current_balance, * as we will write all the non archived transactions, * we need to get the initial balance of the account, without the archived transactions */ current_balance = gsb_data_account_get_init_balance ( account_number, -1); tmp_list = gsb_data_archive_store_get_archives_list ( ); while ( tmp_list ) { gint archive_store_number; archive_store_number = gsb_data_archive_store_get_number ( tmp_list -> data ); if ( gsb_data_archive_store_get_account_number ( archive_store_number ) == account_number ) current_balance = gsb_real_add ( current_balance, gsb_data_archive_store_get_balance ( archive_store_number ) ); tmp_list = tmp_list -> next; } /* ok the balance is now good, can write it */ CSV_CLEAR_FIELD ( csv_field_solde ); csv_field_solde = utils_real_get_string ( current_balance ); if ( current_balance.mantissa >= 0 ) { CSV_CLEAR_FIELD ( csv_field_credit ); csv_field_credit = utils_real_get_string ( current_balance ); } else { CSV_CLEAR_FIELD ( csv_field_debit ); csv_field_debit = utils_real_get_string ( gsb_real_abs ( current_balance ) ); } csv_add_record ( csv_file, TRUE, TRUE ); /* export the transactions */ pTransactionList = gsb_data_transaction_get_transactions_list ( ); tmp_list = g_slist_sort ( g_slist_copy ( pTransactionList ), (GCompareFunc) gsb_csv_export_sort_by_value_date_or_date ); while ( tmp_list ) { gint pTransaction; pTransaction = gsb_data_transaction_get_transaction_number ( tmp_list -> data ); if ( gsb_data_transaction_get_account_number ( pTransaction ) == account_number ) { /* export the transaction */ /* for now, print the balance. is this usefull ? */ gsb_csv_export_transaction ( pTransaction, csv_file, TRUE); } tmp_list = tmp_list -> next; } fclose ( csv_file ); g_slist_free ( tmp_list ); /* return */ return TRUE; }
/** * calcule le total du contenu de l'entrée donnée en argument * accepte les + et les - * / * * \param entry entrée d'un montant * * \return gsb_real total de ce qui est dans l'entrée */ gsb_real utils_real_get_calculate_entry ( GtkWidget *entry ) { gchar *string; gchar *pointeur; gsb_real total = null_real; string = my_strdup ( gtk_entry_get_text ( GTK_ENTRY ( entry ) ) ); if ( string && strlen ( string ) ) pointeur = string + strlen ( string ); else { if ( string ) g_free ( string ); return total; } if ( g_utf8_strchr ( string, -1, '-' ) || g_utf8_strchr ( string, -1, '+' ) ) { while ( pointeur != string ) { if ( pointeur[0] == '+' || pointeur[0] == '-' ) { total = gsb_real_add ( total, utils_real_get_from_string ( pointeur ) ); pointeur[0] = 0; } pointeur--; } total = gsb_real_add ( total, utils_real_get_from_string ( pointeur ) ); } else if ( g_utf8_strchr ( string, -1, '*' ) ) { total.mantissa = 1; total.exponent = 0; while ( pointeur != string ) { if ( pointeur[0] == '*' ) { total = gsb_real_mul ( total, utils_real_get_from_string ( pointeur + 1 ) ); pointeur[0] = 0; } pointeur--; } total = gsb_real_mul ( total, utils_real_get_from_string ( pointeur ) ); } else if ( g_utf8_strchr ( string, -1, '/' ) ) { gchar **tab; tab = g_strsplit ( string, "/", 2 ); total = gsb_real_div ( utils_real_get_from_string ( tab[0] ), utils_real_get_from_string ( tab[1] ) ); g_strfreev ( tab ); } else total = utils_real_get_from_string ( string ); g_free ( string ); return total; }
/** * substract between 2 gsb_real : number_1 - number_2 * * \param number_1 * \param number_2 * * \return a gsb_real = number_1 - number_2 * */ gsb_real gsb_real_sub ( gsb_real number_1, gsb_real number_2 ) { number_2.mantissa = -number_2.mantissa; return gsb_real_add ( number_1, number_2 ); }