1 /* ************************************************************************** */
2 /*                                                                            */
3 /*     Copyright (C) 2007 Dominique Parisot                                   */
4 /*          zionly@free.org                                                   */
5 /*          2008-2020 Pierre Biava (grisbi@pierre.biava.name)                 */
6 /*          https://www.grisbi.org/                                           */
7 /*                                                                            */
8 /*  This program is free software; you can redistribute it and/or modify      */
9 /*  it under the terms of the GNU General Public License as published by      */
10 /*  the Free Software Foundation; either version 2 of the License, or         */
11 /*  (at your option) any later version.                                       */
12 /*                                                                            */
13 /*  This program is distributed in the hope that it will be useful,           */
14 /*  but WITHOUT ANY WARRANTY; without even the implied warranty of            */
15 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             */
16 /*  GNU General Public License for more details.                              */
17 /*                                                                            */
18 /*  You should have received a copy of the GNU General Public License         */
19 /*  along with this program; if not, write to the Free Software               */
20 /*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
21 /*                                                                            */
22 /* ************************************************************************** */
23 
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27 
28 #include "include.h"
29 #include <glib/gi18n.h>
30 
31 /*START_INCLUDE*/
32 #include "bet_data.h"
33 #include "bet_data_finance.h"
34 #include "bet_future.h"
35 #include "bet_hist.h"
36 #include "bet_tab.h"
37 #include "dialog.h"
38 #include "grisbi_win.h"
39 #include "gsb_data_account.h"
40 #include "gsb_data_budget.h"
41 #include "gsb_data_category.h"
42 #include "gsb_data_mix.h"
43 #include "gsb_data_partial_balance.h"
44 #include "gsb_data_scheduled.h"
45 #include "gsb_data_transaction.h"
46 #include "gsb_file.h"
47 #include "gsb_file_save.h"
48 #include "gsb_scheduler_list.h"
49 #include "gsb_transactions_list.h"
50 #include "navigation.h"
51 #include "structures.h"
52 #include "traitement_variables.h"
53 #include "utils_dates.h"
54 #include "utils_real.h"
55 #include "utils_str.h"
56 #include "erreur.h"
57 /*END_INCLUDE*/
58 
59 
60 /*START_STATIC*/
61 static GDate *bet_data_futur_get_next_date ( FuturData *scheduled,
62                         const GDate *date,
63                         const GDate *date_max );
64 static FuturData *bet_data_future_copy_struct ( FuturData *scheduled );
65 static void bet_data_future_set_max_number ( gint number );
66 static gchar *bet_data_get_key ( gint account_number, gint div_number );
67 static gboolean bet_data_update_div ( BetHist *sh,
68                         gint transaction_number,
69                         gint sub_div,
70                         gint type_de_transaction,
71                         GsbReal amount );
72 static void struct_free_bet_future ( FuturData *scheduled );
73 static void struct_free_hist_div ( HistDiv *shd );
74 static BetHist *struct_initialise_bet_historical ( void );
75 /*END_STATIC*/
76 
77 
78 /*START_EXTERN*/
79 /*END_EXTERN*/
80 
81 
82 /* pointeurs définis en fonction du type de données catégories ou IB */
83 gint (*ptr_div) ( gint transaction_num, gboolean is_transaction );
84 gint (*ptr_sub_div) ( gint transaction_num, gboolean is_transaction );
85 gint (*ptr_type) ( gint no_div );
86 gchar* (*ptr_div_name) ( gint div_num, gint sub_div, const gchar *return_value_error );
87 
88 
89 /* liste des div et sub_div cochées dans la vue des divisions */
90 static GHashTable *bet_hist_div_list;
91 
92 /** the hashtable which contains all the bet_future structures */
93 static GHashTable *bet_future_list;
94 static gint future_number;
95 
96 /** the hashtable for account_balance */
97 static GHashTable *bet_transfert_list;
98 static gint transfert_number;
99 
100 /******************************************************************************/
101 /* Private functions                                                          */
102 /******************************************************************************/
103 /**
104  *
105  *
106  * \param
107  * \param
108  * \param
109  *
110  * \return
111  **/
bet_data_hist_set_account_number(gpointer key,gpointer value,gpointer user_data)112 static void bet_data_hist_set_account_number (gpointer key,
113 											  gpointer value,
114 											  gpointer user_data)
115 {
116 	HistDiv *shd = (HistDiv *) value;
117 
118 	if (shd->account_nb == 0)
119 		shd->account_nb = GPOINTER_TO_INT (user_data);
120 }
121 
122 /**
123  *
124  *
125  * \param
126  * \param
127  * \param
128  *
129  * \return
130  **/
bet_data_future_set_account_number(gpointer key,gpointer value,gpointer user_data)131 static void bet_data_future_set_account_number (gpointer key,
132 												   gpointer value,
133 												   gpointer user_data)
134 {
135 	FuturData *sfd = (FuturData *) value;
136 
137 	if (sfd->account_number == 0)
138 		sfd->account_number = GPOINTER_TO_INT (user_data);
139 }
140 
141 /**
142  *
143  *
144  * \param
145  * \param
146  * \param
147  *
148  * \return
149  **/
bet_data_transfert_set_account_number(gpointer key,gpointer value,gpointer user_data)150 static void bet_data_transfert_set_account_number (gpointer key,
151 												   gpointer value,
152 												   gpointer user_data)
153 {
154 	TransfertData *transfert = (TransfertData *) value;
155 
156 	if (transfert->account_number == 0)
157 		transfert->account_number = GPOINTER_TO_INT (user_data);
158 }
159 
160 /**
161  * Sélectionne les onglets du module gestion budgétaire en fonction du type de compte
162  *
163  */
bet_data_select_bet_pages(gint account_number)164 void bet_data_select_bet_pages ( gint account_number )
165 {
166     GtkWidget *page;
167     GtkWidget *account_page;
168     gint current_page;
169     BetTypeOnglets bet_show_onglets;
170 
171     devel_debug_int ( account_number );
172     bet_show_onglets = gsb_data_account_get_bet_show_onglets ( account_number );
173     account_page = grisbi_win_get_account_page ();
174     current_page = gtk_notebook_get_current_page ( GTK_NOTEBOOK ( account_page ) );
175 
176     switch ( bet_show_onglets )
177     {
178     case BET_ONGLETS_PREV:
179         page = gtk_notebook_get_nth_page ( GTK_NOTEBOOK ( account_page ), GSB_ESTIMATE_PAGE );
180         gtk_widget_show ( page );
181         page = gtk_notebook_get_nth_page ( GTK_NOTEBOOK ( account_page ), GSB_HISTORICAL_PAGE );
182         gtk_widget_show ( page );
183         page = gtk_notebook_get_nth_page ( GTK_NOTEBOOK ( account_page ), GSB_FINANCE_PAGE );
184         gtk_widget_hide ( page );
185         bet_historical_g_signal_unblock_tree_view ( );
186         gsb_data_account_set_bet_maj ( account_number, BET_MAJ_ALL );
187         if ( current_page < GSB_PROPERTIES_PAGE
188          &&
189          gsb_data_account_get_bet_use_budget ( account_number ) == FALSE )
190             gtk_notebook_set_current_page ( GTK_NOTEBOOK ( account_page ), GSB_TRANSACTIONS_PAGE );
191         if ( current_page == GSB_FINANCE_PAGE )
192             gtk_notebook_set_current_page ( GTK_NOTEBOOK ( account_page ), GSB_ESTIMATE_PAGE );
193         break;
194     case BET_ONGLETS_HIST:
195         page = gtk_notebook_get_nth_page ( GTK_NOTEBOOK ( account_page ), GSB_ESTIMATE_PAGE );
196         gtk_widget_hide ( page );
197         page = gtk_notebook_get_nth_page ( GTK_NOTEBOOK ( account_page ), GSB_HISTORICAL_PAGE );
198         gtk_widget_show ( page );
199         page = gtk_notebook_get_nth_page ( GTK_NOTEBOOK ( account_page ), GSB_FINANCE_PAGE );
200         gtk_widget_hide ( page );
201         if ( current_page == GSB_ESTIMATE_PAGE || current_page == GSB_FINANCE_PAGE )
202             gtk_notebook_set_current_page ( GTK_NOTEBOOK ( account_page ), GSB_TRANSACTIONS_PAGE );
203         bet_historical_g_signal_block_tree_view ( );
204         gsb_data_account_set_bet_maj ( account_number, BET_MAJ_HISTORICAL );
205         break;
206     case BET_ONGLETS_CAP:
207         page = gtk_notebook_get_nth_page ( GTK_NOTEBOOK ( account_page ), GSB_ESTIMATE_PAGE );
208         gtk_widget_hide ( page );
209         page = gtk_notebook_get_nth_page ( GTK_NOTEBOOK ( account_page ), GSB_HISTORICAL_PAGE );
210         gtk_widget_hide ( page );
211         page = gtk_notebook_get_nth_page ( GTK_NOTEBOOK ( account_page ), GSB_FINANCE_PAGE );
212         gtk_widget_show ( page );
213         if ( current_page == GSB_ESTIMATE_PAGE || current_page == GSB_HISTORICAL_PAGE )
214             gtk_notebook_set_current_page ( GTK_NOTEBOOK ( account_page ), GSB_TRANSACTIONS_PAGE );
215         break;
216 	case BET_ONGLETS_SANS:
217 	case BET_ONGLETS_ASSET:
218     default:
219         if ( current_page < GSB_PROPERTIES_PAGE )
220             gtk_notebook_set_current_page ( GTK_NOTEBOOK ( account_page ), GSB_TRANSACTIONS_PAGE );
221         page = gtk_notebook_get_nth_page ( GTK_NOTEBOOK ( account_page ), GSB_ESTIMATE_PAGE );
222         gtk_widget_hide ( page );
223         page = gtk_notebook_get_nth_page ( GTK_NOTEBOOK ( account_page ), GSB_HISTORICAL_PAGE );
224         gtk_widget_hide ( page );
225         page = gtk_notebook_get_nth_page ( GTK_NOTEBOOK ( account_page ), GSB_FINANCE_PAGE );
226         gtk_widget_hide ( page );
227         break;
228     }
229 }
230 
231 
232 /*
233  * Met à jour les données à afficher dans les différentes vues du module
234  *
235  *
236  */
bet_data_update_bet_module(gint account_number,gint page)237 void bet_data_update_bet_module ( gint account_number, gint page )
238 {
239     gint type_maj;
240 
241     devel_debug_int ( account_number );
242 
243     /* test account number */
244     if ( account_number == -1 )
245         return;
246 
247     type_maj = gsb_data_account_get_bet_maj ( account_number );
248     if ( type_maj == BET_MAJ_FALSE )
249         return;
250 
251     if ( page == -1 && gsb_gui_navigation_get_current_page () == GSB_ACCOUNT_PAGE )
252         page = gtk_notebook_get_current_page ( GTK_NOTEBOOK ( grisbi_win_get_account_page () ) );
253 
254     switch ( page )
255     {
256         case GSB_ESTIMATE_PAGE:
257             bet_array_update_estimate_tab ( account_number, type_maj );
258             gsb_data_account_set_bet_maj ( account_number, BET_MAJ_FALSE );
259             break;
260         case GSB_HISTORICAL_PAGE:
261             if ( type_maj == BET_MAJ_ALL )
262             {
263                 bet_historical_populate_data ( account_number );
264                 gsb_data_account_set_bet_maj ( account_number, BET_MAJ_ESTIMATE );
265             }
266             else if ( type_maj ==  BET_MAJ_HISTORICAL )
267             {
268                 bet_historical_populate_data ( account_number );
269                 gsb_data_account_set_bet_maj ( account_number, BET_MAJ_FALSE );
270             }
271             bet_historical_set_page_title ( account_number );
272             break;
273         default:
274             break;
275     }
276 }
277 
278 
279 /**
280  * used when we init all the global variables
281  *
282  * \param
283  *
284  * \return FALSE
285  * */
bet_data_init_variables(void)286 gboolean bet_data_init_variables ( void )
287 {
288     if ( bet_hist_div_list )
289         g_hash_table_destroy ( bet_hist_div_list );
290     bet_hist_div_list = g_hash_table_new_full ( g_str_hash,
291                         g_str_equal,
292                         (GDestroyNotify) g_free,
293                         (GDestroyNotify) struct_free_hist_div );
294 
295     if ( bet_future_list )
296         g_hash_table_destroy ( bet_future_list );
297     bet_future_list = g_hash_table_new_full ( g_str_hash,
298                         g_str_equal,
299                         (GDestroyNotify) g_free,
300                         (GDestroyNotify) struct_free_bet_future );
301     future_number = 0;
302 
303     if ( bet_transfert_list )
304         g_hash_table_destroy ( bet_transfert_list );
305     bet_transfert_list = g_hash_table_new_full ( g_str_hash,
306                         g_str_equal,
307                         (GDestroyNotify) g_free,
308                         (GDestroyNotify) struct_free_bet_transfert );
309     transfert_number = 0;
310 
311     return FALSE;
312 }
313 
314 
315 /**
316  * used to free the global variables
317  *
318  * \param
319  *
320  * \return
321  * */
bet_data_free_variables(void)322 void bet_data_free_variables ( void )
323 {
324 	if (bet_hist_div_list)
325 		g_hash_table_destroy ( bet_hist_div_list );
326 	if (bet_future_list)
327 		g_hash_table_destroy ( bet_future_list );
328 	if (bet_transfert_list)
329 		g_hash_table_destroy ( bet_transfert_list );
330 }
331 
332 
333 /**
334  *
335  *
336  *
337  *
338  * */
bet_data_hist_add_div(gint account_number,gint div_number,gint sub_div_nb)339 gboolean bet_data_hist_add_div ( gint account_number,
340                         gint div_number,
341                         gint sub_div_nb )
342 {
343     gchar *key = NULL;
344     gchar *sub_key = NULL;
345     HistDiv *shd;
346 
347     key = bet_data_get_key ( account_number, div_number );
348 
349     if ( ( shd = g_hash_table_lookup ( bet_hist_div_list, key ) ) )
350     {
351         g_free ( key );
352         shd -> div_edited = FALSE;
353         shd -> amount = null_real;
354 
355         if ( sub_div_nb > 0 )
356         {
357             sub_key = utils_str_itoa ( sub_div_nb );
358             if (  !g_hash_table_lookup ( shd -> sub_div_list, sub_key ) )
359             {
360                 HistDiv *sub_shd;
361 
362                 sub_shd = struct_initialise_hist_div ( );
363                 if ( !sub_shd )
364                 {
365                     dialogue_error_memory ( );
366                     g_free ( sub_key );
367                     return FALSE;
368                 }
369                 sub_shd -> div_number = sub_div_nb;
370                 g_hash_table_insert ( shd -> sub_div_list, sub_key, sub_shd );
371             }
372             else
373             {
374                 shd -> div_edited = FALSE;
375                 shd -> amount = null_real;
376                 g_free ( sub_key );
377             }
378         }
379     }
380     else
381     {
382         shd = struct_initialise_hist_div ( );
383         if ( !shd )
384         {
385             dialogue_error_memory ( );
386             return FALSE;
387         }
388         shd -> account_nb = account_number;
389         shd -> origin = gsb_data_account_get_bet_hist_data ( account_number );
390         shd -> div_number = div_number;
391         if ( sub_div_nb > 0 )
392         {
393             HistDiv *sub_shd;
394 
395             sub_shd = struct_initialise_hist_div ( );
396             if ( !sub_shd )
397             {
398                 dialogue_error_memory ( );
399                 struct_free_hist_div  ( shd );
400                 return FALSE;
401             }
402             sub_key = utils_str_itoa ( sub_div_nb );
403             sub_shd -> div_number = sub_div_nb;
404             g_hash_table_insert ( shd -> sub_div_list, sub_key, sub_shd );
405         }
406         g_hash_table_insert ( bet_hist_div_list, key, shd );
407     }
408 
409     return TRUE;
410 }
411 
412 
413 /**
414  *
415  *
416  *
417  *
418  * */
bet_data_insert_div_hist(HistDiv * shd,HistDiv * sub_shd)419 void bet_data_insert_div_hist ( HistDiv *shd, HistDiv *sub_shd )
420 {
421     gchar *key;
422     gchar *sub_key;
423     HistDiv *tmp_shd;
424 
425     key = bet_data_get_key ( shd -> account_nb, shd -> div_number );
426 
427     if ( ( tmp_shd = g_hash_table_lookup ( bet_hist_div_list, key ) ) )
428     {
429         g_free ( key );
430         tmp_shd -> div_edited = shd -> div_edited;
431         tmp_shd -> amount = shd -> amount;
432 
433         if ( sub_shd )
434         {
435             sub_key = utils_str_itoa ( sub_shd -> div_number );
436             g_hash_table_insert ( tmp_shd -> sub_div_list, sub_key, sub_shd );
437         }
438 		struct_free_hist_div (shd);
439     }
440     else
441     {
442         if ( sub_shd )
443         {
444             sub_key = utils_str_itoa ( sub_shd -> div_number );
445             g_hash_table_insert ( shd -> sub_div_list, sub_key, sub_shd );
446         }
447         g_hash_table_insert ( bet_hist_div_list, key, shd );
448     }
449 }
450 
451 
452 /**
453  *
454  *
455  *
456  *
457  * */
bet_data_remove_div_hist(gint account_number,gint div_number,gint sub_div_nb)458 gboolean bet_data_remove_div_hist ( gint account_number, gint div_number, gint sub_div_nb )
459 {
460     gchar *key;
461     char *sub_key;
462     HistDiv *shd;
463     gboolean return_val = FALSE;
464 
465     key = bet_data_get_key ( account_number, div_number );
466 
467     if ( ( shd = g_hash_table_lookup ( bet_hist_div_list, key ) ) )
468     {
469         return_val = TRUE;
470         if ( sub_div_nb > 0 )
471         {
472             sub_key = utils_str_itoa ( sub_div_nb );
473             g_hash_table_remove ( shd -> sub_div_list, sub_key );
474             g_free ( sub_key );
475         }
476         if ( g_hash_table_size ( shd -> sub_div_list ) == 0 )
477             g_hash_table_remove ( bet_hist_div_list, key );
478     }
479     g_free ( key );
480 
481     return return_val;
482 }
483 
484 
485 /**
486  * return TRUE si la division et sous division existe.
487  *
488  *
489  *
490  * */
bet_data_search_div_hist(gint account_number,gint div_number,gint sub_div_nb)491 gboolean bet_data_search_div_hist ( gint account_number, gint div_number, gint sub_div_nb )
492 {
493     gchar *key;
494     gchar *sub_key;
495     gint origin;
496     HistDiv *shd;
497     gboolean return_val = FALSE;
498 
499     key = bet_data_get_key ( account_number, div_number );
500 
501     origin = gsb_data_account_get_bet_hist_data ( account_number );
502 
503     if ( ( shd = g_hash_table_lookup ( bet_hist_div_list, key ) )
504      && shd -> origin == origin )
505     {
506         if ( sub_div_nb == 0 )
507             return_val = TRUE;
508         else if ( sub_div_nb > 0 )
509         {
510             sub_key = utils_str_itoa ( sub_div_nb );
511             if ( g_hash_table_lookup ( shd -> sub_div_list, sub_key ) )
512                 return_val = TRUE;
513             g_free ( sub_key );
514         }
515     }
516     g_free ( key );
517 
518     return return_val;
519 }
520 
521 
522 /**
523  *
524  *
525  *
526  *
527  * */
bet_data_set_div_ptr(gint type_div)528 gboolean bet_data_set_div_ptr ( gint type_div )
529 {
530     if ( type_div == 0 )
531     {
532         ptr_div = &gsb_data_mix_get_category_number;
533         ptr_sub_div = &gsb_data_mix_get_sub_category_number;
534         ptr_type = &gsb_data_category_get_type;
535         ptr_div_name = &gsb_data_category_get_name;
536     }
537     else
538     {
539         ptr_div = &gsb_data_mix_get_budgetary_number;
540         ptr_sub_div = &gsb_data_mix_get_sub_budgetary_number;
541         ptr_type = &gsb_data_budget_get_type;
542         ptr_div_name = &gsb_data_budget_get_name;
543     }
544 
545     return FALSE;
546 }
547 /**
548  *
549  *
550  *
551  *
552  * */
bet_data_get_div_number(gint transaction_number,gboolean is_transaction)553 gint bet_data_get_div_number ( gint transaction_number, gboolean is_transaction )
554 {
555     return ptr_div ( transaction_number, is_transaction );
556 }
557 
558 
559 /**
560  *
561  *
562  *
563  *
564  * */
bet_data_get_sub_div_nb(gint transaction_number,gboolean is_transaction)565 gint bet_data_get_sub_div_nb ( gint transaction_number, gboolean is_transaction )
566 {
567     return ptr_sub_div ( transaction_number, is_transaction );
568 }
569 
570 
571 /**
572  *
573  *
574  *
575  *
576  * */
bet_data_get_div_type(gint div_number)577 gint bet_data_get_div_type ( gint div_number )
578 {
579     return ptr_type ( div_number );
580 }
581 
582 
583 /**
584  *
585  *
586  *
587  *
588  * */
bet_data_get_div_name(gint div_num,gint sub_div,const gchar * return_value_error)589 gchar *bet_data_get_div_name ( gint div_num,
590                         gint sub_div,
591                         const gchar *return_value_error )
592 {
593     return ptr_div_name ( div_num, sub_div, NULL );
594 }
595 
596 
597 /**
598  *
599  *
600  *
601  *
602  * */
bet_data_get_div_edited(gint account_number,gint div_number,gint sub_div_nb)603 gboolean bet_data_get_div_edited ( gint account_number, gint div_number, gint sub_div_nb )
604 {
605     gchar *key;
606     gint origin;
607     HistDiv *shd;
608     gboolean edited;
609 
610     key = bet_data_get_key ( account_number, div_number );
611 
612     origin = gsb_data_account_get_bet_hist_data ( account_number );
613 
614     if ( ( shd = g_hash_table_lookup ( bet_hist_div_list, key ) )
615      && shd -> origin == origin )
616     {
617         if ( sub_div_nb == 0 )
618             edited = shd -> div_edited;
619         else
620         {
621             gchar *sub_key;
622             HistDiv *sub_shd;
623 
624             sub_key = utils_str_itoa ( sub_div_nb );
625             if ( ( sub_shd = g_hash_table_lookup ( shd -> sub_div_list, sub_key ) ) )
626                 edited = sub_shd -> div_edited;
627             else
628                 edited = FALSE;
629             g_free ( sub_key );
630         }
631     }
632     else
633         edited = FALSE;
634     g_free ( key );
635 
636     return edited;
637 }
638 
639 
640 /**
641  *
642  *
643  *
644  *
645  * */
bet_data_set_div_edited(gint account_nb,gint div_number,gint sub_div_nb,gboolean edited)646 gboolean bet_data_set_div_edited ( gint account_nb,
647                         gint div_number,
648                         gint sub_div_nb,
649                         gboolean edited )
650 {
651     gchar *key;
652     HistDiv *shd;
653 
654     key = bet_data_get_key ( account_nb, div_number );
655 
656     if ( ( shd = g_hash_table_lookup ( bet_hist_div_list, key ) ) )
657     {
658         if ( sub_div_nb == 0 )
659             shd -> div_edited = edited;
660         else
661         {
662             gchar *sub_key;
663             HistDiv *sub_shd;
664 
665             sub_key = utils_str_itoa ( sub_div_nb );
666             if ( ( sub_shd = g_hash_table_lookup ( shd -> sub_div_list, sub_key ) ) )
667                 sub_shd -> div_edited = edited;
668             g_free ( sub_key );
669         }
670     }
671 
672     g_free ( key );
673 
674     return FALSE;
675 }
676 
677 
678 /**
679  *
680  *
681  *
682  *
683  * */
bet_data_hist_get_div_amount(gint account_nb,gint div_number,gint sub_div_nb)684 GsbReal bet_data_hist_get_div_amount ( gint account_nb, gint div_number, gint sub_div_nb )
685 {
686     gchar *key;
687     HistDiv *shd;
688     GsbReal amount;
689 
690     key = bet_data_get_key ( account_nb, div_number );
691 
692     if ( ( shd = g_hash_table_lookup ( bet_hist_div_list, key ) ) )
693     {
694         if ( sub_div_nb == 0 )
695             amount = shd -> amount;
696         else
697         {
698             gchar *sub_key;
699             HistDiv *sub_shd;
700 
701             sub_key = utils_str_itoa ( sub_div_nb );
702             if ( ( sub_shd = g_hash_table_lookup ( shd -> sub_div_list, sub_key ) ) )
703                 amount = sub_shd -> amount;
704             else
705                 amount = null_real;
706             g_free ( sub_key );
707         }
708     }
709     else
710         amount = null_real;
711     g_free ( key );
712 
713     return amount;
714 }
715 
716 
717 /**
718  *
719  *
720  *
721  *
722  * */
bet_data_set_div_amount(gint account_nb,gint div_number,gint sub_div_nb,GsbReal amount)723 gboolean bet_data_set_div_amount ( gint account_nb,
724                         gint div_number,
725                         gint sub_div_nb,
726                         GsbReal amount )
727 {
728     gchar *key;
729     HistDiv *shd;
730 
731     key = bet_data_get_key ( account_nb, div_number );
732 
733     if ( ( shd = g_hash_table_lookup ( bet_hist_div_list, key ) ) )
734     {
735         if ( sub_div_nb == 0 )
736             shd -> amount = amount;
737         else
738         {
739             gchar *sub_key;
740             HistDiv *sub_shd;
741 
742             sub_key = utils_str_itoa ( sub_div_nb );
743             if ( ( sub_shd = g_hash_table_lookup ( shd -> sub_div_list, sub_key ) ) )
744                 sub_shd -> amount = amount;
745             g_free ( sub_key );
746         }
747     }
748 
749     g_free ( key );
750 
751     return FALSE;
752 }
753 
754 
755 /**
756  *
757  *
758  *
759  *
760  * */
bet_data_get_selected_currency(void)761 gint bet_data_get_selected_currency ( void )
762 {
763     gint selected_account;
764     gint currency_number;
765 
766     selected_account = gsb_gui_navigation_get_current_account ( );
767     if ( selected_account == -1 )
768         return 0;
769 
770     currency_number = gsb_data_account_get_currency ( selected_account );
771 
772     return currency_number;
773 }
774 
775 
776 /**
777  * Ajoute les données de la transaction à la division et la sous division
778  * création des nouvelles divisions et si existantes ajout des données
779  * par appel à bet_data_update_div ( )
780  *
781  * */
bet_data_populate_div(gint transaction_number,gboolean is_transaction,GHashTable * list_div,gint type_de_transaction,TransactionCurrentFyear * tcf)782 gboolean bet_data_populate_div ( gint transaction_number,
783                         gboolean is_transaction,
784                         GHashTable  *list_div,
785                         gint type_de_transaction,
786                         TransactionCurrentFyear *tcf )
787 {
788     gint div = 0;
789     gint sub_div = 0;
790     gchar *key;
791     BetHist *sh = NULL;
792     GsbReal amount;
793 
794     div = ptr_div ( transaction_number, is_transaction );
795     if ( div > 0 )
796         sub_div = ptr_sub_div ( transaction_number, is_transaction );
797     else
798         return FALSE;
799 
800     amount = gsb_data_transaction_get_amount ( transaction_number );
801     /* on complète la structure tcf pour les graphiques */
802     if ( tcf )
803     {
804         tcf->div_nb = div;
805         tcf->sub_div_nb = sub_div;
806         tcf->amount = amount;
807     }
808 
809     key = utils_str_itoa ( div );
810     if ( (sh = g_hash_table_lookup ( list_div, key ) ) )
811     {
812         bet_data_update_div ( sh, transaction_number, sub_div, type_de_transaction, amount );
813         g_free ( key );
814     }
815     else
816     {
817         sh = struct_initialise_bet_historical ( );
818         sh -> div = div;
819         sh -> account_nb = gsb_data_transaction_get_account_number ( transaction_number );
820         bet_data_update_div ( sh, transaction_number, sub_div, type_de_transaction, amount );
821         g_hash_table_insert ( list_div, key, sh );
822     }
823 
824     /* return value */
825     return FALSE;
826 }
827 
828 
829 /**
830  * Ajout des données à la division et création de la sous division si elle
831  * n'existe pas.
832  *
833  *
834  * */
bet_data_update_div(BetHist * sh,gint transaction_number,gint sub_div,gint type_de_transaction,GsbReal amount)835 gboolean bet_data_update_div ( BetHist *sh,
836                         gint transaction_number,
837                         gint sub_div,
838                         gint type_de_transaction,
839                         GsbReal amount )
840 {
841     BetRange *sbr = ( BetRange*) sh -> sbr;
842     gchar *key;
843     BetHist *tmp_sh = NULL;
844 
845     switch ( type_de_transaction )
846     {
847         case 0:
848             sbr-> current_balance = gsb_real_add ( sbr -> current_balance, amount );
849             break;
850         case 1:
851             sbr-> current_fyear = gsb_real_add ( sbr -> current_fyear, amount );
852             break;
853         case 2:
854             sbr-> current_balance = gsb_real_add ( sbr -> current_balance, amount );
855             sbr-> current_fyear = gsb_real_add ( sbr -> current_fyear, amount );
856             break;
857     }
858 
859     if ( sub_div < 1 )
860         return FALSE;
861 
862     key = utils_str_itoa ( sub_div );
863     if ( ( tmp_sh = g_hash_table_lookup ( sh -> list_sub_div, key ) ) )
864     {
865         bet_data_update_div ( tmp_sh, transaction_number, -1, type_de_transaction, amount );
866         g_free ( key );
867     }
868     else
869     {
870         tmp_sh = struct_initialise_bet_historical ( );
871         tmp_sh -> div = sub_div;
872         tmp_sh -> account_nb = gsb_data_transaction_get_account_number ( transaction_number );
873         bet_data_update_div ( tmp_sh, transaction_number, -1, type_de_transaction, amount );
874         g_hash_table_insert ( sh -> list_sub_div, key, tmp_sh );
875     }
876 
877     return FALSE;
878 }
879 
880 
881 /**
882  *
883  *
884  *
885  *
886  * */
bet_data_get_strings_to_save(void)887 GPtrArray *bet_data_get_strings_to_save ( void )
888 {
889     GPtrArray *tab = NULL;
890 	GSList *tmp_list;
891     gchar *tmp_str = NULL;
892     GHashTableIter iter;
893     gpointer key, value;
894 
895     if ( g_hash_table_size ( bet_hist_div_list ) == 0
896 		&& g_hash_table_size ( bet_future_list ) == 0
897 		&& g_hash_table_size (bet_transfert_list) == 0
898 		&& g_slist_length (bet_data_loan_get_loan_list()) == 0)
899 	{
900         return NULL;
901 	}
902 
903 	/* au moins 1 table a des éléments */
904     tab = g_ptr_array_new ( );
905 
906 	if (g_hash_table_size (bet_hist_div_list) > 0)
907 	{
908 		g_hash_table_iter_init ( &iter, bet_hist_div_list );
909 		while ( g_hash_table_iter_next ( &iter, &key, &value ) )
910 		{
911 			HistDiv *shd = ( HistDiv* ) value;
912 
913 			if ( g_hash_table_size ( shd -> sub_div_list ) == 0 )
914 			{
915 				gchar *str_to_free;
916 
917 				str_to_free = gsb_real_safe_real_to_string (shd -> amount,
918 				                                            gsb_data_account_get_currency_floating_point
919 				                                            (shd -> account_nb));
920 				tmp_str = g_markup_printf_escaped ( "\t<Bet_historical Nb=\"%d\" Ac=\"%d\" "
921 							"Ori=\"%d\" Div=\"%d\" Edit=\"%d\" Damount=\"%s\" SDiv=\"%d\" "
922 							"SEdit=\"%d\" SDamount=\"%s\" />\n",
923 							tab -> len + 1,
924 							shd -> account_nb,
925 							shd -> origin,
926 							shd -> div_number,
927 							shd -> div_edited,
928 							str_to_free,
929 							0, 0, "0.00" );
930 
931 				g_ptr_array_add ( tab, tmp_str );
932 				g_free (str_to_free);
933 			}
934 			else
935 			{
936 				GHashTableIter new_iter;
937 
938 				g_hash_table_iter_init ( &new_iter, shd -> sub_div_list );
939 				while ( g_hash_table_iter_next ( &new_iter, &key, &value ) )
940 				{
941 					HistDiv *sub_shd = ( HistDiv* ) value;
942 					gchar *str_to_free_1;
943 					gchar *str_to_free_2;
944 					gint floating_point;
945 
946 					floating_point = gsb_data_account_get_currency_floating_point ( shd -> account_nb );
947 					str_to_free_1 = gsb_real_safe_real_to_string (shd -> amount, floating_point);
948 					str_to_free_2 = gsb_real_safe_real_to_string (sub_shd -> amount, floating_point);
949 					tmp_str = g_markup_printf_escaped ( "\t<Bet_historical Nb=\"%d\" Ac=\"%d\" "
950 							"Ori=\"%d\" Div=\"%d\" Edit=\"%d\" Damount=\"%s\" SDiv=\"%d\" "
951 							"SEdit=\"%d\" SDamount=\"%s\" />\n",
952 							tab -> len + 1,
953 							shd -> account_nb,
954 							shd -> origin,
955 							shd -> div_number,
956 							shd -> div_edited,
957 							str_to_free_1,
958 							sub_shd -> div_number,
959 							sub_shd -> div_edited,
960 							str_to_free_2);
961 
962 					g_ptr_array_add ( tab, tmp_str );
963 					g_free (str_to_free_1);
964 					g_free (str_to_free_2);
965 				}
966 			}
967 		}
968 	}
969 
970 
971 	if (g_hash_table_size (bet_future_list) > 0)
972 	{
973 		g_hash_table_iter_init ( &iter, bet_future_list );
974 		while ( g_hash_table_iter_next ( &iter, &key, &value ) )
975 		{
976 			FuturData *scheduled = ( FuturData* ) value;
977 			gchar *amount;
978 			gchar *date;
979 			gchar *limit_date;
980 
981 			/* set the real */
982 			amount = gsb_real_safe_real_to_string ( scheduled -> amount,
983 							gsb_data_account_get_currency_floating_point ( scheduled -> account_number ) );
984 
985 			/* set the dates */
986 			date = gsb_format_gdate_safe ( scheduled -> date );
987 			limit_date = gsb_format_gdate_safe ( scheduled -> limit_date );
988 
989 			tmp_str = g_markup_printf_escaped ( "\t<Bet_future Nb=\"%d\" Dt=\"%s\" Ac=\"%d\" "
990 							"Am=\"%s\" Pa=\"%d\" IsT=\"%d\" Tra=\"%d\" Ca=\"%d\" Sca=\"%d\" "
991 							"Pn=\"%d\" Fi=\"%d\" Bu=\"%d\" Sbu=\"%d\" No=\"%s\" Au=\"0\" "
992 							"Pe=\"%d\" Pei=\"%d\" Pep=\"%d\" Dtl=\"%s\" Mo=\"%d\" />\n",
993 							scheduled -> number,
994 							my_safe_null_str ( date ),
995 							scheduled -> account_number,
996 							my_safe_null_str ( amount ),
997 							scheduled -> party_number,
998 							scheduled -> is_transfert,
999 							scheduled -> account_transfert,
1000 							scheduled -> category_number,
1001 							scheduled -> sub_category_number,
1002 							scheduled -> payment_number,
1003 							scheduled -> fyear_number,
1004 							scheduled -> budgetary_number,
1005 							scheduled -> sub_budgetary_number,
1006 							my_safe_null_str ( scheduled -> notes ),
1007 							scheduled -> frequency,
1008 							scheduled -> user_interval,
1009 							scheduled -> user_entry,
1010 							my_safe_null_str ( limit_date ),
1011 							scheduled -> mother_row );
1012 
1013 			g_ptr_array_add ( tab, tmp_str );
1014 
1015 			g_free (amount);
1016 			g_free (date);
1017 			g_free (limit_date);
1018 		}
1019 	}
1020 
1021 	if (g_hash_table_size (bet_transfert_list) > 0)
1022 	{
1023 		g_hash_table_iter_init ( &iter, bet_transfert_list );
1024 		while ( g_hash_table_iter_next ( &iter, &key, &value ) )
1025 		{
1026 			TransfertData *transfert = ( TransfertData* ) value;
1027 			gchar *date_debit;
1028 			gchar *date_bascule;
1029 
1030 			/* set the dates */
1031 			date_debit = gsb_format_gdate_safe (transfert->date_debit);
1032 			date_bascule = gsb_format_gdate_safe (transfert->date_bascule);
1033 			tmp_str = g_markup_printf_escaped ("\t<Bet_transfert Nb=\"%d\" Ac=\"%d\" "
1034 											   "Ty=\"%d\" Ra=\"%d\" Rt=\"%d\" Dd=\"%d\" "
1035 											   "Dt=\"%s\" MCbd=\"%d\" Pa=\"%d\" Pn=\"%d\" Ca=\"%d\" "
1036 											   "Sca=\"%d\" Bu=\"%d\" Sbu=\"%d\" "
1037 											   "Dtb=\"%s\"  CCbd=\"%d\"CPa=\"%d\" CPn=\"%d\" CCa=\"%d\" "
1038 											   "CSca=\"%d\" CBu=\"%d\" CSbu=\"%d\" "
1039 											   "/>\n",
1040 							transfert->number,
1041 							transfert->account_number,
1042 							transfert->type,
1043 							transfert->replace_account,
1044 							transfert->replace_transaction,
1045 							transfert->direct_debit,
1046 							my_safe_null_str (date_debit),
1047 							transfert->main_choice_debit_day,
1048 							transfert->main_payee_number,
1049 							transfert->main_payment_number,
1050 							transfert->main_category_number,
1051 							transfert->main_sub_category_number,
1052 							transfert->main_budgetary_number,
1053 							transfert->main_sub_budgetary_number,
1054 							my_safe_null_str (date_bascule),
1055 							transfert->card_choice_bascule_day,
1056 							transfert->card_payee_number,
1057 							transfert->card_payment_number,
1058 							transfert->card_category_number,
1059 							transfert->card_sub_category_number,
1060 							transfert->card_budgetary_number,
1061 							transfert->card_sub_budgetary_number);
1062 
1063 			g_ptr_array_add ( tab, tmp_str );
1064 
1065 			g_free (date_debit);
1066 			g_free (date_bascule);
1067 		}
1068 	}
1069 
1070 	tmp_list = bet_data_loan_get_loan_list ();
1071 	while (tmp_list)
1072 	{
1073         gchar *date;
1074 		gchar *string_to_free1;
1075 		gchar *string_to_free2;
1076 		gchar *string_to_free3;
1077 		gchar *string_to_free4;
1078 		gchar *string_to_free5;
1079 		gchar *string_to_free6;
1080 		gchar *string_to_free7;
1081 		gint flotting_point;
1082 		LoanStruct *s_loan;
1083 
1084 		s_loan = tmp_list->data;
1085 
1086 		date = gsb_format_gdate_safe (s_loan->first_date);
1087 		flotting_point = gsb_data_account_get_currency_floating_point (s_loan->account_number);
1088 
1089 		string_to_free1 = utils_str_dtostr (s_loan->capital, flotting_point, TRUE);
1090 		string_to_free2 = utils_str_dtostr (s_loan->fees, flotting_point, TRUE);
1091 		string_to_free3 = utils_str_dtostr (s_loan->annual_rate, BET_TAUX_DIGITS, TRUE);
1092 		string_to_free4 = utils_str_dtostr (s_loan->first_capital, flotting_point, TRUE);
1093 		string_to_free5 = utils_str_dtostr (s_loan->first_interests, flotting_point, TRUE);
1094 		string_to_free6 = utils_str_dtostr (s_loan->other_echeance_amount, flotting_point, TRUE);
1095 		string_to_free7 = utils_str_dtostr (s_loan->capital_du, flotting_point, TRUE);
1096 
1097 		tmp_str = g_markup_printf_escaped ("\t<Bet_loan\n"
1098 										   "\t\tNb=\"%d\" Ac=\"%d\" Ver=\"%d\" InCol=\"%d\"\n"
1099 										   "\t\tCa=\"%s\" Duree=\"%d\" FDate=\"%s\" Fees=\"%s\" Taux=\"%s\" TyTaux=\"%d\"\n"
1100 										   "\t\tFEchDif=\"%d\" FCa=\"%s\" FIn=\"%s\" OEch=\"%s\"\n"
1101 										   "\t\tISchWL=\"%d\" AAc=\"%d\" ASch=\"%d\" AFr=\"%d\" CaDu=\"%s\" />\n",
1102 										   s_loan->number,
1103 										   s_loan->account_number,
1104 										   s_loan->version_number,
1105 										   s_loan->invers_cols_cap_ech,
1106 										   my_safe_null_str (string_to_free1),
1107 										   s_loan->duree,
1108 										   date,
1109 										   my_safe_null_str (string_to_free2),
1110 										   my_safe_null_str (string_to_free3),
1111 										   s_loan->type_taux,
1112 										   s_loan->first_is_different,
1113 										   my_safe_null_str (string_to_free4),
1114 										   my_safe_null_str (string_to_free5),
1115 										   my_safe_null_str (string_to_free6),
1116 										   s_loan->init_sch_with_loan,
1117 										   s_loan->associated_account,
1118 										   s_loan->associated_scheduled,
1119 										   s_loan->associated_frequency,
1120 										   my_safe_null_str (string_to_free7)
1121 										   );
1122 		g_ptr_array_add (tab, tmp_str);
1123 		g_free (date);
1124 		g_free (string_to_free1);
1125 		g_free (string_to_free2);
1126 		g_free (string_to_free3);
1127 		g_free (string_to_free4);
1128 		g_free (string_to_free5);
1129 		g_free (string_to_free6);
1130 		g_free (string_to_free7);
1131 
1132 		tmp_list = tmp_list->next;
1133 	}
1134     return tab;
1135 }
1136 
1137 
1138 /**
1139  * supprime de la liste bet_hist_div_list les divisions sous divisions
1140  * inexistantes dans list_div.
1141  *
1142  *
1143  * */
bet_data_synchronise_hist_div_list(GHashTable * list_div)1144 void bet_data_synchronise_hist_div_list ( GHashTable  *list_div )
1145 {
1146     GHashTableIter iter;
1147     gpointer key, value;
1148     BetHist *sh = NULL;
1149 
1150     g_hash_table_iter_init ( &iter, bet_hist_div_list );
1151     while ( g_hash_table_iter_next ( &iter, &key, &value ) )
1152     {
1153         HistDiv *shd = ( HistDiv* ) value;
1154         GHashTableIter new_iter;
1155 
1156         sh = g_hash_table_lookup ( list_div, utils_str_itoa ( shd -> div_number ) );
1157         if ( sh == NULL )
1158             bet_data_remove_div_hist ( shd -> account_nb, shd -> div_number, 0 );
1159         else
1160         {
1161             g_hash_table_iter_init ( &new_iter, shd -> sub_div_list );
1162             while ( g_hash_table_iter_next ( &new_iter, &key, &value ) )
1163             {
1164                 HistDiv *sub_shd = ( HistDiv* ) value;
1165 
1166                 if ( !g_hash_table_lookup ( sh -> list_sub_div, utils_str_itoa (
1167                  sub_shd -> div_number ) ) )
1168                 {
1169                     bet_data_remove_div_hist ( shd -> account_nb,
1170                                 shd -> div_number,
1171                                 sub_shd -> div_number );
1172                     g_hash_table_iter_init ( &new_iter, shd -> sub_div_list );
1173                 }
1174             }
1175         }
1176     }
1177 }
1178 /**
1179  *
1180  *
1181  *
1182  *
1183  * */
struct_initialise_bet_range(void)1184 BetRange *struct_initialise_bet_range ( void )
1185 {
1186 	BetRange	*sbr;
1187 
1188 	sbr = g_malloc0 ( sizeof ( BetRange ) );
1189     sbr -> first_pass = TRUE;
1190     sbr -> current_fyear = null_real;
1191     sbr -> current_balance = null_real;
1192 
1193 	return sbr;
1194 }
1195 
1196 
1197 /**
1198  *
1199  *
1200  *
1201  *
1202  * */
struct_free_bet_range(BetRange * sbr)1203 void struct_free_bet_range ( BetRange *sbr )
1204 {
1205     g_free ( sbr );
1206 }
1207 
1208 
1209 /**
1210  *
1211  *
1212  *
1213  *
1214  * */
struct_initialise_bet_historical(void)1215 BetHist *struct_initialise_bet_historical ( void )
1216 {
1217 	BetHist	*sh;
1218 
1219 	sh = g_malloc0 ( sizeof (BetHist) );
1220     sh -> sbr = struct_initialise_bet_range ( );
1221     sh -> list_sub_div = g_hash_table_new_full ( g_str_hash,
1222                         g_str_equal,
1223                         (GDestroyNotify) g_free,
1224                         (GDestroyNotify) struct_free_bet_historical );
1225 	return sh;
1226 }
1227 
1228 
1229 /**
1230  *
1231  *
1232  *
1233  *
1234  * */
struct_free_bet_historical(BetHist * sh)1235 void struct_free_bet_historical (BetHist *sh )
1236 {
1237 
1238     if ( sh -> sbr )
1239         struct_free_bet_range ( sh -> sbr );
1240     if ( sh -> list_sub_div )
1241 		g_hash_table_remove_all ( sh -> list_sub_div );
1242 	g_hash_table_unref (sh->list_sub_div);
1243 
1244     g_free ( sh );
1245 }
1246 
1247 
1248 /**
1249  *
1250  *
1251  *
1252  *
1253  * */
struct_initialise_hist_div(void)1254 HistDiv *struct_initialise_hist_div ( void )
1255 {
1256     HistDiv *shd;
1257 
1258     shd = g_malloc0 ( sizeof ( HistDiv ) );
1259     shd -> account_nb = 0;
1260     shd -> div_number = 0;
1261     shd -> div_edited = FALSE;
1262     shd -> amount = null_real;
1263     shd -> sub_div_list = g_hash_table_new_full ( g_str_hash,
1264                         g_str_equal,
1265                         (GDestroyNotify) g_free,
1266                         (GDestroyNotify) struct_free_hist_div );
1267 
1268     return shd;
1269 }
1270 
1271 
1272 /**
1273  *
1274  *
1275  *
1276  *
1277  * */
struct_free_hist_div(HistDiv * shd)1278 void struct_free_hist_div ( HistDiv *shd )
1279 {
1280     if ( shd -> sub_div_list )
1281 		g_hash_table_remove_all ( shd -> sub_div_list );
1282 	g_hash_table_unref (shd->sub_div_list);
1283 
1284     g_free ( shd );
1285 }
1286 
1287 /**
1288  *
1289  *
1290  *
1291  *
1292  * */
struct_initialise_bet_future(void)1293 FuturData *struct_initialise_bet_future ( void )
1294 {
1295     FuturData *sfd;
1296 
1297     sfd = g_malloc0 ( sizeof ( FuturData ) );
1298 
1299     sfd -> date = NULL;
1300     sfd -> amount = null_real;
1301     sfd -> notes = NULL;
1302     sfd -> limit_date = NULL;
1303 
1304     return sfd;
1305 }
1306 
1307 
1308 /**
1309  *
1310  *
1311  *
1312  *
1313  * */
struct_free_bet_future(FuturData * scheduled)1314 void struct_free_bet_future ( FuturData *scheduled )
1315 {
1316     if ( scheduled -> date )
1317         g_date_free ( scheduled -> date );
1318     if ( scheduled -> limit_date )
1319         g_date_free ( scheduled -> limit_date );
1320     if ( scheduled -> notes )
1321         g_free ( scheduled -> notes );
1322 
1323     g_free ( scheduled );
1324 }
1325 
1326 
1327 /**
1328  * add lines creates in the bet_future_list
1329  *
1330  *
1331  *
1332  * */
bet_data_future_add_lines(FuturData * scheduled)1333 gboolean bet_data_future_add_lines ( FuturData *scheduled )
1334 {
1335     gchar *key;
1336 
1337     future_number ++;
1338 
1339     if ( scheduled -> frequency == 0 )
1340     {
1341         key = bet_data_get_key ( scheduled -> account_number, future_number );
1342 
1343         scheduled -> number = future_number;
1344         g_hash_table_insert ( bet_future_list, key, scheduled );
1345     }
1346     else
1347     {
1348         GDate *date;
1349         GDate *date_max;
1350         gint mother_row;
1351         FuturData *new_sch = NULL;
1352 
1353         mother_row = future_number;
1354 
1355         date_max = bet_data_array_get_date_max ( scheduled -> account_number );
1356 
1357         /* we don't change the initial date */
1358         date = gsb_date_copy ( scheduled -> date );
1359         while (TRUE)
1360         {
1361             key = bet_data_get_key ( scheduled -> account_number, future_number );
1362 
1363             if ( mother_row == future_number )
1364 			{
1365 				if (new_sch)
1366 					struct_free_bet_future (new_sch);
1367                 new_sch = scheduled;
1368 			}
1369             else
1370 			{
1371 				if (new_sch)
1372 					new_sch -> mother_row = mother_row;
1373 				else
1374 				{
1375 					g_date_free (date_max);
1376 					return FALSE;
1377 				}
1378 			}
1379 
1380             new_sch -> number = future_number;
1381             g_hash_table_insert ( bet_future_list, key, new_sch );
1382 
1383             date = bet_data_futur_get_next_date ( new_sch, date, date_max );
1384             if (date == NULL || !g_date_valid (date))
1385                 break;
1386 
1387 			future_number ++;
1388             new_sch = bet_data_future_copy_struct ( scheduled );
1389 			new_sch -> date = date;
1390         }
1391         g_date_free ( date_max );
1392     }
1393 
1394     gsb_file_set_modified ( TRUE );
1395 
1396     return TRUE;
1397 }
1398 
1399 
1400 /**
1401  * add lines from file
1402  *
1403  *
1404  *
1405  * */
bet_data_future_set_lines_from_file(FuturData * scheduled)1406 gboolean bet_data_future_set_lines_from_file ( FuturData *scheduled )
1407 {
1408     gchar *key;
1409 
1410     key = bet_data_get_key ( scheduled -> account_number, scheduled -> number );
1411 
1412     bet_data_future_set_max_number ( scheduled -> number );
1413 
1414     g_hash_table_insert ( bet_future_list, key, scheduled );
1415 
1416     return TRUE;
1417 }
1418 
1419 
1420 /**
1421  *
1422  *
1423  *
1424  *
1425  * */
bet_data_future_set_max_number(gint number)1426 void bet_data_future_set_max_number ( gint number )
1427 {
1428     if ( number >  future_number )
1429         future_number = number;
1430 }
1431 
1432 
1433 /**
1434  *
1435  *
1436  *
1437  *
1438  * */
bet_data_future_get_list(void)1439 GHashTable *bet_data_future_get_list ( void )
1440 {
1441     return bet_future_list;
1442 }
1443 
1444 
1445 /**
1446  * find and return the next date after the given date for the given futur data
1447  *
1448  *
1449  * \param FuturData
1450  * \param date the current date, we want the next one after that one
1451  *
1452  * \return a newly allocated date, the next date or NULL if over the limit
1453  * */
bet_data_futur_get_next_date(FuturData * scheduled,const GDate * date,const GDate * date_max)1454 GDate *bet_data_futur_get_next_date ( FuturData *scheduled,
1455                         const GDate *date,
1456                         const GDate *date_max )
1457 {
1458     GDate *return_date;
1459 
1460     if ( !scheduled
1461 	 ||
1462 	 !scheduled -> frequency
1463 	 ||
1464 	 !date
1465 	 ||
1466 	 !g_date_valid ( date ) )
1467 	return NULL;
1468 
1469     /* we don't change the initial date */
1470     return_date = gsb_date_copy (date);
1471 
1472     switch ( scheduled -> frequency )
1473     {
1474 	case SCHEDULER_PERIODICITY_ONCE_VIEW:
1475 	    return NULL;
1476 	    break;
1477 
1478 	case SCHEDULER_PERIODICITY_WEEK_VIEW:
1479 	    g_date_add_days ( return_date, 7 );
1480 	    break;
1481 
1482 	case SCHEDULER_PERIODICITY_MONTH_VIEW:
1483 	    g_date_add_months ( return_date, 1 );
1484 	    break;
1485 
1486 	case SCHEDULER_PERIODICITY_TWO_MONTHS_VIEW:
1487 	    g_date_add_months ( return_date, 2 );
1488 	    break;
1489 
1490 	case SCHEDULER_PERIODICITY_TRIMESTER_VIEW:
1491 	    g_date_add_months ( return_date, 3 );
1492 	    break;
1493 
1494 	case SCHEDULER_PERIODICITY_YEAR_VIEW:
1495 	    g_date_add_years ( return_date, 1 );
1496 	    break;
1497 
1498 	case SCHEDULER_PERIODICITY_CUSTOM_VIEW:
1499 	    if ( scheduled -> user_entry <= 0 )
1500 	    {
1501             g_date_free (return_date);
1502             return NULL;
1503 	    }
1504 
1505 	    switch ( scheduled -> user_interval )
1506 	    {
1507 		case PERIODICITY_DAYS:
1508 		    g_date_add_days ( return_date, scheduled -> user_entry);
1509 		    break;
1510 
1511 		case PERIODICITY_WEEKS:
1512 		    g_date_add_days ( return_date, scheduled -> user_entry * 7 );
1513 		    break;
1514 
1515 		case PERIODICITY_MONTHS:
1516 		    g_date_add_months ( return_date, scheduled -> user_entry );
1517 		    break;
1518 
1519 		case PERIODICITY_YEARS:
1520 		    g_date_add_years ( return_date, scheduled -> user_entry );
1521 		    break;
1522 	    }
1523 	    break;
1524     }
1525 
1526     if ( scheduled -> limit_date )
1527     {
1528 
1529 	    if ( g_date_compare ( return_date, scheduled -> limit_date ) > 0 )
1530         {
1531             g_date_free (return_date);
1532             return_date = NULL;
1533         }
1534     }
1535     else
1536     {
1537         if ( g_date_compare ( return_date, date_max ) > 0 )
1538         {
1539             g_date_free (return_date);
1540             return_date = NULL;
1541         }
1542     }
1543 
1544     return ( return_date );
1545 }
1546 
1547 
1548 /**
1549  *
1550  *
1551  *
1552  *
1553  * */
bet_data_future_copy_struct(FuturData * scheduled)1554 FuturData *bet_data_future_copy_struct ( FuturData *scheduled )
1555 {
1556     FuturData *new_scheduled;
1557 
1558     new_scheduled = struct_initialise_bet_future ( );
1559 
1560     if ( !new_scheduled )
1561     {
1562         dialogue_error_memory ();
1563         return NULL;
1564     }
1565 
1566     new_scheduled ->  number = scheduled -> number;
1567     new_scheduled ->  account_number = scheduled -> account_number;
1568 
1569     if ( g_date_valid ( scheduled -> date ) )
1570         new_scheduled -> date = gsb_date_copy ( scheduled -> date );
1571     else
1572         new_scheduled -> date = NULL;
1573 
1574     new_scheduled -> amount = gsb_real_new ( scheduled -> amount.mantissa,
1575                         scheduled -> amount.exponent );
1576     new_scheduled -> fyear_number = scheduled -> fyear_number;
1577     new_scheduled -> payment_number = scheduled -> payment_number;
1578 
1579     new_scheduled -> party_number = scheduled -> party_number;
1580     new_scheduled -> is_transfert = scheduled -> is_transfert;
1581     new_scheduled -> account_transfert = scheduled -> account_transfert;
1582     new_scheduled -> category_number = scheduled -> category_number;
1583     new_scheduled -> sub_category_number = scheduled -> sub_category_number;
1584     new_scheduled -> budgetary_number = scheduled -> budgetary_number;
1585     new_scheduled -> sub_budgetary_number = scheduled -> sub_budgetary_number;
1586     new_scheduled -> notes = g_strdup ( scheduled -> notes );
1587 
1588     new_scheduled -> frequency = scheduled -> frequency;
1589     new_scheduled -> user_interval = scheduled -> user_interval;
1590     new_scheduled -> user_entry = scheduled -> user_entry;
1591 
1592     if ( scheduled -> limit_date && g_date_valid ( scheduled -> limit_date ) )
1593         new_scheduled -> limit_date = gsb_date_copy ( scheduled -> limit_date );
1594     else
1595         new_scheduled -> limit_date = NULL;
1596 
1597     new_scheduled -> mother_row = scheduled -> mother_row;
1598 
1599     return new_scheduled;
1600 }
1601 /**
1602  * supprime l'occurence sélectionnée.
1603  *
1604  * \param maj TRUE force la mise à jour
1605  *
1606  * */
bet_data_future_remove_line(gint account_number,gint number,gboolean maj)1607 gboolean bet_data_future_remove_line ( gint account_number, gint number, gboolean maj )
1608 {
1609     GHashTableIter iter;
1610     gpointer key, value;
1611 
1612     g_hash_table_iter_init ( &iter, bet_future_list );
1613     while (g_hash_table_iter_next ( &iter, &key, &value ) )
1614     {
1615         FuturData *scheduled = ( FuturData *) value;
1616 
1617         if ( number != scheduled -> number )
1618             continue;
1619 
1620         if ( account_number != scheduled -> account_number )
1621         {
1622             if ( scheduled -> is_transfert == 0
1623              || ( scheduled -> is_transfert && account_number != scheduled -> account_transfert ) )
1624                 continue;
1625         }
1626 
1627         g_hash_table_iter_remove ( &iter );
1628 
1629         break;
1630     }
1631 
1632     gsb_file_set_modified ( TRUE );
1633 
1634     if ( maj )
1635     {
1636         gsb_data_account_set_bet_maj ( account_number, BET_MAJ_ESTIMATE );
1637         bet_data_update_bet_module ( account_number, GSB_ESTIMATE_PAGE );
1638     }
1639 
1640     return FALSE;
1641 }
1642 
1643 
1644 /**
1645  * supprime touts les occurrences de la ligne sélectionnée
1646  *
1647  *
1648  *
1649  * */
bet_data_future_remove_lines(gint account_number,gint number,gint mother_row)1650 gboolean bet_data_future_remove_lines ( gint account_number,
1651                         gint number,
1652                         gint mother_row )
1653 {
1654     GHashTableIter iter;
1655     gpointer key, value;
1656 
1657     g_hash_table_iter_init ( &iter, bet_future_list );
1658     while (g_hash_table_iter_next ( &iter, &key, &value ) )
1659     {
1660         FuturData *scheduled = ( FuturData *) value;
1661 
1662         if ( account_number != scheduled -> account_number )
1663         {
1664             if ( scheduled -> is_transfert == 0
1665              || ( scheduled -> is_transfert && account_number != scheduled -> account_transfert ) )
1666                 continue;
1667         }
1668 
1669         if ( number == scheduled -> number )
1670             g_hash_table_iter_remove ( &iter );
1671         else if ( number == scheduled -> mother_row )
1672             g_hash_table_iter_remove ( &iter );
1673         else if ( mother_row > 0 && mother_row == scheduled -> number )
1674             g_hash_table_iter_remove ( &iter );
1675         else if ( mother_row > 0 && mother_row == scheduled -> mother_row )
1676             g_hash_table_iter_remove ( &iter );
1677     }
1678 
1679     gsb_file_set_modified ( TRUE );
1680 
1681     return FALSE;
1682 }
1683 
1684 
1685 /**
1686  * retourne la date max d'interrogation pour les prévisions
1687  *
1688  *
1689  *
1690  * */
bet_data_array_get_date_max(gint account_number)1691 GDate *bet_data_array_get_date_max ( gint account_number )
1692 {
1693     GDate *date_min;
1694     GDate *date_max;
1695     GDate *date_tmp;
1696 
1697     date_min = gsb_data_account_get_bet_start_date ( account_number );
1698 
1699     date_max = gsb_date_copy ( date_min );
1700     date_tmp = date_max;
1701 
1702     if ( g_date_get_day ( date_min ) == 1 )
1703     {
1704         g_date_add_months (date_max, gsb_data_account_get_bet_months ( account_number ) - 1 );
1705         date_max = gsb_date_get_last_day_of_month ( date_tmp );
1706         g_date_free ( date_tmp );
1707     }
1708     else
1709     {
1710         g_date_add_months (date_max, gsb_data_account_get_bet_months ( account_number ) );
1711         g_date_subtract_days ( date_max, 1 );
1712     }
1713 
1714     g_date_free ( date_min );
1715 
1716     return date_max;
1717 }
1718 
1719 
1720 /**
1721  * modify futures data lines
1722  *
1723  *
1724  *
1725  * */
bet_data_future_modify_lines(FuturData * scheduled)1726 gboolean bet_data_future_modify_lines ( FuturData *scheduled )
1727 {
1728     gchar *key;
1729 
1730     key = bet_data_get_key ( scheduled -> account_number, scheduled -> number );
1731 
1732     g_hash_table_replace ( bet_future_list, key, scheduled );
1733 
1734     gsb_file_set_modified ( TRUE );
1735 
1736     return TRUE;
1737 }
1738 
1739 
1740 /**
1741  *
1742  *
1743  *
1744  *
1745  * */
bet_data_future_get_struct(gint account_number,gint number)1746 FuturData *bet_data_future_get_struct ( gint account_number, gint number )
1747 {
1748     gchar *key;
1749     FuturData *scheduled;
1750 
1751     key = bet_data_get_key ( account_number, number );
1752 
1753     if ( ( scheduled = g_hash_table_lookup ( bet_future_list, key ) ) )
1754         return scheduled;
1755     else
1756         return NULL;
1757 }
1758 
1759 
1760 /**
1761  *
1762  *
1763  *
1764  *
1765  * */
struct_initialise_bet_transfert(void)1766 TransfertData *struct_initialise_bet_transfert ( void )
1767 {
1768     TransfertData *transfert;
1769 
1770     transfert =  g_malloc0 ( sizeof ( TransfertData ) );
1771 
1772     transfert->date_debit = NULL;
1773     transfert->date_bascule = NULL;
1774 
1775     return transfert;
1776 }
1777 
1778 
1779 /**
1780  *
1781  *
1782  *
1783  *
1784  * */
struct_free_bet_transfert(TransfertData * transfert)1785 void struct_free_bet_transfert ( TransfertData *transfert )
1786 {
1787     if ( transfert->date_debit )
1788         g_date_free ( transfert->date_debit );
1789     if ( transfert->date_bascule )
1790         g_date_free ( transfert->date_bascule );
1791 
1792     g_free ( transfert );
1793 }
1794 
1795 
1796 /**
1797  *
1798  *
1799  *
1800  *
1801  * */
bet_data_transfert_get_list(void)1802 GHashTable *bet_data_transfert_get_list ( void )
1803 {
1804     return bet_transfert_list;
1805 }
1806 
1807 
1808 /**
1809  * add line in the bet_transfer_list
1810  *
1811  *
1812  *
1813  * */
bet_data_transfert_add_line(TransfertData * transfert)1814 gboolean bet_data_transfert_add_line ( TransfertData *transfert )
1815 {
1816     gchar *key;
1817 
1818     transfert_number ++;
1819 
1820     key = bet_data_get_key ( transfert -> account_number, transfert_number );
1821 
1822     transfert -> number = transfert_number;
1823     g_hash_table_insert ( bet_transfert_list, key, transfert );
1824 
1825     gsb_file_set_modified ( TRUE );
1826 
1827     return TRUE;
1828 }
1829 
1830 
1831 /**
1832  *
1833  *
1834  *
1835  *
1836  * */
bet_data_transfert_remove_line(gint account_number,gint number)1837 gboolean bet_data_transfert_remove_line ( gint account_number, gint number )
1838 {
1839     GHashTableIter iter;
1840     gpointer key, value;
1841 
1842     g_hash_table_iter_init ( &iter, bet_transfert_list );
1843     while (g_hash_table_iter_next ( &iter, &key, &value ) )
1844     {
1845         TransfertData *transfert = ( TransfertData *) value;
1846 
1847         if ( account_number != transfert -> account_number
1848          ||
1849          number != transfert -> number)
1850             continue;
1851 
1852         g_hash_table_iter_remove ( &iter );
1853 
1854         break;
1855     }
1856 
1857     gsb_file_set_modified ( TRUE );
1858 
1859     gsb_data_account_set_bet_maj ( account_number, BET_MAJ_ESTIMATE );
1860     bet_data_update_bet_module ( account_number, GSB_ESTIMATE_PAGE );
1861 
1862     return FALSE;
1863 }
1864 
1865 
1866 /**
1867  *
1868  *
1869  *
1870  *
1871  * */
bet_data_transfert_set_line_from_file(TransfertData * transfert)1872 gboolean bet_data_transfert_set_line_from_file ( TransfertData *transfert )
1873 {
1874     gchar *key;
1875 
1876     key = bet_data_get_key ( transfert -> account_number, transfert -> number );
1877 
1878     if ( transfert -> number >  transfert_number )
1879         transfert_number = transfert -> number;
1880 
1881     g_hash_table_insert ( bet_transfert_list, key, transfert );
1882 
1883     return TRUE;
1884 }
1885 
1886 
1887 /**
1888  * modify transfert line
1889  *
1890  *
1891  *
1892  * */
bet_data_transfert_modify_line(TransfertData * transfert)1893 gboolean bet_data_transfert_modify_line ( TransfertData *transfert )
1894 {
1895     gchar *key;
1896 
1897     key = bet_data_get_key ( transfert -> account_number, transfert -> number );
1898 
1899     g_hash_table_replace ( bet_transfert_list, key, transfert );
1900 
1901     gsb_file_set_modified ( TRUE );
1902 
1903     return TRUE;
1904 }
1905 
1906 
1907 /**
1908  * crée la ou les transactions de remise à zéro des comptes cartes concernés
1909  *
1910  * \param struct transfert
1911  *
1912  * \return
1913  * */
bet_data_transfert_create_reset_credit_card(TransfertData * transfert)1914 static void bet_data_transfert_create_reset_credit_card ( TransfertData *transfert )
1915 {
1916     gint transaction_number;
1917     GDate *date;
1918     GsbReal amount;
1919 
1920     date = gsb_date_copy ( transfert->date_bascule );
1921     /* on enlève 1 jour pour la date de l'opération de remise à 0 du compte */
1922     g_date_subtract_days ( date, 1 );
1923 
1924     /* replace_account is an account */
1925     if ( transfert -> type == 0 )
1926     {
1927         amount = gsb_data_account_get_balance_at_date ( transfert->replace_account, date );
1928         transaction_number = gsb_data_transaction_new_transaction ( transfert->replace_account );
1929         gsb_data_transaction_set_date ( transaction_number, date );
1930         gsb_data_transaction_set_amount ( transaction_number, gsb_real_opposite ( amount ) );
1931 
1932         /* set the currency */
1933         gsb_data_transaction_set_currency_number ( transaction_number,
1934                         gsb_data_account_get_currency ( transfert->replace_account ) );
1935 
1936         /* set the payement mode */
1937         if ( amount.mantissa < 0 )
1938             gsb_data_transaction_set_method_of_payment_number ( transaction_number,
1939                         gsb_data_account_get_default_debit ( transfert->replace_account ) );
1940         else
1941             gsb_data_transaction_set_method_of_payment_number ( transaction_number,
1942                         gsb_data_account_get_default_credit ( transfert->replace_account ) );
1943 
1944         /* set the payee */
1945         gsb_data_transaction_set_party_number ( transaction_number, transfert->main_payee_number );
1946 
1947         /* set the category sub_category */
1948         if ( transfert->card_category_number )
1949         {
1950             gsb_data_transaction_set_category_number ( transaction_number, transfert->card_category_number );
1951             if ( transfert->card_sub_category_number )
1952                 gsb_data_transaction_set_sub_category_number ( transaction_number,
1953                         transfert->card_sub_category_number );
1954         }
1955 
1956         /* set the IB sub_IB */
1957         if ( transfert->card_budgetary_number )
1958         {
1959             gsb_data_transaction_set_budgetary_number ( transaction_number, transfert->card_budgetary_number );
1960             if ( transfert->card_sub_category_number )
1961                 gsb_data_transaction_set_sub_budgetary_number ( transaction_number,
1962                         transfert->card_sub_budgetary_number );
1963         }
1964 
1965         /* append the transaction in list */
1966         gsb_transactions_list_append_new_transaction ( transaction_number, TRUE );
1967     }
1968     else
1969     {
1970         GPtrArray *balances;
1971         gchar **tab;
1972         gint i;
1973 
1974         tab = g_strsplit ( gsb_data_partial_balance_get_liste_cptes ( transfert->replace_account ), ";", 0 );
1975 
1976         /* on calcule la balance de tous les comptes du pseudo compte */
1977         balances = gsb_data_partial_balance_calculate_balances_at_date ( transfert->replace_account, date );
1978 
1979         for ( i = 0; tab[i]; i++ )
1980         {
1981             gint account_number;
1982             GsbReal *balance;
1983 
1984             account_number = utils_str_atoi ( tab[i] );
1985             balance = (GsbReal *) g_ptr_array_index ( balances, i );
1986             amount.mantissa = balance->mantissa;
1987             amount.exponent = balance->exponent;
1988 
1989             transaction_number = gsb_data_transaction_new_transaction ( account_number );
1990             gsb_data_transaction_set_date ( transaction_number, date );
1991             gsb_data_transaction_set_amount ( transaction_number, gsb_real_opposite ( amount ) );
1992 
1993             /* set the currency */
1994             gsb_data_transaction_set_currency_number ( transaction_number,
1995                         gsb_data_account_get_currency ( account_number ) );
1996 
1997             /* set the payement mode */
1998             if ( amount.mantissa < 0 )
1999                 gsb_data_transaction_set_method_of_payment_number ( transaction_number,
2000                         gsb_data_account_get_default_debit ( account_number ) );
2001             else
2002                 gsb_data_transaction_set_method_of_payment_number ( transaction_number,
2003                         gsb_data_account_get_default_credit ( account_number ) );
2004 
2005             /* set the payee */
2006             gsb_data_transaction_set_party_number ( transaction_number, transfert->main_payee_number );
2007 
2008             /* set the category sub_category */
2009             if ( transfert->card_category_number )
2010             {
2011                 gsb_data_transaction_set_category_number ( transaction_number, transfert->card_category_number );
2012                 if ( transfert->card_sub_category_number )
2013                     gsb_data_transaction_set_sub_category_number ( transaction_number,
2014                         transfert->card_sub_category_number );
2015             }
2016 
2017             /* set the IB sub_IB */
2018             if ( transfert->card_budgetary_number )
2019             {
2020                 gsb_data_transaction_set_budgetary_number ( transaction_number, transfert->card_budgetary_number );
2021                 if ( transfert->card_sub_category_number )
2022                     gsb_data_transaction_set_sub_budgetary_number ( transaction_number,
2023                         transfert->card_sub_budgetary_number );
2024             }
2025 
2026             /* append the transaction in list */
2027             gsb_transactions_list_append_new_transaction ( transaction_number, TRUE );
2028         }
2029         g_strfreev ( tab );
2030         g_ptr_array_free ( balances, TRUE );
2031     }
2032     g_date_free ( date );
2033 }
2034 
2035 
2036 /**
2037  * update la date de la ligne transfert lorsque la date de bascule est dépassée
2038  *
2039  * \param struct transfert contenant les données
2040  *
2041  * \return
2042  * */
bet_data_transfert_update_date_if_necessary(TransfertData * transfert,GDate * date_bascule,gboolean force)2043 void bet_data_transfert_update_date_if_necessary (TransfertData *transfert,
2044 												  GDate *date_bascule,
2045 												  gboolean force)
2046 {
2047     GDate *date_jour;
2048     GDate *tmp_date;
2049 
2050     if ( transfert->date_bascule == NULL )
2051         return;
2052 
2053     date_jour = gdate_today ( );
2054 
2055     if ( g_date_compare ( date_jour, date_bascule ) > 0 || force)
2056     {
2057         gchar *msg;
2058         const gchar *tmp_str;
2059 
2060         if ( transfert -> type == 0 )
2061             tmp_str = gsb_data_account_get_name ( transfert->replace_account );
2062         else
2063             tmp_str = gsb_data_partial_balance_get_name ( transfert->replace_account );
2064 
2065         msg = g_strdup_printf (
2066                         _("Warning: the start date of the period of deferred debit card account (%s) "
2067                           "is reached or exceeded. All operations of this card account must be entered "
2068                           "or they will not be taken into account in the period.\n\n"
2069                           "If you have entered all transactions, confirm with \"Yes\".\n"
2070                           "If you have yet to enter into transactions on behalf deferred debit card finish "
2071                           "with \"No\" and update the account before you start."),
2072                         tmp_str );
2073         if (!dialogue_yes_no ( msg, _("Confirmation of the change of period"), GTK_RESPONSE_CANCEL ))
2074         {
2075             g_free ( msg );
2076             return;
2077         }
2078             g_free ( msg );
2079 
2080         /* on crée la transaction dans le compte principal */
2081         if ( transfert->direct_debit )
2082             bet_array_create_transaction_from_transfert (transfert);
2083 
2084         /* on remet à zéro les comptes cartes */
2085         bet_data_transfert_create_reset_credit_card ( transfert );
2086 
2087         /* on incrémente la date de prélèvement */
2088         tmp_date = gsb_date_copy ( transfert->date_debit);
2089 
2090         g_date_free ( transfert->date_debit);
2091         g_date_add_months ( tmp_date, 1 );
2092 
2093         if ( transfert->main_choice_debit_day )
2094         {
2095             transfert->date_debit = gsb_date_get_last_banking_day_of_month ( tmp_date );
2096             g_date_free ( tmp_date );
2097         }
2098         else
2099         {
2100             transfert->date_debit = tmp_date;
2101         }
2102 
2103         /* on incrémente la date de bascule */
2104         tmp_date = gsb_date_copy ( transfert->date_bascule );
2105 
2106         g_date_free ( transfert->date_bascule );
2107         g_date_add_months ( tmp_date, 1 );
2108         transfert->date_bascule = tmp_date;
2109 
2110         gsb_data_account_set_bet_maj ( transfert->account_number, BET_MAJ_ESTIMATE );
2111         gsb_file_set_modified ( TRUE );
2112     }
2113 
2114     g_date_free ( date_jour );
2115 }
2116 
2117 /**
2118  * supprime toutes les données du module pour le compte passé en paramètre.
2119  *
2120  *
2121  *
2122  * */
bet_data_remove_all_bet_data(gint account_number)2123 gboolean bet_data_remove_all_bet_data ( gint account_number )
2124 {
2125     GHashTable *tmp_list;
2126     GHashTableIter iter;
2127     gpointer key, value;
2128 
2129     tmp_list = bet_hist_div_list;
2130 
2131     g_hash_table_iter_init ( &iter, tmp_list );
2132     while ( g_hash_table_iter_next ( &iter, &key, &value ) )
2133     {
2134         HistDiv *shd = ( HistDiv *) value;
2135 
2136         if ( account_number != shd -> account_nb )
2137             continue;
2138 
2139         if ( g_hash_table_size ( shd -> sub_div_list ) == 0 )
2140         {
2141             g_hash_table_iter_remove ( &iter );
2142             g_hash_table_iter_init ( &iter, tmp_list );
2143         }
2144         else
2145         {
2146             GHashTableIter new_iter;
2147 
2148             g_hash_table_iter_init ( &new_iter, shd -> sub_div_list );
2149             while ( g_hash_table_iter_next ( &new_iter, &key, &value ) )
2150             {
2151                 g_hash_table_iter_remove ( &new_iter );
2152                 g_hash_table_iter_init ( &new_iter, shd -> sub_div_list );
2153 
2154                 if ( g_hash_table_size ( shd -> sub_div_list ) == 0 )
2155                     break;
2156             }
2157         }
2158 
2159         if ( g_hash_table_size ( tmp_list ) == 0 )
2160             break;
2161     }
2162 
2163     tmp_list = bet_future_list;
2164 
2165     g_hash_table_iter_init ( &iter, tmp_list );
2166     while ( g_hash_table_iter_next ( &iter, &key, &value ) )
2167     {
2168         FuturData *scheduled = ( FuturData *) value;
2169 
2170         if ( account_number != scheduled -> account_number )
2171             continue;
2172 
2173         bet_data_future_remove_lines ( account_number, scheduled -> number,
2174                         scheduled -> mother_row );
2175         g_hash_table_iter_init ( &iter, tmp_list );
2176 
2177         if ( g_hash_table_size ( tmp_list ) == 0 )
2178             break;
2179     }
2180 
2181      tmp_list = bet_transfert_list;
2182 
2183     g_hash_table_iter_init ( &iter, tmp_list );
2184     while ( g_hash_table_iter_next ( &iter, &key, &value ) )
2185     {
2186         TransfertData *transfert = ( TransfertData *) value;
2187 
2188         if ( account_number != transfert -> account_number )
2189             continue;
2190 
2191         g_hash_table_iter_remove ( &iter );
2192         g_hash_table_iter_init ( &iter, tmp_list );
2193 
2194         if ( g_hash_table_size ( tmp_list ) == 0 )
2195             return TRUE;
2196     }
2197 
2198 	bet_data_loan_struct_loan_free_by_account (account_number);
2199     return TRUE;
2200 }
2201 
2202 
2203 /**
2204  * retourne la clef de recherche de la division passée en paramètre.
2205  *
2206  *
2207  *
2208  * */
bet_data_get_key(gint account_number,gint div_number)2209 gchar *bet_data_get_key ( gint account_number, gint div_number )
2210 {
2211     gchar *key;
2212     gchar *div_number_str, *account_number_str; /* only to avoid memory leaks */
2213 
2214     div_number_str = utils_str_itoa ( div_number );
2215 
2216     if ( account_number == 0 )
2217         key = g_strconcat ("0:", div_number_str, NULL );
2218     else
2219     {
2220         account_number_str = utils_str_itoa ( account_number );
2221         key = g_strconcat ( account_number_str, ":", div_number_str, NULL );
2222 
2223         g_free ( account_number_str );
2224     }
2225 
2226     g_free ( div_number_str );
2227 
2228     return key;
2229 }
2230 
2231 
2232 /**
2233  *
2234  *
2235  *
2236  *
2237  * */
bet_data_get_str_amount_in_account_currency(GsbReal amount,gint account_number,gint line_number,gint origin)2238 gchar *bet_data_get_str_amount_in_account_currency ( GsbReal amount,
2239                         gint account_number,
2240                         gint line_number,
2241                         gint origin )
2242 {
2243     gchar *str_amount = NULL;
2244     gint account_currency;
2245     gint floating_point;
2246 	GsbReal new_amount = {0, 0};
2247 
2248     account_currency = gsb_data_account_get_currency ( account_number );
2249     floating_point = gsb_data_account_get_currency_floating_point ( account_number );
2250 
2251     switch ( origin )
2252     {
2253         case SPP_ORIGIN_TRANSACTION :
2254             new_amount = gsb_data_transaction_get_adjusted_amount_for_currency ( line_number,
2255                                     account_currency,
2256                                     floating_point );
2257         break;
2258         case SPP_ORIGIN_SCHEDULED :
2259             new_amount = gsb_data_scheduled_get_adjusted_amount_for_currency ( line_number,
2260                                     account_currency,
2261                                     floating_point );
2262 
2263         break;
2264         case SPP_ORIGIN_ACCOUNT :
2265             if ( account_currency == line_number || amount.mantissa == 0 )
2266             {
2267                 new_amount.mantissa = amount.mantissa;
2268                 new_amount.exponent = amount.exponent;
2269             }
2270             else
2271                 new_amount = gsb_transfert_get_str_amount ( amount,
2272                                     account_currency,
2273                                     line_number,
2274                                     floating_point );
2275 
2276         break;
2277     }
2278 
2279     str_amount = utils_real_get_string ( new_amount );
2280 
2281     return str_amount;
2282 }
2283 
2284 
2285 /**
2286  * Création effective de la transaction dans le compte qui comporte le suivi de la carte
2287  * à débit différé
2288  *
2289  * \param structure transfert
2290  *
2291  * \return
2292  * */
bet_data_transfert_create_new_transaction(TransfertData * transfert)2293 void bet_data_transfert_create_new_transaction ( TransfertData *transfert )
2294 {
2295     gint transaction_number;
2296     GDate *date;
2297     GsbReal amount;
2298 
2299     date = gsb_date_copy ( transfert->date_bascule );
2300     /* on enlève 1 jour pour la date de l'opération de remise à 0 du compte */
2301     g_date_subtract_days ( date, 1 );
2302 
2303     transaction_number = gsb_data_transaction_new_transaction ( transfert->account_number );
2304 
2305     /* set the date */
2306     gsb_data_transaction_set_date ( transaction_number, transfert->date_debit);
2307 
2308     /* set the amount soit celui du compte carte soit celui du solde partiel */
2309     if ( transfert -> type == 0 )
2310     {
2311         amount = gsb_data_account_get_balance_at_date ( transfert->replace_account, date );
2312     }
2313     else
2314     {
2315         amount = gsb_data_partial_balance_get_balance_at_date ( transfert -> replace_account, date );
2316     }
2317     gsb_data_transaction_set_amount ( transaction_number, amount );
2318 
2319     /* set the currency */
2320     gsb_data_transaction_set_currency_number ( transaction_number,
2321                         gsb_data_account_get_currency ( transfert->account_number ) );
2322 
2323     /* set the payement mode */
2324     gsb_data_transaction_set_method_of_payment_number ( transaction_number, transfert->main_payment_number );
2325 
2326     /* set the payee */
2327     gsb_data_transaction_set_party_number ( transaction_number, transfert->main_payee_number );
2328 
2329     /* set the category sub_category */
2330     if ( transfert->main_category_number )
2331     {
2332         gsb_data_transaction_set_category_number ( transaction_number, transfert->main_category_number );
2333         if ( transfert->main_sub_category_number )
2334             gsb_data_transaction_set_sub_category_number ( transaction_number, transfert->main_sub_category_number );
2335     }
2336 
2337     /* set the IB sub_IB */
2338     if ( transfert->main_budgetary_number )
2339     {
2340         gsb_data_transaction_set_budgetary_number ( transaction_number, transfert->main_budgetary_number );
2341         if ( transfert->main_sub_budgetary_number )
2342             gsb_data_transaction_set_sub_budgetary_number ( transaction_number, transfert->main_sub_budgetary_number );
2343     }
2344 
2345     /* append the transaction in list */
2346     gsb_transactions_list_append_new_transaction ( transaction_number, TRUE );
2347 
2348     g_date_free ( date );
2349 }
2350 
2351 
2352 /**
2353  * initialise la structure
2354  *
2355  * \param
2356  *
2357  * \return
2358  * */
struct_initialise_transaction_current_fyear(void)2359 TransactionCurrentFyear *struct_initialise_transaction_current_fyear ( void )
2360 {
2361     TransactionCurrentFyear *self;
2362 
2363     self = g_malloc0 ( sizeof ( TransactionCurrentFyear ) );
2364 
2365     self -> date = NULL;
2366     self -> amount = null_real;
2367 
2368     return self;
2369 }
2370 
2371 
2372 /**
2373  *
2374  *
2375  * \param
2376  *
2377  * \return
2378  * */
struct_free_bet_transaction_current_fyear(TransactionCurrentFyear * self)2379 void struct_free_bet_transaction_current_fyear ( TransactionCurrentFyear *self )
2380 {
2381     if ( self->date )
2382         g_date_free ( self->date );
2383 
2384     g_free ( self );
2385 }
2386 
2387 
2388 /**
2389  * Sets to 0 all the amounts selected for historical data (ou "archival")
2390  *
2391  * \param account_number
2392  *
2393  * \return
2394  * */
bet_data_hist_reset_all_amounts(gint account_number)2395 void bet_data_hist_reset_all_amounts ( gint account_number )
2396 {
2397     GHashTableIter iter;
2398     gpointer key, value;
2399 
2400     if ( g_hash_table_size ( bet_hist_div_list ) == 0 )
2401         return;
2402 
2403     g_hash_table_iter_init ( &iter, bet_hist_div_list );
2404     while ( g_hash_table_iter_next ( &iter, &key, &value ) )
2405     {
2406         HistDiv *shd = ( HistDiv* ) value;
2407 
2408         if ( g_hash_table_size ( shd -> sub_div_list ) == 0 )
2409         {
2410             if ( shd -> div_edited )
2411                 bet_data_set_div_amount ( account_number, shd -> div_number, 0, null_real );
2412         }
2413         else
2414         {
2415             GHashTableIter new_iter;
2416 
2417             g_hash_table_iter_init ( &new_iter, shd -> sub_div_list );
2418             while ( g_hash_table_iter_next ( &new_iter, &key, &value ) )
2419             {
2420                 HistDiv *sub_shd = ( HistDiv* ) value;
2421 
2422                 if ( sub_shd->div_edited )
2423                     bet_data_set_div_amount ( account_number, shd->div_number, sub_shd->div_number, null_real );
2424             }
2425         }
2426     }
2427 }
2428 
2429 
2430 /**
2431  *
2432  *
2433  * \param
2434  *
2435  * \return
2436  **/
bet_data_renum_account_number_0(gint new_account_number)2437 void bet_data_renum_account_number_0 (gint new_account_number)
2438 {
2439 	gpointer account_nb;
2440 
2441 	account_nb = GINT_TO_POINTER (new_account_number);
2442 	g_hash_table_foreach (bet_hist_div_list, bet_data_hist_set_account_number, account_nb);
2443 	g_hash_table_foreach (bet_future_list, bet_data_future_set_account_number, account_nb);
2444 	g_hash_table_foreach (bet_transfert_list, bet_data_transfert_set_account_number, account_nb);
2445 }
2446 
2447 /**
2448  *
2449  *
2450  * \param
2451  *
2452  * \return
2453  **/
bet_data_transfert_get_struct_from_number(gint number)2454 TransfertData *bet_data_transfert_get_struct_from_number (gint number)
2455 {
2456     GHashTableIter iter;
2457     gpointer key;
2458     gpointer value;
2459 	TransfertData *transfert = NULL;
2460 
2461     g_hash_table_iter_init ( &iter, bet_transfert_list);
2462     while (g_hash_table_iter_next (&iter, &key, &value))
2463     {
2464         transfert = (TransfertData *) value;
2465 
2466         if (number != transfert->number)
2467             continue;
2468         break;
2469     }
2470 
2471 	return transfert;
2472 }
2473 
2474 /**
2475  *
2476  *
2477  * \param
2478  *
2479  * \return
2480  **/
2481 /* Local Variables: */
2482 /* c-basic-offset: 4 */
2483 /* End: */
2484