/** * 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; }
/** * used to compare 2 iters and sort the by value date or date if not exist * always put the white line below * * \param model the GtkTreeModel * \param iter_1 * \param iter_2 * * \return -1 if iter_1 is above iter_2 * */ gint gsb_transactions_list_sort_by_value_date ( gint transaction_number_1, gint transaction_number_2 ) { gint return_value; const GDate *value_date_1 = NULL; const GDate *value_date_2 = NULL; if (conf.transactions_list_primary_sorting == 2) return gsb_transactions_list_sort_by_date (transaction_number_1, transaction_number_2); /* need to work a little more here because value date is not obligatory filled, * if we compare 2 transactions and 1 has no value date, set the value date before */ value_date_1 = gsb_data_transaction_get_value_date ( transaction_number_1 ); if ( !value_date_1 && !conf.transactions_list_primary_sorting ) 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 && !conf.transactions_list_primary_sorting ) value_date_2 = gsb_data_transaction_get_date ( transaction_number_2 ); if ( value_date_1 ) { if (value_date_2) return_value = g_date_compare ( value_date_1, value_date_2); else return_value = -1; } else { if (value_date_2) return_value = 1; else return gsb_transactions_list_sort_by_date ( transaction_number_1, transaction_number_2 ); } if ( return_value ) return return_value; else return gsb_transactions_list_sort_initial_by_secondary_key ( transaction_number_1, transaction_number_2 ); }
/** * 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; }
/** * 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; }
/** * 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; }