1 /* ************************************************************************** */
2 /*                                                                            */
3 /*     Copyright (C) 2010-2018 Pierre Biava (grisbi@pierre.biava.name)        */
4 /*          https://www.grisbi.org/                                            */
5 /*                                                                            */
6 /*  This program is free software; you can redistribute it and/or modify      */
7 /*  it under the terms of the GNU General Public License as published by      */
8 /*  the Free Software Foundation; either version 2 of the License, or         */
9 /*  (at your option) any later version.                                       */
10 /*                                                                            */
11 /*  This program is distributed in the hope that it will be useful,           */
12 /*  but WITHOUT ANY WARRANTY; without even the implied warranty of            */
13 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             */
14 /*  GNU General Public License for more details.                              */
15 /*                                                                            */
16 /*  You should have received a copy of the GNU General Public License         */
17 /*  along with this program; if not, write to the Free Software               */
18 /*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
19 /*                                                                            */
20 /* ************************************************************************** */
21 
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 
26 #include "include.h"
27 #include <gdk/gdkkeysyms.h>
28 #include <glib/gprintf.h>
29 #include <glib/gi18n.h>
30 
31 /*START_INCLUDE*/
32 #include "bet_finance_ui.h"
33 #include "dialog.h"
34 #include "export_csv.h"
35 #include "grisbi_app.h"
36 #include "gsb_automem.h"
37 #include "gsb_combo_box.h"
38 #include "gsb_currency.h"
39 #include "gsb_data_account.h"
40 #include "gsb_data_scheduled.h"
41 #include "gsb_dirs.h"
42 #include "gsb_file.h"
43 #include "gsb_form_widget.h"
44 #include "gsb_real.h"
45 #include "gsb_rgba.h"
46 #include "mouse.h"
47 #include "navigation.h"
48 #include "print_tree_view_list.h"
49 #include "structures.h"
50 #include "traitement_variables.h"
51 #include "utils.h"
52 #include "utils_dates.h"
53 #include "utils_files.h"
54 #include "utils_real.h"
55 #include "utils_str.h"
56 #include "erreur.h"
57 /*END_INCLUDE*/
58 
59 /*START_STATIC*/
60 /* notebook pour la simulation de crédits */
61 static GtkWidget *finance_notebook;
62 /* toolbars */
63 static GtkWidget *account_toolbar;
64 static GtkWidget *amortization_toolbar;
65 static GtkWidget *simulator_toolbar;
66 /*END_STATIC*/
67 
68 /*START_EXTERN*/
69 /*END_EXTERN*/
70 
71 #define DUREE_MIN_MOIS 		 3		/* durée mini du prêt en mois */
72 #define DUREE_MAX_MOIS 		18		/* durée maxi du prêt en mois */
73 #define DUREE_MIN_ANNEE		 1		/* durée mini du prêt en année */
74 #define DUREE_MOY_ANNEE		15		/* durée moyennedu prêt en années */
75 #define DUREE_MAX_ANNEE		30		/* durée maxi du prêt en années */
76 
77 enum BetFinanceAmortizationColumns
78 {
79     BET_AMORTIZATION_NUMBER_COLUMN,
80     BET_AMORTIZATION_DATE_COLUMN,
81     BET_AMORTIZATION_CAPITAL_DU_COLUMN,
82     BET_AMORTIZATION_INTERETS_COLUMN,
83     BET_AMORTIZATION_PRINCIPAL_COLUMN,
84     BET_AMORTIZATION_FRAIS_COLUMN,
85     BET_AMORTIZATION_ECHEANCE_COLUMN,
86     BET_AMORTIZATION_BACKGROUND_COLOR,
87     BET_AMORTIZATION_NBRE_COLUMNS
88 };
89 
90 enum BetFinanceDataColumns
91 {
92     BET_FINANCE_DURATION_COLUMN,
93     BET_FINANCE_NBRE_ECHEANCE_COLUMN,
94     BET_FINANCE_DEVISE_COLUMN,
95     BET_FINANCE_CAPITAL_COLUMN,
96     BET_FINANCE_CAPITAL_DOUBLE,
97     BET_FINANCE_TAUX_COLUMN,
98     BET_FINANCE_TAUX_PERIODIQUE_DOUBLE,
99     BET_FINANCE_HORS_FRAIS_COLUMN,
100     BET_FINANCE_HORS_FRAIS_DOUBLE,
101     BET_FINANCE_FRAIS_COLUMN,
102     BET_FINANCE_FRAIS_DOUBLE,
103     BET_FINANCE_ECHEANCE_COLUMN,
104     BET_FINANCE_ECHEANCE_DOUBLE,
105     BET_FINANCE_COUT_COLUMN,
106     BET_FINANCE_COUT_DOUBLE,
107     BET_FINANCE_BACKGROUND_COLOR,
108     BET_FINANCE_NBRE_COLUMNS
109 };
110 
111 /******************************************************************************/
112 /* Private functions                                                          */
113 /******************************************************************************/
114 /* TRAITEMENTS */
115 /**
116  *
117  *
118  * \param
119  * \param
120  * \param force la maj de s_loan->capital_du
121  *
122  * \return
123  **/
bet_finance_get_echeance_at_date(LoanStruct * s_loan,GDate * date,gboolean maj_s_loan_capital_du)124 static AmortissementStruct *bet_finance_get_echeance_at_date (LoanStruct *s_loan,
125 															  GDate *date,
126 															  gboolean maj_s_loan_capital_du)
127 {
128 	AmortissementStruct *s_amortissement = NULL;
129 
130 	devel_debug (gsb_format_gdate (date));
131 	s_amortissement = bet_data_finance_structure_amortissement_init ();
132 	if (g_date_compare (date, s_loan->first_date) == 0
133 		&& s_loan->first_is_different)
134 	{
135 			s_amortissement->echeance = s_loan->first_capital;
136 			s_amortissement->echeance += s_loan->fees + s_loan->first_interests;
137 			s_amortissement->interets = s_loan->first_interests;
138 			s_amortissement->frais = s_loan->fees;
139 			s_amortissement->principal = s_loan->first_capital;
140 	}
141 	else
142 	{
143 		gdouble taux_periodique;
144 //~ printf ("s_loan->capital_du avant = %f\n", s_loan->capital_du);
145 		taux_periodique = bet_data_finance_get_taux_periodique (s_loan->annual_rate, s_loan->type_taux);
146 		s_amortissement->echeance = bet_data_finance_get_echeance (s_loan->capital, taux_periodique, s_loan->duree);
147 		s_amortissement->echeance += s_loan->fees;
148 		s_amortissement->interets = bet_data_finance_get_interets (s_loan->capital_du, taux_periodique);
149 		s_amortissement->frais = s_loan->fees;
150 		s_amortissement->principal = bet_data_finance_get_principal (s_amortissement->echeance,
151 																	 s_amortissement->interets,
152 																	 s_amortissement->frais);
153 	}
154 	s_amortissement->capital_du = s_loan->capital_du - s_amortissement->principal;
155 //~ printf ("capital_du = %f principal = %f interêts = %f frais = %f\n",
156 		//~ s_amortissement->capital_du, s_amortissement->principal, s_amortissement->interets, s_amortissement->frais);
157 
158 	if (maj_s_loan_capital_du)
159 		s_loan->capital_du -= s_amortissement->principal;
160 //~ printf ("s_loan->capital_du après = %f\n\n", s_loan->capital_du);
161 	return s_amortissement;
162 }
163 
164 /**
165  *
166  *
167  * \param
168  * \param
169  * \param
170  *
171  * \return
172  **/
bet_finance_fill_data_ligne(GtkTreeModel * model,EcheanceStruct * s_echeance,const gchar * unit)173 static void bet_finance_fill_data_ligne (GtkTreeModel *model,
174 										 EcheanceStruct *s_echeance,
175 										 const gchar *unit)
176 {
177     GtkTreeIter iter;
178     gchar *str_duree;
179     gchar *str_capital;
180     gchar *str_taux;
181     gchar *str_frais;
182     gchar *str_echeance;
183     gchar *str_totale;
184     gchar *str_total_cost;
185     gchar *str_format;
186 	gchar *tmp_str;
187     gchar buffer[256];
188     gint nbre_char;
189 
190 	tmp_str = utils_str_itoa (s_echeance->duree);
191     str_duree = g_strconcat (tmp_str, " ", unit, " ", NULL);
192 	g_free (tmp_str);
193 
194     str_capital = utils_real_get_string_with_currency (gsb_real_double_to_real (s_echeance->capital),
195 													   s_echeance->devise,
196 													   TRUE);
197 
198 	tmp_str = utils_str_itoa (BET_TAUX_DIGITS);
199     str_format = g_strconcat ("%.", tmp_str, "f", NULL);
200 	g_free (tmp_str);
201     nbre_char = g_sprintf (buffer, str_format, s_echeance->taux);
202     str_taux =  g_strndup (buffer, nbre_char + 1);
203     g_free (str_format);
204 
205     str_frais = utils_real_get_string_with_currency (gsb_real_double_to_real (s_echeance->frais),
206 													 s_echeance->devise,
207 													 TRUE);
208 
209     str_echeance = utils_real_get_string_with_currency (gsb_real_double_to_real (s_echeance->echeance),
210 														s_echeance->devise,
211 														TRUE);
212 
213     str_totale = utils_real_get_string_with_currency (gsb_real_double_to_real (s_echeance->total_echeance),
214 													  s_echeance->devise,
215 													  TRUE);
216 
217     str_total_cost = utils_real_get_string_with_currency (gsb_real_double_to_real (s_echeance->total_cost),
218 														  s_echeance->devise,
219 														  TRUE);
220 
221     gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
222     gtk_tree_store_set (GTK_TREE_STORE (model),
223                         &iter,
224                         BET_FINANCE_DURATION_COLUMN, str_duree,
225                         BET_FINANCE_NBRE_ECHEANCE_COLUMN, s_echeance->nbre_echeances,
226                         BET_FINANCE_DEVISE_COLUMN, s_echeance->devise,
227                         BET_FINANCE_CAPITAL_COLUMN, str_capital,
228                         BET_FINANCE_CAPITAL_DOUBLE, s_echeance->capital,
229                         BET_FINANCE_TAUX_COLUMN, str_taux,
230                         BET_FINANCE_TAUX_PERIODIQUE_DOUBLE, s_echeance->taux_periodique,
231                         BET_FINANCE_HORS_FRAIS_COLUMN, str_echeance,
232                         BET_FINANCE_HORS_FRAIS_DOUBLE, s_echeance->echeance,
233                         BET_FINANCE_FRAIS_COLUMN, str_frais,
234                         BET_FINANCE_FRAIS_DOUBLE, s_echeance->frais,
235                         BET_FINANCE_ECHEANCE_COLUMN, str_totale,
236                         BET_FINANCE_ECHEANCE_DOUBLE, s_echeance->total_echeance,
237                         BET_FINANCE_COUT_COLUMN, str_total_cost,
238                         BET_FINANCE_COUT_DOUBLE, s_echeance->total_cost,
239                         - 1);
240 
241     g_free (str_duree);
242     g_free (str_capital);
243     g_free (str_taux);
244     g_free (str_frais);
245     g_free (str_echeance);
246     g_free (str_totale);
247 	g_free (str_total_cost);
248 }
249 
250 /**
251  * Affiche une ligne du tableau d'amortissement en mois
252  *
253  * \param
254  * \param
255  * \param
256  *
257  * \return
258  **/
bet_finance_calcule_show_months_tab(GtkTreeModel * model,EcheanceStruct * s_echeance,gdouble taux_frais)259 static void bet_finance_calcule_show_months_tab (GtkTreeModel *model,
260 												 EcheanceStruct *s_echeance,
261 												 gdouble taux_frais)
262 {
263     gint index;
264 
265     for (index = DUREE_MIN_MOIS; index <= DUREE_MAX_MOIS; index++)
266     {
267         s_echeance->duree = index;
268         s_echeance->nbre_echeances = index;
269         s_echeance->frais = bet_data_finance_get_frais_par_echeance (s_echeance->capital,
270 																	 taux_frais,
271 																	 s_echeance->nbre_echeances);
272 
273         s_echeance->echeance = bet_data_finance_get_echeance (s_echeance->capital,
274 															  s_echeance->taux_periodique,
275 															  s_echeance->nbre_echeances);
276 
277         s_echeance->total_echeance = s_echeance->echeance + s_echeance->frais;
278         s_echeance->total_cost = bet_data_finance_get_total_cost (s_echeance);
279 
280         bet_finance_fill_data_ligne (model, s_echeance, _("months"));
281 
282         s_echeance->duree = 0;
283         s_echeance->nbre_echeances = 0;
284         s_echeance->echeance = 0;
285     }
286 }
287 
288 /**
289  *
290  *
291  * \param
292  * \param
293  *
294  * \return
295  **/
bet_finance_fill_amortization_ligne(GtkTreeModel * model,AmortissementStruct * s_amortissement)296 static void bet_finance_fill_amortization_ligne (GtkTreeModel *model,
297 												 AmortissementStruct *s_amortissement)
298 {
299     GtkTreeIter iter;
300     gchar *str_capital_du = NULL;
301     gchar *str_interets = NULL;
302     gchar *str_principal = NULL;
303 
304     str_capital_du = utils_real_get_string_with_currency (gsb_real_double_to_real (s_amortissement->capital_du),
305 														  s_amortissement->devise,
306 														  TRUE);
307 
308     str_interets = utils_real_get_string_with_currency (gsb_real_double_to_real (s_amortissement->interets),
309 														s_amortissement-> devise,
310 														TRUE);
311 
312     str_principal = utils_real_get_string_with_currency (gsb_real_double_to_real (s_amortissement->principal),
313 														 s_amortissement-> devise,
314 														 TRUE);
315 
316     gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
317 
318     if (s_amortissement->origin == SPP_ORIGIN_FINANCE)
319     {
320         gtk_tree_store_set (GTK_TREE_STORE (model),
321 							&iter,
322 							BET_AMORTIZATION_NUMBER_COLUMN, s_amortissement->num_echeance,
323 							BET_AMORTIZATION_DATE_COLUMN, s_amortissement->str_date,
324 							BET_AMORTIZATION_CAPITAL_DU_COLUMN, str_capital_du,
325 							BET_AMORTIZATION_INTERETS_COLUMN, str_interets,
326 							BET_AMORTIZATION_PRINCIPAL_COLUMN, str_principal,
327 							BET_AMORTIZATION_FRAIS_COLUMN, s_amortissement->str_frais,
328 							BET_AMORTIZATION_ECHEANCE_COLUMN, s_amortissement->str_echeance,
329 							- 1);
330     }
331     else
332     {
333         gtk_tree_store_set (GTK_TREE_STORE (model),
334 							&iter,
335 							BET_AMORTIZATION_NUMBER_COLUMN, s_amortissement->num_echeance,
336 							BET_AMORTIZATION_CAPITAL_DU_COLUMN, str_capital_du,
337 							BET_AMORTIZATION_INTERETS_COLUMN, str_interets,
338 							BET_AMORTIZATION_PRINCIPAL_COLUMN, str_principal,
339 							BET_AMORTIZATION_FRAIS_COLUMN, s_amortissement->str_frais,
340 							BET_AMORTIZATION_ECHEANCE_COLUMN, s_amortissement->str_echeance,
341 							- 1);
342     }
343 
344     g_free (str_capital_du);
345     g_free (str_interets);
346     g_free (str_principal);
347 }
348 
349 /**
350  * remplit le tableau d'amortissement
351  *
352  * /param menu item
353  * /param row selected
354  *
355  * \return
356  **/
bet_finance_fill_amortization_array(GtkWidget * menu_item,GtkTreeSelection * tree_selection)357 static void bet_finance_fill_amortization_array (GtkWidget *menu_item,
358 												 GtkTreeSelection *tree_selection)
359 {
360     GtkWidget *page;
361     GtkWidget *label;
362     GtkWidget *tree_view;
363     GtkTreeModel *store;
364     GtkTreeModel *model;
365     GtkTreeIter iter;
366     GtkTreePath *path;
367     gchar *str_duree;
368     gchar *str_capital;
369     gchar *str_taux;
370     gint index = 0;
371     gint nbre_echeances;
372     gdouble taux_periodique;
373     AmortissementStruct *s_amortissement;
374 
375     devel_debug (NULL);
376     if (!gtk_tree_selection_get_selected (GTK_TREE_SELECTION (tree_selection), &model, &iter))
377 		return;
378 
379     gtk_notebook_next_page (GTK_NOTEBOOK (finance_notebook));
380 
381     /* initialise les données utiles */
382     s_amortissement = bet_data_finance_structure_amortissement_init ();
383     gtk_tree_model_get (model,
384                         &iter,
385                         BET_FINANCE_DURATION_COLUMN, &str_duree,
386                         BET_FINANCE_NBRE_ECHEANCE_COLUMN, &nbre_echeances,
387                         BET_FINANCE_DEVISE_COLUMN, &s_amortissement->devise,
388                         BET_FINANCE_CAPITAL_COLUMN, &str_capital,
389                         BET_FINANCE_CAPITAL_DOUBLE, &s_amortissement->capital_du,
390                         BET_FINANCE_TAUX_COLUMN, &str_taux,
391                         BET_FINANCE_TAUX_PERIODIQUE_DOUBLE, &taux_periodique,
392                         BET_FINANCE_FRAIS_COLUMN, &s_amortissement->str_frais,
393                         BET_FINANCE_FRAIS_DOUBLE, &s_amortissement->frais,
394                         BET_FINANCE_ECHEANCE_COLUMN, &s_amortissement->str_echeance,
395                         BET_FINANCE_ECHEANCE_DOUBLE, &s_amortissement->echeance,
396                         -1);
397 
398     /* met à jour le titre du tableau d'amortissement */
399     page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (finance_notebook), 1);
400     label = g_object_get_data (G_OBJECT (page), "capital");
401     gtk_label_set_label (GTK_LABEL (label), str_capital);
402     label = g_object_get_data (G_OBJECT (page), "bet_finance_taux");
403     gtk_label_set_label (GTK_LABEL (label), str_taux);
404     label = g_object_get_data (G_OBJECT (page), "duree");
405     gtk_label_set_label (GTK_LABEL (label), str_duree);
406 
407     g_free (str_duree);
408     g_free (str_capital);
409     g_free (str_taux);
410 
411     /* remplit le tableau d'amortissement */
412     tree_view = g_object_get_data (G_OBJECT (page), "tree_view");
413     store = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
414     gtk_tree_store_clear (GTK_TREE_STORE (store));
415 
416     for (index = 1; index <= nbre_echeances; index++)
417     {
418         s_amortissement->num_echeance = index;
419         s_amortissement->interets = bet_data_finance_get_interets (s_amortissement->capital_du,
420 																   taux_periodique);
421 
422         if (index == nbre_echeances)
423         {
424 			gchar *amount;
425 
426 			s_amortissement->echeance = bet_data_finance_get_last_echeance (s_amortissement->capital_du,
427 																			s_amortissement->interets,
428 																			s_amortissement->frais);
429             g_free (s_amortissement->str_echeance);
430 			amount = utils_real_get_string_with_currency (gsb_real_double_to_real (s_amortissement->echeance),
431 														  s_amortissement-> devise,
432 														  TRUE);
433             s_amortissement->str_echeance = amount;
434             s_amortissement->principal = s_amortissement->capital_du;
435         }
436         else
437             s_amortissement->principal = bet_data_finance_get_principal (s_amortissement->echeance,
438 																		 s_amortissement->interets,
439 																		 s_amortissement->frais);
440 
441         bet_finance_fill_amortization_ligne (store, s_amortissement);
442         s_amortissement->capital_du -= s_amortissement->principal;
443     }
444 
445     utils_set_tree_store_background_color (tree_view, BET_AMORTIZATION_BACKGROUND_COLOR);
446     path = gtk_tree_path_new_first ();
447     gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (tree_view), path, NULL, TRUE, 0.0, 0.0);
448     gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)), path);
449 
450     gtk_tree_path_free (path);
451     bet_data_finance_structure_amortissement_free (s_amortissement);
452 }
453 
454 /**
455  *
456  *
457  * \param
458  *
459  * \return
460  **/
bet_finance_struct_amortization_free(AmortissementStruct * s_amortissement)461 static void bet_finance_struct_amortization_free (AmortissementStruct *s_amortissement)
462 {
463     if (s_amortissement->str_date)
464         g_free (s_amortissement->str_date);
465     if (s_amortissement->str_echeance)
466         g_free (s_amortissement->str_echeance);
467     if (s_amortissement->str_frais)
468         g_free (s_amortissement->str_frais);
469 
470     g_free (s_amortissement);
471 }
472 
473 /* IHM */
474 /**
475  *
476  *
477  * \param
478  * \param
479  *
480  * \return
481  **/
bet_finance_ui_calculer_clicked(GtkButton * button,GtkWidget * widget)482 static void bet_finance_ui_calculer_clicked (GtkButton *button,
483 											 GtkWidget *widget)
484 {
485     GtkWidget *combobox;
486     GtkWidget *bouton;
487     GtkWidget *tree_view;
488     GtkTreeModel *model;
489     GtkTreePath *path;
490     gdouble taux_frais;
491     gint duree_min, duree_max;
492     gint type_taux;
493     gint index = 0;
494     EcheanceStruct *s_echeance;
495 
496     tree_view = g_object_get_data (G_OBJECT (widget), "tree_view");
497     if (!GTK_IS_TREE_VIEW (tree_view))
498         return;
499 
500     s_echeance = g_malloc0 (sizeof (EcheanceStruct));
501 
502     /* devise */
503     combobox = g_object_get_data (G_OBJECT (widget), "devise");
504     if (combobox)
505         s_echeance->devise = gsb_currency_get_currency_from_combobox (combobox);
506 
507     /* capital */
508     s_echeance->capital = bet_finance_get_number_from_string (widget, "capital");
509 
510     if (s_echeance->capital == 0)
511     {
512         gchar *tmp_str;
513 
514         tmp_str = g_strdup (_("You must enter at least one value for the capital"));
515         dialogue_error (tmp_str);
516         g_free (tmp_str);
517 		g_free (s_echeance);
518 
519 		return;
520     }
521     else if (s_echeance->capital == G_MININT64)
522 	{
523  		g_free (s_echeance);
524 
525 		return;
526 	}
527 
528     /* rate */
529     s_echeance->taux = bet_finance_get_number_from_string (widget, "taux");
530 
531     /* Duration */
532     combobox = g_object_get_data (G_OBJECT (widget), "duree");
533     if (combobox)
534         index = gsb_combo_box_get_index (combobox);
535 
536     switch (index)
537     {
538         case 0:
539             duree_min = DUREE_MIN_MOIS;
540             duree_max = DUREE_MAX_MOIS;
541             break;
542         case 1:
543             duree_min = DUREE_MIN_ANNEE;
544             duree_max = DUREE_MOY_ANNEE;
545             break;
546         case 2:
547             duree_min = DUREE_MOY_ANNEE;
548             duree_max = DUREE_MAX_ANNEE;
549             break;
550         default :
551             duree_min = DUREE_MIN_ANNEE;
552             duree_max = DUREE_MOY_ANNEE;
553             break;
554     }
555 
556     /* frais */
557     taux_frais = bet_finance_get_number_from_string (widget, "frais");
558 
559     /* type de taux */
560     bouton = g_object_get_data (G_OBJECT (widget), "type_taux");
561     type_taux = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (bouton));
562 
563     /* taux periodique */
564     s_echeance->taux_periodique = bet_data_finance_get_taux_periodique (s_echeance->taux,
565 																		type_taux);
566 
567     /* réinitialisation du model */
568     model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
569     gtk_tree_store_clear (GTK_TREE_STORE (model));
570 
571     if (index == 0)
572         bet_finance_calcule_show_months_tab (model, s_echeance, taux_frais);
573     else
574     {
575         for (index = duree_min; index <= duree_max; index++)
576         {
577             s_echeance->duree = index;
578             s_echeance->nbre_echeances = index * 12;
579             s_echeance->frais = bet_data_finance_get_frais_par_echeance (s_echeance->capital,
580 																		 taux_frais,
581 																		 s_echeance->nbre_echeances);
582 
583             s_echeance->echeance = bet_data_finance_get_echeance (s_echeance->capital,
584 																  s_echeance->taux_periodique,
585 																  s_echeance->nbre_echeances);
586 
587             s_echeance->total_echeance = s_echeance->echeance + s_echeance->frais;
588             s_echeance->total_cost = bet_data_finance_get_total_cost (s_echeance);
589 
590             if (s_echeance->duree == 1)
591                 bet_finance_fill_data_ligne (model, s_echeance, _("year"));
592             else
593                 bet_finance_fill_data_ligne (model, s_echeance, _("years"));
594 
595             s_echeance->duree = 0;
596             s_echeance->nbre_echeances = 0;
597             s_echeance->echeance = 0;
598         }
599     }
600 
601     utils_set_tree_store_background_color (tree_view, BET_FINANCE_BACKGROUND_COLOR);
602     path = gtk_tree_path_new_first ();
603     gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (tree_view), path, NULL, TRUE, 0.0, 0.0);
604     gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)), path);
605 
606     gtk_tree_path_free (path);
607     g_free (s_echeance);
608 
609     gsb_file_set_modified (TRUE);
610 }
611 
612 /**
613  *
614  *
615  * \param
616  * \param
617  *
618  * \return
619  **/
bet_finance_ui_capital_entry_changed(GtkWidget * entry,GtkWidget * page)620 static gboolean bet_finance_ui_capital_entry_changed (GtkWidget *entry,
621 													  GtkWidget *page)
622 {
623     const gchar *text;
624     gdouble capital;
625     gboolean valide;
626 
627     text = gtk_entry_get_text (GTK_ENTRY (entry));
628     capital = utils_str_strtod (text, NULL);
629 
630     if (strlen (text) == 0 || capital == 0)
631     {
632         gtk_widget_set_name (entry, "form_entry");
633 	    return FALSE;
634     }
635 
636     valide = gsb_form_widget_get_valide_amout_entry (text);
637     if (valide)
638     {
639         /* the entry is valid, make it normal */
640         gtk_widget_set_name (entry, "form_entry");
641     }
642     else
643     {
644 	    /* the entry is not valid, make it red */
645         gtk_widget_set_name (entry, "form_entry_error");
646     }
647 
648     return FALSE;
649 }
650 
651 /**
652  * called when press a key on an element of the form
653  *
654  * \param widget which receive the signal
655  * \param ev
656  * \param page
657  *
658  * \return FALSE
659  **/
bet_finance_ui_capital_entry_key_press_event(GtkWidget * widget,GdkEventKey * ev,GtkWidget * page)660 static gboolean bet_finance_ui_capital_entry_key_press_event (GtkWidget *widget,
661 															  GdkEventKey *ev,
662 															  GtkWidget *page)
663 {
664     gchar *str_capital;
665 
666     switch (ev->keyval)
667     {
668         case GDK_KEY_1:
669         case GDK_KEY_2:
670         case GDK_KEY_3:
671         case GDK_KEY_4:
672         case GDK_KEY_5:
673         case GDK_KEY_6:
674         case GDK_KEY_7:
675         case GDK_KEY_8:
676         case GDK_KEY_9:
677         case GDK_KEY_0:
678             break;
679 
680         case GDK_KEY_Escape :
681             str_capital = utils_real_get_string_with_currency (gsb_real_double_to_real (etat.bet_capital),
682 															   etat.bet_currency,
683 															   FALSE);
684             gtk_entry_set_text (GTK_ENTRY (widget), str_capital);
685             gtk_editable_set_position (GTK_EDITABLE (widget), -1);
686             g_free (str_capital);
687             return TRUE;
688             break;
689 
690         case GDK_KEY_ISO_Left_Tab:
691             etat.bet_capital = bet_finance_get_number_from_string (page, "capital");
692             bet_finance_ui_calculer_clicked (NULL, page);
693             return TRUE;
694             break;
695 
696         case GDK_KEY_Tab :
697             etat.bet_capital = bet_finance_get_number_from_string (page, "capital");
698             bet_finance_ui_calculer_clicked (NULL, page);
699             return TRUE;
700             break;
701 
702         case GDK_KEY_KP_Enter :
703         case GDK_KEY_Return :
704             etat.bet_capital = bet_finance_get_number_from_string (page, "capital");
705             bet_finance_ui_calculer_clicked (NULL, page);
706             return TRUE;
707             break;
708     }
709 
710     return FALSE;
711 }
712 
713 /**
714  *
715  *
716  * \param
717  * \param
718  *
719  * \return
720  **/
bet_finance_ui_switch_amortization_initial_date(GtkWidget * widget,GtkWidget * tree_view)721 static void bet_finance_ui_switch_amortization_initial_date (GtkWidget *widget,
722 															 GtkWidget *tree_view)
723 {
724     GtkWidget *tmp_button;
725     gint account_number;
726     gboolean amortization_initial_date;
727 	GrisbiAppConf *a_conf;
728 
729 	devel_debug (NULL);
730 	a_conf = (GrisbiAppConf *) grisbi_app_get_a_conf ();
731     amortization_initial_date = GPOINTER_TO_INT (g_object_get_data ( G_OBJECT (tree_view),
732 																	"amortization_initial_date"));
733     amortization_initial_date = !amortization_initial_date;
734 
735     g_object_set_data (G_OBJECT (tree_view),
736 					   "amortization_initial_date",
737 					   GINT_TO_POINTER (amortization_initial_date));
738 
739 	if (GTK_IS_BUTTON (widget))
740 		tmp_button = widget;
741 	else
742 		tmp_button = g_object_get_data (G_OBJECT (tree_view), "amortization_initial_date_button");
743 
744     if (a_conf->display_toolbar != GSB_BUTTON_ICON)
745     {
746 		if (amortization_initial_date)
747 			gtk_tool_button_set_label (GTK_TOOL_BUTTON (tmp_button), _("At today"));
748 		else
749 			gtk_tool_button_set_label (GTK_TOOL_BUTTON (tmp_button), _("Start date"));
750     }
751 
752 	if (amortization_initial_date)
753 		gtk_widget_set_tooltip_text (GTK_WIDGET (tmp_button), _("Show amortization schedule to date"));
754 	else
755 		gtk_widget_set_tooltip_text (GTK_WIDGET (tmp_button), _("Show amortization schedule from the beginning"));
756 
757     account_number = gsb_gui_navigation_get_current_account ();
758     bet_finance_update_amortization_tab (account_number);
759 }
760 
761 /**
762  *
763  *
764  * \param
765  * \param
766  *
767  * \return
768  **/
bet_finance_ui_export_tab(GtkWidget * menu_item,GtkTreeView * tree_view)769 static void bet_finance_ui_export_tab (GtkWidget *menu_item,
770 									   GtkTreeView *tree_view)
771 {
772     GtkWidget *dialog;
773     gint resultat;
774     gchar *filename;
775     gchar *tmp_last_directory;
776 
777     dialog = gtk_file_chooser_dialog_new (_("Export the array"),
778 										  GTK_WINDOW (grisbi_app_get_active_window (NULL)),
779 										  GTK_FILE_CHOOSER_ACTION_SAVE,
780 										  "gtk-cancel", GTK_RESPONSE_CANCEL,
781 										  "gtk-save", GTK_RESPONSE_OK,
782 										  NULL);
783 
784     gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog),  _("credit.csv"));
785     gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), gsb_file_get_last_path ());
786     gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
787     gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ON_PARENT);
788 
789     resultat = gtk_dialog_run (GTK_DIALOG (dialog));
790 
791     switch (resultat)
792     {
793 		case GTK_RESPONSE_OK :
794 			filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
795 			tmp_last_directory = utils_files_selection_get_last_directory (GTK_FILE_CHOOSER (dialog), TRUE);
796 			gsb_file_update_last_path (tmp_last_directory);
797 			g_free (tmp_last_directory);
798 			gtk_widget_destroy (GTK_WIDGET (dialog));
799 
800 			/* vérification que c'est possible est faite par la boite de dialogue */
801 			if (!gsb_csv_export_tree_view_list (filename, tree_view))
802 			{
803 				dialogue_error (_("Cannot save file."));
804 				return;
805 			}
806 
807 			break;
808 
809 		default :
810 			gtk_widget_destroy (GTK_WIDGET (dialog));
811 			return;
812     }
813 }
814 
815 /**
816  * Pop up a menu with several actions to apply to data_list.
817  *
818  * \param tree_view
819  *
820  * \return
821  **/
bet_finance_ui_data_list_context_menu(GtkWidget * tree_view,gint page_num)822 static void bet_finance_ui_data_list_context_menu (GtkWidget *tree_view,
823 												   gint page_num)
824 {
825     GtkWidget *menu;
826     GtkWidget *menu_item;
827     GtkTreeModel *model;
828     GtkTreeSelection *tree_selection;
829     GtkTreeIter iter;
830     gint origin;
831 
832     tree_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
833 
834     if (!gtk_tree_selection_get_selected (GTK_TREE_SELECTION (tree_selection), &model, &iter))
835 		return;
836 
837     menu = gtk_menu_new ();
838 
839 	origin = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tree_view), "origin"));
840     if (origin == SPP_ORIGIN_SIMULATOR)
841     {
842         if (page_num == 0)
843         {
844             menu_item = utils_menu_item_new_from_image_label ("gsb-ac-liability-16.png",
845 															  _("View amortization table"));
846             g_signal_connect (G_OBJECT (menu_item),
847 							  "activate",
848 							  G_CALLBACK (bet_finance_fill_amortization_array),
849 							  tree_selection);
850         }
851         else
852         {
853             menu_item = utils_menu_item_new_from_image_label ("gsb-ac-liability-16.png",
854 															  _("View credits simulator"));
855             g_signal_connect (G_OBJECT (menu_item),
856 							  "activate",
857 							  G_CALLBACK (bet_finance_ui_switch_simulator_page),
858 							  NULL);
859         }
860 		gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
861 
862 		/* Separator */
863 		gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new());
864 
865     }
866     else if (origin == SPP_ORIGIN_FINANCE)
867     {
868         gboolean amortization_initial_date;
869 
870         amortization_initial_date = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tree_view),
871 																		"amortization_initial_date"));
872 
873         if (amortization_initial_date)
874             menu_item = utils_menu_item_new_from_image_label ("gsb-ac-liability-16.png",
875 															  _("Show amortization schedule to date"));
876         else
877             menu_item = utils_menu_item_new_from_image_label ("gsb-ac-liability-16.png",
878 															  _("Show amortization schedule from the beginning"));
879 
880         g_signal_connect (G_OBJECT (menu_item),
881 						  "activate",
882 						  G_CALLBACK (bet_finance_ui_switch_amortization_initial_date),
883 						  tree_view);
884     gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
885 
886     /* Separator */
887     gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new());
888 
889     }
890     /* Print list */
891     menu_item = utils_menu_item_new_from_image_label ("gtk-print-16.png", _("Print the array"));
892     g_signal_connect (G_OBJECT (menu_item),
893 					  "activate",
894 					  G_CALLBACK (print_tree_view_list),
895 					  tree_view);
896     gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
897 
898     /* Export list */
899     menu_item = utils_menu_item_new_from_image_label ("gsb-export-16.png", _("Export the array"));
900     g_signal_connect (G_OBJECT (menu_item),
901 					  "activate",
902 					  G_CALLBACK (bet_finance_ui_export_tab),
903 					  tree_view);
904     gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
905 
906     /* Finish all. */
907     gtk_widget_show_all (menu);
908 
909 #if GTK_CHECK_VERSION (3,22,0)
910 	gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL);
911 #else
912 	gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, 3, gtk_get_current_event_time ());
913 #endif
914 }
915 
916 /**
917  * called when we press a button on the list
918  *
919  * \param tree_view
920  * \param ev
921  * \param page
922  *
923  * \return FALSE
924  **/
bet_finance_ui_data_list_button_press(GtkWidget * tree_view,GdkEventButton * ev,GtkWidget * page)925 static gboolean bet_finance_ui_data_list_button_press (GtkWidget *tree_view,
926 													   GdkEventButton *ev,
927 													   GtkWidget *page)
928 {
929     /* show the popup */
930     if (ev->button == RIGHT_BUTTON)
931     {
932         gint page_num;
933 
934         page_num = gtk_notebook_page_num (GTK_NOTEBOOK (finance_notebook), page);
935         bet_finance_ui_data_list_context_menu (tree_view, page_num);
936     }
937 
938     return FALSE;
939 }
940 
941 /**
942  * Create the amortization page
943  *
944  * \param
945  *
946  * \return
947  **/
bet_finance_ui_create_amortization_page(void)948 static GtkWidget *bet_finance_ui_create_amortization_page (void)
949 {
950     GtkWidget *page;
951     GtkWidget *frame;
952     GtkWidget *hbox;
953     GtkWidget *label_title;
954     GtkWidget *label;
955     GtkWidget *tree_view;
956 
957     page = gtk_box_new (GTK_ORIENTATION_VERTICAL, MARGIN_BOX);
958 
959     /* frame pour la barre d'outils */
960     frame = gtk_frame_new (NULL);
961     gtk_box_pack_start (GTK_BOX (page), frame, FALSE, FALSE, 0);
962 
963     /* titre de la page */
964     label_title = gtk_label_new (_("Amortization Table"));
965 	gtk_widget_set_halign (label_title, GTK_ALIGN_CENTER);
966     gtk_box_pack_start (GTK_BOX (page), label_title, FALSE, FALSE, MARGIN_BOX);
967 
968     /* Choix des données sources */
969     hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, MARGIN_BOX);
970 	gtk_widget_set_halign (hbox, GTK_ALIGN_CENTER);
971     gtk_box_pack_start (GTK_BOX (page), hbox, FALSE, FALSE, 5);
972 
973     /* capital */
974     label = gtk_label_new (_("Loan amount: "));
975     utils_labels_set_alignment (GTK_LABEL (label), GSB_LEFT, GSB_CENTER);
976     gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
977     gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, MARGIN_BOX);
978 
979     label = gtk_label_new (NULL);
980     g_object_set_data (G_OBJECT (page), "capital", label);
981     gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, MARGIN_BOX);
982 
983     /* taux */
984     label = gtk_label_new (_("Annuel rate interest: "));
985     utils_labels_set_alignment (GTK_LABEL (label), GSB_LEFT, GSB_CENTER);
986     gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
987     gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, MARGIN_BOX);
988 
989     label = gtk_label_new (NULL);
990     g_object_set_data (G_OBJECT (page), "bet_finance_taux", label);
991     gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
992 
993     label = gtk_label_new (_("%"));
994     gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
995     gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 5);
996 
997     /* Duration */
998     label = gtk_label_new (_("Duration: "));
999     utils_labels_set_alignment (GTK_LABEL (label), GSB_LEFT, GSB_CENTER);
1000     gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1001     gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, MARGIN_BOX);
1002 
1003     label = gtk_label_new (NULL);
1004     g_object_set_data (G_OBJECT (page), "duree", label);
1005     gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
1006 
1007     /* création de la liste des données */
1008     tree_view = bet_finance_ui_create_amortization_tree_view (page, SPP_ORIGIN_SIMULATOR);
1009     g_object_set_data (G_OBJECT (tree_view), "origin", GINT_TO_POINTER (SPP_ORIGIN_SIMULATOR));
1010     g_object_set_data (G_OBJECT (page), "tree_view", tree_view);
1011     g_object_set_data (G_OBJECT (tree_view), "label_title", label_title);
1012 
1013     /* set the color of selected row */
1014 	gtk_widget_set_name (tree_view, "tree_view");
1015 
1016     /* on y ajoute la barre d'outils */
1017     amortization_toolbar = bet_finance_ui_create_simulator_toolbar (page, tree_view, FALSE, TRUE);
1018     gtk_container_add (GTK_CONTAINER (frame), amortization_toolbar);
1019 
1020     gtk_widget_show_all (page);
1021 
1022     return page;
1023 }
1024 
1025 /**
1026  *
1027  *
1028  * \param
1029  *
1030  * \return
1031  **/
bet_finance_ui_create_data_tree_view(GtkWidget * container)1032 static GtkWidget *bet_finance_ui_create_data_tree_view (GtkWidget *container)
1033 {
1034     GtkWidget *scrolled_window;
1035     GtkWidget *tree_view;
1036     GtkWidget *button;
1037     GtkTreeStore *tree_model;
1038     GtkCellRenderer *cell;
1039     GtkTreeViewColumn *column;
1040     gchar *title;
1041 
1042     tree_view = gtk_tree_view_new ();
1043 
1044     /* Create the tree store */
1045     tree_model = gtk_tree_store_new (BET_FINANCE_NBRE_COLUMNS,
1046 									 G_TYPE_STRING,		/* BET_FINANCE_DURATION_COLUMN        */
1047 									 G_TYPE_INT,		/* BET_FINANCE_NBRE_ECHEANCE_COLUMN   */
1048 									 G_TYPE_INT,		/* BET_FINANCE_DEVISE_COLUMN          */
1049 									 G_TYPE_STRING,		/* BET_FINANCE_CAPITAL_COLUMN         */
1050 									 G_TYPE_DOUBLE,		/* BET_FINANCE_CAPITAL_DOUBLE         */
1051 									 G_TYPE_STRING,		/* BET_FINANCE_TAUX_COLUMN            */
1052 									 G_TYPE_DOUBLE,		/* BET_FINANCE_TAUX_DOUBLE            */
1053 									 G_TYPE_STRING,		/* BET_FINANCE_HORS_FRAIS_COLUMN      */
1054 									 G_TYPE_DOUBLE,		/* BET_FINANCE_HORS_FRAIS_DOUBLE      */
1055 									 G_TYPE_STRING,		/* BET_FINANCE_FRAIS_COLUMN           */
1056 									 G_TYPE_DOUBLE,		/* BET_FINANCE_FRAIS_DOUBLE           */
1057 									 G_TYPE_STRING,		/* BET_FINANCE_ECHEANCE_COLUMN        */
1058 									 G_TYPE_DOUBLE,		/* BET_FINANCE_ECHEANCE_DOUBLE        */
1059 									 G_TYPE_STRING,		/* BET_FINANCE_COUT_COLUMN            */
1060 									 G_TYPE_DOUBLE,		/* BET_FINANCE_COUT_DOUBLE            */
1061 									 GDK_TYPE_RGBA);	/* BET_FINANCE_BACKGROUND_COLOR       */
1062     gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), GTK_TREE_MODEL (tree_model));
1063     g_object_unref (G_OBJECT (tree_model));
1064 
1065     /* create columns */
1066 
1067     /* Duration */
1068     title = g_strdup (_("Duration"));
1069     cell = gtk_cell_renderer_text_new ();
1070     g_object_set (G_OBJECT (cell), "xalign", GSB_CENTER, NULL);
1071 
1072     column = gtk_tree_view_column_new_with_attributes (title,
1073 													   cell,
1074 													   "text", BET_FINANCE_DURATION_COLUMN,
1075 													   "cell-background-rgba", BET_FINANCE_BACKGROUND_COLOR,
1076 													   NULL);
1077     gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column));
1078     gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
1079     gtk_tree_view_column_set_resizable (column, TRUE);
1080     gtk_tree_view_column_set_alignment (column, 0.5);
1081     g_object_set_data (G_OBJECT (column), "num_col_model", GINT_TO_POINTER (BET_FINANCE_DURATION_COLUMN));
1082     g_free (title);
1083 
1084     /* Number of periods */
1085     title = g_strdup (_("Number\nof periods"));
1086     cell = gtk_cell_renderer_text_new ();
1087     g_object_set (G_OBJECT (cell), "xalign", GSB_CENTER, NULL);
1088 
1089     column = gtk_tree_view_column_new_with_attributes (title,
1090 													   cell,
1091 													   "text", BET_FINANCE_NBRE_ECHEANCE_COLUMN,
1092 													   "cell-background-rgba", BET_FINANCE_BACKGROUND_COLOR,
1093 													   NULL);
1094     gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column));
1095     gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
1096     gtk_tree_view_column_set_resizable (column, TRUE);
1097     gtk_tree_view_column_set_alignment (column, COLUMN_CENTER);
1098     g_object_set_data (G_OBJECT (column), "num_col_model", GINT_TO_POINTER (BET_FINANCE_NBRE_ECHEANCE_COLUMN));
1099     g_free (title);
1100 
1101     /* Loan capital */
1102     title = g_strdup (_("Loan\ncapital"));
1103     cell = gtk_cell_renderer_text_new ();
1104     g_object_set (G_OBJECT (cell), "xalign", GSB_CENTER, NULL);
1105 
1106     column = gtk_tree_view_column_new_with_attributes (title,
1107 													   cell,
1108 													   "text", BET_FINANCE_CAPITAL_COLUMN,
1109 													   "cell-background-rgba", BET_FINANCE_BACKGROUND_COLOR,
1110 													   NULL);
1111     gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column));
1112     gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
1113     gtk_tree_view_column_set_resizable (column, TRUE);
1114     gtk_tree_view_column_set_alignment (column, COLUMN_CENTER);
1115     g_object_set_data (G_OBJECT (column), "num_col_model", GINT_TO_POINTER (BET_FINANCE_CAPITAL_COLUMN));
1116     g_free (title);
1117 
1118     /* Annuel rate interest */
1119     title = g_strdup (_("Annuel\nrate interest"));
1120     cell = gtk_cell_renderer_text_new ();
1121     g_object_set (G_OBJECT (cell), "xalign", GSB_CENTER, NULL);
1122 
1123     column = gtk_tree_view_column_new_with_attributes (title,
1124 													   cell,
1125 													   "text", BET_FINANCE_TAUX_COLUMN,
1126 													   "cell-background-rgba", BET_FINANCE_BACKGROUND_COLOR,
1127 													   NULL);
1128     gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column));
1129     gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
1130     gtk_tree_view_column_set_resizable (column, TRUE);
1131     gtk_tree_view_column_set_alignment (column, COLUMN_CENTER);
1132     g_object_set_data (G_OBJECT (column), "num_col_model", GINT_TO_POINTER (BET_FINANCE_TAUX_COLUMN));
1133     g_free (title);
1134 
1135     /* Amount without fees */
1136     title = g_strdup (_("Amount\nwithout fees"));
1137     cell = gtk_cell_renderer_text_new ();
1138     g_object_set (G_OBJECT (cell), "xalign", GSB_CENTER, NULL);
1139 
1140     column = gtk_tree_view_column_new_with_attributes (title,
1141 													   cell,
1142 													   "text", BET_FINANCE_HORS_FRAIS_COLUMN,
1143 													   "cell-background-rgba", BET_FINANCE_BACKGROUND_COLOR,
1144 													   NULL);
1145     gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column));
1146     gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
1147     gtk_tree_view_column_set_resizable (column, TRUE);
1148     gtk_tree_view_column_set_alignment (column, COLUMN_CENTER);
1149     g_object_set_data (G_OBJECT (column), "num_col_model", GINT_TO_POINTER (BET_FINANCE_HORS_FRAIS_COLUMN));
1150     g_free (title);
1151 
1152     /* Fees */
1153     title = g_strdup (_("Fees"));
1154     cell = gtk_cell_renderer_text_new ();
1155     g_object_set (G_OBJECT (cell), "xalign", GSB_CENTER, NULL);
1156 
1157     column = gtk_tree_view_column_new_with_attributes (title,
1158 													   cell,
1159 													   "text", BET_FINANCE_FRAIS_COLUMN,
1160 													   "cell-background-rgba", BET_FINANCE_BACKGROUND_COLOR,
1161 													   NULL);
1162     gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column));
1163     gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
1164     gtk_tree_view_column_set_resizable (column, TRUE);
1165     gtk_tree_view_column_set_alignment (column, COLUMN_CENTER);
1166     g_object_set_data (G_OBJECT (column), "num_col_model", GINT_TO_POINTER (BET_FINANCE_FRAIS_COLUMN));
1167     g_free (title);
1168 
1169     /* Monthly paid */
1170     title = g_strdup (_("Monthly paid"));
1171     cell = gtk_cell_renderer_text_new ();
1172     g_object_set (G_OBJECT (cell), "xalign", GSB_CENTER, NULL);
1173 
1174     column = gtk_tree_view_column_new_with_attributes (title,
1175 													   cell,
1176 													   "text", BET_FINANCE_ECHEANCE_COLUMN,
1177 													   "cell-background-rgba", BET_FINANCE_BACKGROUND_COLOR,
1178 													   NULL);
1179     gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column));
1180     gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
1181     gtk_tree_view_column_set_resizable (column, TRUE);
1182     gtk_tree_view_column_set_alignment (column, COLUMN_CENTER);
1183     g_object_set_data (G_OBJECT (column), "num_col_model", GINT_TO_POINTER (BET_FINANCE_ECHEANCE_COLUMN));
1184     g_free (title);
1185 
1186     /* Total cost */
1187     title = g_strdup (_("Total cost"));
1188     cell = gtk_cell_renderer_text_new ();
1189     g_object_set (G_OBJECT (cell), "xalign", GSB_CENTER, NULL);
1190 
1191     column = gtk_tree_view_column_new_with_attributes (title,
1192 													   cell,
1193 													   "text", BET_FINANCE_COUT_COLUMN,
1194 													   "cell-background-rgba", BET_FINANCE_BACKGROUND_COLOR,
1195 													   NULL);
1196     gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column));
1197 
1198     button = gtk_tree_view_column_get_button  (column);
1199     gtk_widget_set_tooltip_text (GTK_WIDGET (button), _("Approximate cost"));
1200     gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
1201     gtk_tree_view_column_set_resizable (column, TRUE);
1202     gtk_tree_view_column_set_alignment (column, COLUMN_CENTER);
1203     g_object_set_data (G_OBJECT (column), "num_col_model", GINT_TO_POINTER (BET_FINANCE_COUT_COLUMN));
1204     g_free (title);
1205 
1206     g_signal_connect (G_OBJECT (tree_view),
1207 					  "button-press-event",
1208 					  G_CALLBACK (bet_finance_ui_data_list_button_press),
1209 					  container);
1210 
1211     scrolled_window = gtk_scrolled_window_new (NULL, NULL);
1212     gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
1213 									GTK_POLICY_NEVER,
1214 									GTK_POLICY_AUTOMATIC);
1215     gtk_widget_set_size_request (scrolled_window, -1, 250);
1216     gtk_container_add (GTK_CONTAINER (scrolled_window), tree_view);
1217     gtk_box_pack_start (GTK_BOX (container), scrolled_window, TRUE, TRUE, 15);
1218 
1219     gtk_widget_show_all (scrolled_window);
1220 
1221     return tree_view;
1222 }
1223 
1224 /**
1225  *
1226  *
1227  * \param
1228  * \param
1229  *
1230  * \return
1231  **/
bet_finance_ui_duration_button_changed(GtkWidget * combobox,GtkWidget * widget)1232 static gboolean bet_finance_ui_duration_button_changed (GtkWidget *combobox,
1233 														GtkWidget *widget)
1234 {
1235     bet_finance_ui_calculer_clicked (NULL, widget);
1236 
1237     return FALSE;
1238 }
1239 
1240 /**
1241  *
1242  *
1243  * \param
1244  *
1245  * \return
1246  **/
bet_finance_ui_create_duration_widget(GtkWidget * parent)1247 static GtkWidget *bet_finance_ui_create_duration_widget (GtkWidget *parent)
1248 {
1249     GtkWidget *combobox;
1250     const gchar *text_duration [] = {N_("Between 3 and 18 months"),
1251 									 N_("Between 1 and 15 years"),
1252     								 N_("Between 15 and 30 years"),
1253     								 NULL};
1254 
1255     combobox = gsb_combo_box_new_with_index (text_duration,
1256 											 G_CALLBACK (bet_finance_ui_duration_button_changed),
1257 											 parent);
1258 
1259     g_signal_handlers_block_by_func (G_OBJECT (combobox),
1260 									 G_CALLBACK (bet_finance_ui_duration_button_changed),
1261 									 parent);
1262     gsb_combo_box_set_index (combobox, etat.bet_index_duree);
1263     g_signal_handlers_unblock_by_func (G_OBJECT (combobox),
1264 									   G_CALLBACK (bet_finance_ui_duration_button_changed),
1265 									   parent);
1266 
1267     return combobox;
1268 }
1269 
1270 /**
1271  *
1272  *
1273  * \param
1274  * \param
1275  *
1276  * \return
1277  **/
bet_finance_ui_spin_button_fees_changed(GtkSpinButton * spinbutton,GtkWidget * page)1278 static void bet_finance_ui_spin_button_fees_changed (GtkSpinButton *spinbutton,
1279 													 GtkWidget *page)
1280 {
1281     etat.bet_frais = gtk_spin_button_get_value (GTK_SPIN_BUTTON (spinbutton));
1282     bet_finance_ui_calculer_clicked (NULL, page);
1283 }
1284 
1285 /**
1286  *
1287  *
1288  * \param
1289  * \param
1290  *
1291  * \return
1292  **/
bet_finance_ui_spin_button_taux_changed(GtkSpinButton * spinbutton,GtkWidget * page)1293 static void bet_finance_ui_spin_button_taux_changed (GtkSpinButton *spinbutton,
1294 													 GtkWidget *page)
1295 {
1296     etat.bet_taux_annuel = gtk_spin_button_get_value (GTK_SPIN_BUTTON (spinbutton));
1297     bet_finance_ui_calculer_clicked (NULL, page);
1298 }
1299 
1300 /**
1301  *
1302  *
1303  * \param
1304  * \param
1305  * \param
1306  *
1307  * \return
1308  **/
bet_finance_ui_type_taux_changed(GtkWidget * togglebutton,GdkEventButton * event,GtkWidget * widget)1309 static void bet_finance_ui_type_taux_changed (GtkWidget *togglebutton,
1310 											  GdkEventButton *event,
1311 											  GtkWidget *widget)
1312 {
1313     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (togglebutton), TRUE);
1314     etat.bet_type_taux = !etat.bet_type_taux;
1315     bet_finance_ui_calculer_clicked (NULL, widget);
1316 }
1317 
1318 /**
1319  *
1320  *
1321  * \param
1322  *
1323  * \return
1324  **/
bet_finance_ui_create_saisie_widget(GtkWidget * page,GtkWidget * grid)1325 static void bet_finance_ui_create_saisie_widget (GtkWidget *page,
1326 												 GtkWidget *grid)
1327 {
1328     GtkWidget *hbox;
1329     GtkWidget *label;
1330     GtkWidget *spin_button = NULL;
1331     GtkWidget *button_1, *button_2;
1332     gchar *tmp_str;
1333 
1334     /* taux */
1335     label = gtk_label_new (_("Annual interest: "));
1336     utils_labels_set_alignment (GTK_LABEL (label), GSB_LEFT, GSB_CENTER);
1337     gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1338 	gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1 ,1);
1339 
1340     spin_button = gtk_spin_button_new_with_range (0.0, 100,
1341                         bet_data_finance_get_bet_taux_step (BET_TAUX_DIGITS));
1342     gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_button), etat.bet_taux_annuel);
1343     g_object_set_data (G_OBJECT (page), "taux", spin_button);
1344 	gtk_grid_attach (GTK_GRID (grid), spin_button, 1, 1, 1 ,1);
1345     g_signal_connect (spin_button,
1346 					  "value-changed",
1347 					  G_CALLBACK (bet_finance_ui_spin_button_taux_changed),
1348 					  page);
1349 
1350     label = gtk_label_new (_("%"));
1351     gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1352 	gtk_widget_set_halign (label, GTK_ALIGN_START);
1353 	gtk_grid_attach (GTK_GRID (grid), label, 2, 1, 1 ,1);
1354 
1355     /* Frais */
1356     label = gtk_label_new (_("Fees: "));
1357     utils_labels_set_alignment (GTK_LABEL (label), GSB_LEFT, GSB_CENTER);
1358     gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1359     gtk_grid_attach (GTK_GRID (grid), label, 3, 1, 1 ,1);
1360 
1361     spin_button = gtk_spin_button_new_with_range (0.0,
1362 												  100,
1363 												  bet_data_finance_get_bet_taux_step (BET_TAUX_DIGITS));
1364     gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_button), etat.bet_frais);
1365     g_object_set_data (G_OBJECT (page), "frais", spin_button);
1366 	gtk_grid_attach (GTK_GRID (grid), spin_button, 4, 1, 1 ,1);
1367     g_signal_connect (spin_button,
1368 					  "value-changed",
1369 					  G_CALLBACK (bet_finance_ui_spin_button_fees_changed),
1370 					  page);
1371 
1372     tmp_str = g_strconcat (_("%"), _(" of capital"), NULL);
1373     label = gtk_label_new (tmp_str);
1374     gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1375     gtk_grid_attach (GTK_GRID (grid), label, 5, 1, 1 ,1);
1376     g_free (tmp_str);
1377 
1378     /* Type de taux */
1379     hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, MARGIN_BOX);
1380 	gtk_widget_set_halign (hbox, GTK_ALIGN_CENTER);
1381     gtk_grid_attach (GTK_GRID (grid), hbox, 0, 2, 6 ,1);
1382 
1383     label = gtk_label_new (_("Rate Type: "));
1384     utils_labels_set_alignment (GTK_LABEL (label), GSB_LEFT, GSB_CENTER);
1385     gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1386     gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, MARGIN_BOX);
1387     button_1 = gtk_radio_button_new_with_label (NULL, _("CAGR"));
1388 
1389     button_2 = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (button_1),
1390 															_("Proportional rate"));
1391     g_object_set_data (G_OBJECT (page), "type_taux", button_2);
1392 
1393     if (etat.bet_type_taux)
1394         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button_2), TRUE);
1395     else
1396         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button_1), TRUE);
1397 
1398     gtk_box_pack_start (GTK_BOX (hbox), button_1, FALSE, FALSE, MARGIN_BOX) ;
1399     gtk_box_pack_start (GTK_BOX (hbox), button_2, FALSE, FALSE, MARGIN_BOX) ;
1400     g_signal_connect (button_1,
1401 					  "button-release-event",
1402 					  G_CALLBACK (bet_finance_ui_type_taux_changed),
1403 					  page);
1404     g_signal_connect (button_2,
1405 					  "button-release-event",
1406 					  G_CALLBACK (bet_finance_ui_type_taux_changed),
1407 					  page);
1408 }
1409 
1410 /**
1411  *
1412  *
1413  * \param
1414  * \param
1415  *
1416  * \return
1417  **/
bet_finance_ui_currency_changed(GtkComboBox * combo_box,GtkWidget * page)1418 static void bet_finance_ui_currency_changed (GtkComboBox *combo_box,
1419 											 GtkWidget *page)
1420 {
1421     etat.bet_currency = gsb_currency_get_currency_from_combobox (GTK_WIDGET (combo_box));
1422     bet_finance_ui_calculer_clicked (NULL, page);
1423 }
1424 
1425 /**
1426  * Create the simulator page
1427  *
1428  * \param
1429  *
1430  * \return
1431  **/
bet_finance_ui_create_simulator_page(void)1432 static GtkWidget *bet_finance_ui_create_simulator_page (void)
1433 {
1434     GtkWidget *page;
1435     GtkWidget *frame;
1436     GtkWidget *widget;
1437     GtkWidget *grid;
1438     GtkWidget *label_title;
1439     GtkWidget *label;
1440     GtkWidget *tree_view;
1441     gchar *str_capital;
1442 
1443     page = gtk_box_new (GTK_ORIENTATION_VERTICAL, MARGIN_BOX);
1444 
1445     /* frame pour la barre d'outils */
1446     frame = gtk_frame_new (NULL);
1447     gtk_box_pack_start (GTK_BOX (page), frame, FALSE, FALSE, 0);
1448 
1449     /* titre de la page */
1450     label_title = gtk_label_new (_("Credits simulator"));
1451 	gtk_widget_set_halign (label_title, GTK_ALIGN_CENTER);
1452     gtk_box_pack_start (GTK_BOX (page), label_title, FALSE, FALSE, MARGIN_BOX);
1453 
1454     /* Choix des données sources */
1455 	grid = gtk_grid_new ();
1456 	gtk_grid_set_column_spacing (GTK_GRID (grid), MARGIN_BOX);
1457 	gtk_grid_set_row_spacing (GTK_GRID (grid), MARGIN_BOX);
1458 	gtk_widget_set_margin_start (grid, MARGIN_BOX);
1459     gtk_box_pack_start (GTK_BOX (page), grid, FALSE, FALSE, MARGIN_BOX);
1460 
1461     /* capital */
1462     label = gtk_label_new (_("Loan capital: "));
1463     utils_labels_set_alignment (GTK_LABEL (label), GSB_LEFT, GSB_CENTER);
1464     gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1465 	gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1 ,1);
1466 
1467     str_capital = utils_real_get_string_with_currency (gsb_real_double_to_real (etat.bet_capital),
1468 													   etat.bet_currency,
1469 													   FALSE);
1470 
1471     widget = gtk_entry_new ();
1472     gtk_entry_set_text (GTK_ENTRY (widget), str_capital);
1473     g_object_set_data (G_OBJECT (page), "capital", widget);
1474 	gtk_grid_attach (GTK_GRID (grid), widget, 1, 0, 1 ,1);
1475     g_signal_connect (G_OBJECT (widget),
1476 					  "changed",
1477 					  G_CALLBACK (bet_finance_ui_capital_entry_changed),
1478 					  page);
1479     g_signal_connect (G_OBJECT (widget),
1480 					  "key-press-event",
1481 					  G_CALLBACK (bet_finance_ui_capital_entry_key_press_event),
1482 					  page);
1483 
1484     g_free (str_capital);
1485 
1486     /* Set the devises */
1487     widget = gsb_currency_make_combobox (FALSE);
1488     gsb_currency_set_combobox_history (widget, etat.bet_currency);
1489     g_object_set_data (G_OBJECT (page), "devise", widget);
1490 	gtk_grid_attach (GTK_GRID (grid), widget, 2, 0, 1 ,1);
1491     g_signal_connect (G_OBJECT ( widget),
1492 					  "changed",
1493 					  G_CALLBACK (bet_finance_ui_currency_changed),
1494 					  page);
1495 
1496     /* Duration */
1497     label = gtk_label_new (_("Duration: "));
1498     utils_labels_set_alignment (GTK_LABEL (label), GSB_LEFT, GSB_CENTER);
1499     gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1500 	gtk_grid_attach (GTK_GRID (grid), label, 3, 0, 1 ,1);
1501 
1502     widget = bet_finance_ui_create_duration_widget (page);
1503     g_object_set_data (G_OBJECT (page), "duree", widget);
1504 	gtk_grid_attach (GTK_GRID (grid), widget, 4, 0, 1 ,1);
1505 
1506     /* création du widget saisie détaillée */
1507 	bet_finance_ui_create_saisie_widget (page, grid);
1508 
1509     /* création de la liste des données */
1510     tree_view = bet_finance_ui_create_data_tree_view (page);
1511     g_object_set_data (G_OBJECT (tree_view), "origin", GINT_TO_POINTER (SPP_ORIGIN_SIMULATOR));
1512     g_object_set_data (G_OBJECT (page), "tree_view", tree_view);
1513     g_object_set_data (G_OBJECT (tree_view), "label_title", label_title);
1514 
1515     /* set the color of selected row */
1516 	gtk_widget_set_name (tree_view, "colorized_tree_view");
1517 
1518     /* on y ajoute la barre d'outils */
1519     simulator_toolbar = bet_finance_ui_create_simulator_toolbar (page, tree_view, TRUE, FALSE);
1520     gtk_container_add (GTK_CONTAINER (frame), simulator_toolbar);
1521 
1522     gtk_widget_show_all (page);
1523 
1524     return page;
1525 }
1526 
1527 /**
1528  *
1529  *
1530  * \param
1531  * \param
1532  *
1533  * \return
1534  **/
bet_finance_ui_get_column_by_name(GtkWidget * tree_view,const gchar * name)1535 static GtkTreeViewColumn *bet_finance_ui_get_column_by_name (GtkWidget *tree_view,
1536 															 const gchar *name)
1537 {
1538 	GList *list;
1539 
1540 	list = gtk_tree_view_get_columns (GTK_TREE_VIEW (tree_view));
1541 	while (list)
1542 	{
1543 		GtkTreeViewColumn *col;
1544 		gchar *tmp_str;
1545 
1546 		col = list->data;
1547 		tmp_str = g_object_get_data (G_OBJECT (col), "name");
1548 		if (g_strcmp0 (tmp_str, name) == 0)
1549 		{
1550 			g_list_free (list);
1551 
1552 			return col;
1553 		}
1554 
1555 		list = list->next;
1556 	}
1557 	g_list_free (list);
1558 
1559 	return NULL;
1560 }
1561 
1562 /**
1563  *
1564  *
1565  * \param
1566  * \param
1567  *
1568  * \return
1569  **/
bet_finance_ui_invers_cols_cap_ech_amortization(GtkWidget * tree_view,gboolean invers_cols_cap_ech)1570 static void bet_finance_ui_invers_cols_cap_ech_amortization (GtkWidget *tree_view,
1571 															 gboolean invers_cols_cap_ech)
1572 {
1573 	GtkTreeViewColumn *capital_du_col;
1574 	GtkTreeViewColumn *date_col;
1575 	GtkTreeViewColumn *echeance_col;
1576 	GtkTreeViewColumn *frais_col;
1577 
1578 	date_col = gtk_tree_view_get_column (GTK_TREE_VIEW (tree_view), 1);
1579 	frais_col = gtk_tree_view_get_column (GTK_TREE_VIEW (tree_view), 5);
1580 	capital_du_col = bet_finance_ui_get_column_by_name (tree_view, "CapitalDu");
1581 	echeance_col = bet_finance_ui_get_column_by_name (tree_view, "Echeance");
1582 
1583 	if (invers_cols_cap_ech)
1584 	{
1585 		gtk_tree_view_move_column_after (GTK_TREE_VIEW (tree_view),
1586 										 echeance_col,
1587 										 date_col);
1588 		gtk_tree_view_move_column_after (GTK_TREE_VIEW (tree_view),
1589 										 capital_du_col,
1590 										 frais_col);
1591 	}
1592 	else
1593 	{
1594 		gtk_tree_view_move_column_after (GTK_TREE_VIEW (tree_view),
1595 										 capital_du_col,
1596 										 date_col);
1597 		gtk_tree_view_move_column_after (GTK_TREE_VIEW (tree_view),
1598 										 echeance_col,
1599 										 frais_col);
1600 	}
1601 }
1602 
1603 /******************************************************************************/
1604 /* Public functions                                                           */
1605 /******************************************************************************/
1606 /**
1607  * Create the loan simulator page
1608  *
1609  * \param
1610  *
1611  * \return
1612  **/
bet_finance_ui_create_loan_simulator(void)1613 GtkWidget *bet_finance_ui_create_loan_simulator (void)
1614 {
1615     GtkWidget *page;
1616 
1617     devel_debug (NULL);
1618 
1619     /* create a notebook for simulator and array of Amortization */
1620     finance_notebook = gtk_notebook_new ();
1621     gtk_notebook_set_show_tabs (GTK_NOTEBOOK (finance_notebook), FALSE);
1622     gtk_widget_show (finance_notebook);
1623 
1624     /* create the simulator page */
1625     page = bet_finance_ui_create_simulator_page ();
1626     gtk_notebook_append_page (GTK_NOTEBOOK (finance_notebook), page, NULL);
1627 
1628     /* create the array page */
1629     page = bet_finance_ui_create_amortization_page ();
1630     gtk_notebook_append_page (GTK_NOTEBOOK (finance_notebook), page, NULL);
1631 
1632     return finance_notebook;
1633 }
1634 
1635 /**
1636  * Switch to the simulator page
1637  *
1638  * \param
1639  *
1640  * \return
1641  **/
bet_finance_ui_switch_simulator_page(void)1642 void bet_finance_ui_switch_simulator_page (void)
1643 {
1644     GtkWidget *page;
1645 
1646     page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (finance_notebook), 0);
1647     gtk_notebook_set_current_page (GTK_NOTEBOOK (finance_notebook), 0);
1648     bet_finance_ui_calculer_clicked (NULL, page);
1649 }
1650 
1651 /**
1652  * Create the account amortization page
1653  *
1654  * \param
1655  *
1656  * \return
1657  **/
bet_finance_ui_create_account_amortization_page(void)1658 GtkWidget *bet_finance_ui_create_account_amortization_page (void)
1659 {
1660     GtkWidget *page;
1661     GtkWidget *frame;
1662     GtkWidget *label_title;
1663     GtkWidget *tree_view;
1664     GtkWidget *account_page;
1665 
1666     devel_debug (NULL);
1667     account_page = grisbi_win_get_account_page ();
1668 
1669     /* frame pour la barre d'outils */
1670 	page = bet_finance_ui_create_amortization_heading (account_page);
1671 
1672     /* titre de la page */
1673 	label_title = g_object_get_data (G_OBJECT (account_page), "label_title");
1674 
1675     /* création de la liste des données */
1676     tree_view = bet_finance_ui_create_amortization_tree_view (page, SPP_ORIGIN_FINANCE);
1677     g_object_set_data (G_OBJECT (tree_view), "origin", GINT_TO_POINTER (SPP_ORIGIN_FINANCE));
1678     g_object_set_data (G_OBJECT (account_page), "bet_finance_tree_view", tree_view);
1679     g_object_set_data (G_OBJECT (tree_view), "label_title", label_title);
1680 
1681     /* set the color of selected row */
1682 	gtk_widget_set_name (tree_view, "colorized_tree_view");
1683 
1684     /* on y ajoute la barre d'outils */
1685 	frame = g_object_get_data (G_OBJECT (account_page), "frame");
1686     account_toolbar = bet_finance_ui_create_simulator_toolbar (page, tree_view, FALSE, FALSE);
1687     gtk_container_add (GTK_CONTAINER (frame), account_toolbar);
1688 
1689     gtk_widget_show_all (page);
1690 
1691     return page;
1692 }
1693 
1694 /**
1695  *
1696  *
1697  * \param
1698  *
1699  * \return
1700  **/
bet_finance_ui_create_amortization_heading(GtkWidget * parent)1701 GtkWidget *bet_finance_ui_create_amortization_heading (GtkWidget *parent)
1702 {
1703     GtkWidget *heading;
1704     GtkWidget *frame;
1705     GtkWidget *hbox;
1706     GtkWidget *label_title;
1707     GtkWidget *label;
1708 
1709     heading = gtk_box_new (GTK_ORIENTATION_VERTICAL, MARGIN_BOX);
1710 
1711     /* frame pour la barre d'outils */
1712     frame = gtk_frame_new (NULL);
1713     gtk_box_pack_start (GTK_BOX (heading), frame, FALSE, FALSE, 0);
1714 
1715     /* titre de la heading */
1716     label_title = gtk_label_new (_("Amortization Table"));
1717 	gtk_widget_set_halign (label_title, GTK_ALIGN_CENTER);
1718     gtk_box_pack_start (GTK_BOX (heading), label_title, FALSE, FALSE, 5);
1719     g_object_set_data (G_OBJECT (parent),
1720 					   "bet_finance_amortization_title",
1721 					   label_title);
1722 
1723     /* Choix des données sources */
1724     hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, MARGIN_BOX);
1725 	gtk_widget_set_halign (hbox, GTK_ALIGN_CENTER);
1726     gtk_box_pack_start (GTK_BOX (heading), hbox, FALSE, FALSE, 5);
1727 
1728     /* capital */
1729     label = gtk_label_new (_("Loan amount: "));
1730     utils_labels_set_alignment (GTK_LABEL (label), 0, 0.5);
1731     gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1732     gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 5);
1733 
1734     label = gtk_label_new (NULL);
1735     g_object_set_data (G_OBJECT (parent), "bet_finance_capital", label);
1736     gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 5);
1737 
1738     /* taux */
1739     label = gtk_label_new (_("Annuel rate interest: "));
1740     utils_labels_set_alignment (GTK_LABEL (label), 0, 0.5);
1741     gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1742     gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 5);
1743 
1744     label = gtk_label_new (NULL);
1745     g_object_set_data (G_OBJECT (parent), "bet_finance_taux", label);
1746     gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
1747 
1748     label = gtk_label_new (_("%"));
1749     gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1750     gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 5);
1751 
1752     /* Duration */
1753     label = gtk_label_new (_("Duration: "));
1754     utils_labels_set_alignment (GTK_LABEL (label), 0, 0.5);
1755     gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1756     gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 5);
1757 
1758     label = gtk_label_new (NULL);
1759     g_object_set_data (G_OBJECT (parent), "bet_finance_duree", label);
1760     gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
1761 
1762 	g_object_set_data (G_OBJECT (parent), "frame", frame);
1763 	g_object_set_data (G_OBJECT (parent), "label_title", label_title);
1764 
1765 	gtk_widget_show_all (heading);
1766 
1767 	return heading;
1768 }
1769 
1770 /**
1771  *
1772  *
1773  * \param
1774  * \param
1775  *
1776  * \return
1777  **/
bet_finance_ui_create_amortization_tree_view(GtkWidget * container,gint origin)1778 GtkWidget *bet_finance_ui_create_amortization_tree_view (GtkWidget *container,
1779 														 gint origin)
1780 {
1781     GtkWidget *scrolled_window;
1782     GtkWidget *tree_view;
1783     GtkTreeStore *tree_model;
1784     GtkCellRenderer *cell;
1785     GtkTreeViewColumn *column;
1786     gchar *title;
1787 
1788     tree_view = gtk_tree_view_new ();
1789     g_object_set_data (G_OBJECT (tree_view), "amortization_initial_date", GINT_TO_POINTER (FALSE));
1790 
1791     /* Create the tree store */
1792     tree_model = gtk_tree_store_new (BET_AMORTIZATION_NBRE_COLUMNS,
1793 									 G_TYPE_INT,         /* BET_AMORTIZATION_NUMBER_COLUMN       */
1794 									 G_TYPE_STRING,      /* BET_AMORTIZATION_DATE_COLUMN         */
1795 									 G_TYPE_STRING,      /* BET_AMORTIZATION_CAPITAL_DU_COLUMN,  */
1796 									 G_TYPE_STRING,      /* BET_AMORTIZATION_INTERETS_COLUMN     */
1797 									 G_TYPE_STRING,      /* BET_AMORTIZATION_PRINCIPAL_COLUMN    */
1798 									 G_TYPE_STRING,      /* BET_AMORTIZATION_FRAIS_COLUMN        */
1799 									 G_TYPE_STRING,      /* BET_AMORTIZATION_ECHEANCE_COLUMN     */
1800 									 GDK_TYPE_RGBA);    /* BET_AMORTIZATION_BACKGROUND_COLOR    */
1801     gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), GTK_TREE_MODEL (tree_model));
1802     g_object_unref (G_OBJECT (tree_model));
1803 
1804     /* create columns */
1805     /* numéro ou date de l'échéance */
1806 	title = g_strdup (_("Number"));
1807     cell = gtk_cell_renderer_text_new ();
1808     g_object_set (G_OBJECT (cell), "xalign", GSB_CENTER, NULL);
1809 
1810     column = gtk_tree_view_column_new_with_attributes (title,
1811 													   cell,
1812 													   "text", BET_AMORTIZATION_NUMBER_COLUMN,
1813 													   "cell-background-rgba", BET_AMORTIZATION_BACKGROUND_COLOR,
1814 													   NULL);
1815 	g_object_set_data (G_OBJECT (column), "num_col_model", GINT_TO_POINTER (BET_AMORTIZATION_NUMBER_COLUMN));
1816 	g_object_set_data (G_OBJECT (column), "name", (gchar*)"NumEch");
1817     g_free (title);
1818 
1819     gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column));
1820     gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
1821     gtk_tree_view_column_set_resizable (column, TRUE);
1822     gtk_tree_view_column_set_alignment (column, COLUMN_CENTER);
1823 
1824     /* date de l'échéance si nécessaire */
1825 	if ( origin == SPP_ORIGIN_FINANCE )
1826     {
1827 		title = g_strdup (_("Date"));
1828 		cell = gtk_cell_renderer_text_new ();
1829 		g_object_set (G_OBJECT (cell), "xalign", GSB_CENTER, NULL);
1830 
1831 		column = gtk_tree_view_column_new_with_attributes (title,
1832 														   cell,
1833 														   "text", BET_AMORTIZATION_DATE_COLUMN,
1834 														   "cell-background-rgba", BET_AMORTIZATION_BACKGROUND_COLOR,
1835 														   NULL);
1836 		g_object_set_data (G_OBJECT (column), "num_col_model", GINT_TO_POINTER (BET_AMORTIZATION_DATE_COLUMN));
1837 		g_object_set_data (G_OBJECT (column), "name", (gchar*)"Date");
1838 		g_free (title);
1839 		gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column));
1840 		gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
1841 		gtk_tree_view_column_set_resizable (column, TRUE);
1842 		gtk_tree_view_column_set_alignment (column, COLUMN_CENTER);
1843 	}
1844 
1845 	/* Inversion des colonnes Capital_du et echéance fix Gtk-WARNING **: 13:32:11.757: Negative content height -1 */
1846 	if (origin == SPP_ORIGIN_INVERSE_FINANCE)
1847 	{
1848 		/* Monthly paid */
1849 		title = g_strdup (_("Monthly paid"));
1850 		cell = gtk_cell_renderer_text_new ();
1851 		g_object_set (G_OBJECT (cell), "xalign", GSB_CENTER, NULL);
1852 
1853 		column = gtk_tree_view_column_new_with_attributes (title,
1854 														   cell,
1855 														   "text", BET_AMORTIZATION_ECHEANCE_COLUMN,
1856 														   "cell-background-rgba", BET_AMORTIZATION_BACKGROUND_COLOR,
1857 														   NULL);
1858 		g_object_set_data (G_OBJECT (column), "num_col_model", GINT_TO_POINTER (BET_AMORTIZATION_ECHEANCE_COLUMN));
1859 		g_object_set_data (G_OBJECT (column), "name", (gchar*)"Echeance");
1860 		g_free (title);
1861 		gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column));
1862 		gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
1863 		gtk_tree_view_column_set_resizable (column, TRUE);
1864 		gtk_tree_view_column_set_alignment (column, COLUMN_CENTER);
1865 	}
1866 	else
1867 	{
1868 		/* Capital restant dû */
1869 		title = g_strdup (_("Capital remaining"));
1870 		cell = gtk_cell_renderer_text_new ();
1871 		g_object_set (G_OBJECT (cell), "xalign", GSB_CENTER, NULL);
1872 
1873 		column = gtk_tree_view_column_new_with_attributes (title,
1874 															   cell,
1875 															   "text", BET_AMORTIZATION_CAPITAL_DU_COLUMN,
1876 															   "cell-background-rgba", BET_AMORTIZATION_BACKGROUND_COLOR,
1877 															   NULL);
1878 		g_object_set_data (G_OBJECT (column), "num_col_model", GINT_TO_POINTER (BET_AMORTIZATION_CAPITAL_DU_COLUMN));
1879 		g_object_set_data (G_OBJECT (column), "name", (gchar*)"CapitalDu");
1880 		g_free (title);
1881 		gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column));
1882 		gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
1883 		gtk_tree_view_column_set_resizable (column, TRUE);
1884 		gtk_tree_view_column_set_alignment (column, COLUMN_CENTER);
1885 	}
1886 
1887     /* Interests */
1888     title = g_strdup (_("Capital repaid"));
1889     cell = gtk_cell_renderer_text_new ();
1890     g_object_set (G_OBJECT (cell), "xalign", GSB_CENTER, NULL);
1891 
1892     column = gtk_tree_view_column_new_with_attributes (title,
1893 													   cell,
1894 													   "text", BET_AMORTIZATION_PRINCIPAL_COLUMN,
1895 													   "cell-background-rgba", BET_AMORTIZATION_BACKGROUND_COLOR,
1896 													   NULL);
1897     g_object_set_data (G_OBJECT (column), "num_col_model", GINT_TO_POINTER (BET_AMORTIZATION_PRINCIPAL_COLUMN));
1898 	g_object_set_data (G_OBJECT (column), "name", (gchar*)"Principal");
1899     g_free (title);
1900     gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column));
1901     gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
1902     gtk_tree_view_column_set_resizable (column, TRUE);
1903     gtk_tree_view_column_set_alignment (column, COLUMN_CENTER);
1904 
1905     /* Capital repaid */
1906     title = g_strdup (_("Interests"));
1907     cell = gtk_cell_renderer_text_new ();
1908     g_object_set (G_OBJECT (cell), "xalign", GSB_CENTER, NULL);
1909 
1910     column = gtk_tree_view_column_new_with_attributes (title,
1911 													   cell,
1912 													   "text", BET_AMORTIZATION_INTERETS_COLUMN,
1913 													   "cell-background-rgba", BET_AMORTIZATION_BACKGROUND_COLOR,
1914 													   NULL);
1915     g_object_set_data (G_OBJECT (column), "num_col_model", GINT_TO_POINTER (BET_AMORTIZATION_INTERETS_COLUMN));
1916 	g_object_set_data (G_OBJECT (column), "name", (gchar*)"Interests");
1917     g_free (title);
1918     gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column));
1919     gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
1920     gtk_tree_view_column_set_resizable (column, TRUE);
1921     gtk_tree_view_column_set_alignment (column, COLUMN_CENTER);
1922 
1923     /* Fees*/
1924     title = g_strdup (_("Fees"));
1925     cell = gtk_cell_renderer_text_new ();
1926     g_object_set (G_OBJECT (cell), "xalign", GSB_CENTER, NULL);
1927 
1928     column = gtk_tree_view_column_new_with_attributes (title,
1929 													   cell,
1930 													   "text", BET_AMORTIZATION_FRAIS_COLUMN,
1931 													   "cell-background-rgba", BET_AMORTIZATION_BACKGROUND_COLOR,
1932 													   NULL);
1933     gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column));
1934     g_object_set_data (G_OBJECT (column), "num_col_model", GINT_TO_POINTER (BET_AMORTIZATION_FRAIS_COLUMN));
1935 	g_object_set_data (G_OBJECT (column), "name", (gchar*)"Fees");
1936     g_free (title);
1937 	gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
1938     gtk_tree_view_column_set_resizable (column, TRUE);
1939     gtk_tree_view_column_set_alignment (column, COLUMN_CENTER);
1940 
1941 	if (origin == SPP_ORIGIN_INVERSE_FINANCE)
1942 	{
1943 		/* Capital restant dû */
1944 		title = g_strdup (_("Capital remaining"));
1945 		cell = gtk_cell_renderer_text_new ();
1946 		g_object_set (G_OBJECT (cell), "xalign", GSB_CENTER, NULL);
1947 
1948 		column = gtk_tree_view_column_new_with_attributes (title,
1949 															   cell,
1950 															   "text", BET_AMORTIZATION_CAPITAL_DU_COLUMN,
1951 															   "cell-background-rgba", BET_AMORTIZATION_BACKGROUND_COLOR,
1952 															   NULL);
1953 		g_object_set_data (G_OBJECT (column), "num_col_model", GINT_TO_POINTER (BET_AMORTIZATION_CAPITAL_DU_COLUMN));
1954 		g_object_set_data (G_OBJECT (column), "name", (gchar*)"CapitalDu");
1955 		g_free (title);
1956 		gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column));
1957 		gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
1958 		gtk_tree_view_column_set_resizable (column, TRUE);
1959 		gtk_tree_view_column_set_alignment (column, COLUMN_CENTER);
1960 	}
1961 	else
1962 	{
1963 		/* Monthly paid */
1964 		title = g_strdup (_("Monthly paid"));
1965 		cell = gtk_cell_renderer_text_new ();
1966 		g_object_set (G_OBJECT (cell), "xalign", GSB_CENTER, NULL);
1967 
1968 		column = gtk_tree_view_column_new_with_attributes (title,
1969 														   cell,
1970 														   "text", BET_AMORTIZATION_ECHEANCE_COLUMN,
1971 														   "cell-background-rgba", BET_AMORTIZATION_BACKGROUND_COLOR,
1972 														   NULL);
1973 		g_object_set_data (G_OBJECT (column), "num_col_model", GINT_TO_POINTER (BET_AMORTIZATION_ECHEANCE_COLUMN));
1974 		g_object_set_data (G_OBJECT (column), "name", (gchar*)"Echeance");
1975 		g_free (title);
1976 		gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column));
1977 		gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
1978 		gtk_tree_view_column_set_resizable (column, TRUE);
1979 		gtk_tree_view_column_set_alignment (column, COLUMN_CENTER);
1980 	}
1981 
1982     g_signal_connect (G_OBJECT (tree_view),
1983 					  "button-press-event",
1984 					  G_CALLBACK (bet_finance_ui_data_list_button_press),
1985 					  container);
1986 
1987     /* create the scrolled window */
1988     scrolled_window = gtk_scrolled_window_new (NULL, NULL);
1989     gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
1990 									GTK_POLICY_NEVER,
1991 									GTK_POLICY_AUTOMATIC);
1992     gtk_widget_set_size_request (scrolled_window, -1, 250);
1993     gtk_container_add (GTK_CONTAINER (scrolled_window), tree_view);
1994     gtk_box_pack_start (GTK_BOX (container), scrolled_window, TRUE, TRUE, MARGIN_PADDING_BOX);
1995 
1996     gtk_widget_show_all (scrolled_window);
1997 
1998     return tree_view;
1999 }
2000 
2001 /**
2002  *
2003  *
2004  * \param
2005  *
2006  * \return
2007  **/
bet_finance_update_amortization_tab(gint account_number)2008 void bet_finance_update_amortization_tab (gint account_number)
2009 {
2010     GtkWidget *account_page;
2011 	LoanStruct *s_loan = NULL;
2012 
2013 /*     devel_debug (NULL);  */
2014 	if (gsb_gui_navigation_get_current_account () != account_number)
2015 		return;
2016 
2017 	s_loan = (LoanStruct *) bet_data_loan_get_last_loan_struct_by_account (account_number);
2018 	if (!s_loan)
2019 		return;
2020 
2021     /* récupère le tableau d'amortissement */
2022 	account_page = grisbi_win_get_account_page ();
2023 	bet_finance_update_amortization_tab_with_data (account_number, account_page, s_loan);
2024 }
2025 
2026 /**
2027  * Création de la barre d'outils pour les crédits
2028  *
2029  * \param parent
2030  * \param toolbar
2031  * \param tree_view
2032  * \param simulator     TRUE si page de simulation
2033  * \param               TRUE si tableau d'amortissement
2034  *
2035  * \return
2036  **/
bet_finance_ui_create_simulator_toolbar(GtkWidget * parent,GtkWidget * tree_view,gboolean simulator,gboolean amortization)2037 GtkWidget *bet_finance_ui_create_simulator_toolbar (GtkWidget *parent,
2038 													GtkWidget *tree_view,
2039 													gboolean simulator,
2040 													gboolean amortization)
2041 {
2042     GtkWidget *toolbar;
2043     GtkTreeSelection *selection;
2044     GtkToolItem *item;
2045 
2046     toolbar = gtk_toolbar_new ();
2047     g_object_set_data (G_OBJECT (toolbar), "tree_view", tree_view);
2048     g_object_set_data (G_OBJECT (toolbar), "page", parent);
2049 
2050     if (simulator)
2051     {
2052         /* création du bouton afficher le tableau d'amortissement */
2053         item = utils_buttons_tool_button_new_from_image_label ("gsb-ac-liability-24.png", _("Amortization"));
2054         gtk_widget_set_tooltip_text (GTK_WIDGET (item), _("View amortization table"));
2055         selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
2056         g_signal_connect (G_OBJECT (item),
2057 						  "clicked",
2058 						  G_CALLBACK (bet_finance_fill_amortization_array),
2059 						  selection);
2060         gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
2061     }
2062     else if (amortization)
2063     {
2064         /* création du bouton afficher le simulateur de crédits */
2065         item = utils_buttons_tool_button_new_from_image_label ("gsb-ac-liability-24.png", _("Credits"));
2066         gtk_widget_set_tooltip_text (GTK_WIDGET (item), _("View credits simulator"));
2067         g_signal_connect (G_OBJECT (item),
2068 						  "clicked",
2069 						  G_CALLBACK (bet_finance_ui_switch_simulator_page),
2070 						  NULL);
2071         gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
2072     }
2073     else
2074     {
2075         gboolean amortization_initial_date = FALSE;
2076 
2077         /* création du bouton afficher le simulateur de crédits */
2078         item = utils_buttons_tool_button_new_from_image_label ("gsb-ac-liability-24.png", _("Start date"));
2079         gtk_widget_set_tooltip_text (GTK_WIDGET (item), _("Show amortization schedule from the beginning"));
2080         g_object_set_data (G_OBJECT (tree_view), "amortization_initial_date_button", item);
2081         g_signal_connect (G_OBJECT (item),
2082 						  "clicked",
2083 						  G_CALLBACK (bet_finance_ui_switch_amortization_initial_date),
2084 						  tree_view);
2085         gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
2086         g_object_set_data (G_OBJECT (tree_view),
2087 						   "amortization_initial_date",
2088 						   GINT_TO_POINTER (amortization_initial_date));
2089     }
2090 
2091     /* création du bouton print */
2092     item = utils_buttons_tool_button_new_from_image_label ("gtk-print-24.png", _("Print"));
2093     gtk_widget_set_tooltip_text (GTK_WIDGET (item), _("Print the array"));
2094     g_signal_connect (G_OBJECT (item),
2095 					  "clicked",
2096 					  G_CALLBACK (print_tree_view_list),
2097 					  tree_view);
2098     gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
2099 
2100     /* Export button */
2101     item = utils_buttons_tool_button_new_from_image_label ("gsb-export-24.png", _("Export"));
2102     gtk_widget_set_tooltip_text (GTK_WIDGET (item), _("Export the array"));
2103     g_signal_connect (G_OBJECT (item),
2104 					  "clicked",
2105 					  G_CALLBACK (bet_finance_ui_export_tab),
2106 					  tree_view);
2107     gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
2108 
2109     /* return value */
2110     return toolbar;
2111 }
2112 
2113 /**
2114  *
2115  *
2116  * \param
2117  *
2118  * \return
2119  **/
bet_finance_ui_get_capital_entry(void)2120 GtkWidget *bet_finance_ui_get_capital_entry (void)
2121 {
2122     GtkWidget *page;
2123     GtkWidget *entry;
2124 
2125     page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (finance_notebook), 0);
2126     entry = g_object_get_data (G_OBJECT (page), "capital");
2127 
2128     return entry;
2129 }
2130 
2131 /**
2132  *
2133  *
2134  * \param
2135  *
2136  * \return
2137  **/
bet_finance_ui_update_all_finance_toolbars(gint toolbar_style)2138 void bet_finance_ui_update_all_finance_toolbars (gint toolbar_style)
2139 {
2140     gtk_toolbar_set_style (GTK_TOOLBAR (account_toolbar), toolbar_style);
2141     gtk_toolbar_set_style (GTK_TOOLBAR (amortization_toolbar), toolbar_style);
2142     gtk_toolbar_set_style (GTK_TOOLBAR (simulator_toolbar), toolbar_style);
2143 }
2144 
2145 /**
2146  *
2147  *
2148  * \param
2149  * \param
2150  * \param
2151  * \param
2152  *
2153  * \return
2154  **/
bet_finance_get_loan_amount_at_date(gint scheduled_number,gint transfer_account,GDate * date,gboolean maj_s_loan_capital_du)2155 GsbReal bet_finance_get_loan_amount_at_date (gint scheduled_number,
2156 											 gint transfer_account,
2157 											 GDate *date,
2158 											 gboolean maj_s_loan_capital_du)
2159 {
2160 	gint transaction_mother = 0;
2161 	static gint mother_number = 0;
2162 	static AmortissementStruct *s_amortissement;
2163 	GsbReal amount = {0, 0};
2164 
2165 	devel_debug_int (scheduled_number);
2166 	if (gsb_data_scheduled_get_split_of_scheduled (scheduled_number))
2167 	{
2168 		LoanStruct *s_loan;
2169 
2170 		s_loan = bet_data_loan_get_last_loan_struct_by_account (transfer_account);
2171 		if (!s_loan)
2172 			return amount;
2173 
2174 		s_amortissement = bet_finance_get_echeance_at_date (s_loan, date, maj_s_loan_capital_du);
2175 		if (!s_amortissement)
2176 			return amount;
2177 
2178 		mother_number = scheduled_number;
2179 		amount = gsb_real_opposite (gsb_real_double_to_real (s_amortissement->echeance));
2180 	}
2181 	else
2182 	{
2183 		transaction_mother = gsb_data_scheduled_get_mother_scheduled_number (scheduled_number);
2184 //~ printf ("transaction_mother = %d mother_number = %d\n", transaction_mother, mother_number);
2185 		if (transaction_mother == mother_number)
2186 		{
2187 			if (scheduled_number == mother_number+1 && (s_amortissement && s_amortissement->principal))
2188 				amount = gsb_real_opposite (gsb_real_double_to_real (s_amortissement->principal));
2189 			else if (scheduled_number == mother_number+2  && (s_amortissement && s_amortissement->interets))
2190 				amount = gsb_real_opposite (gsb_real_double_to_real (s_amortissement->interets));
2191 			else if (scheduled_number == mother_number+3  && (s_amortissement && s_amortissement->frais))
2192 				amount = gsb_real_opposite (gsb_real_double_to_real (s_amortissement->frais));
2193 //~ printf ("amount = %s\n", utils_real_get_string (amount));
2194 		}
2195 	}
2196 
2197 	return amount;
2198 }
2199 
2200 /**
2201  *
2202  *
2203  * \param
2204  * \param
2205  *
2206  * \return
2207  **/
bet_finance_get_echeance_first(LoanStruct * s_loan,GDate * first_date)2208 AmortissementStruct *bet_finance_get_echeance_first (LoanStruct *s_loan,
2209 													 GDate *first_date)
2210 {
2211 	gdouble taux_periodique;
2212 	AmortissementStruct *s_amortissement = NULL;
2213 
2214 	devel_debug (gsb_format_gdate (first_date));
2215 	taux_periodique = bet_data_finance_get_taux_periodique (s_loan->annual_rate, s_loan->type_taux);
2216 	s_amortissement = bet_data_finance_structure_amortissement_init ();
2217 	if (s_loan->first_is_different)
2218 	{
2219 		s_amortissement->echeance = s_loan->first_capital;
2220 		s_amortissement->echeance += s_loan->fees + s_loan->first_interests;
2221 		s_amortissement->interets = s_loan->first_interests;
2222 		s_amortissement->frais = s_loan->fees;
2223 		s_amortissement->principal = s_loan->first_capital;
2224 		s_loan->other_echeance_amount = bet_data_finance_get_echeance (s_loan->capital,
2225 																	   taux_periodique,
2226 																	   s_loan->duree);
2227 		s_loan->other_echeance_amount += s_loan->fees;
2228 	}
2229 	else
2230 	{
2231 		s_amortissement->echeance = bet_data_finance_get_echeance (s_loan->capital,
2232 																   taux_periodique,
2233 																   s_loan->duree);
2234 		s_amortissement->echeance += s_loan->fees;
2235 		s_amortissement->interets = bet_data_finance_get_interets (s_loan->capital_du,
2236 																   taux_periodique);
2237 		s_amortissement->frais = s_loan->fees;
2238 		s_amortissement->principal = bet_data_finance_get_principal (s_amortissement->echeance,
2239 																	 s_amortissement->interets,
2240 																	 s_amortissement->frais);
2241 		s_loan->other_echeance_amount = s_amortissement->echeance;
2242 	}
2243 
2244 	return s_amortissement;
2245 }
2246 
2247 /**
2248  *
2249  *
2250  * \param
2251  * \param
2252  *
2253  * \return
2254  **/
bet_finance_get_number_from_string(GtkWidget * parent,const gchar * name)2255 gdouble bet_finance_get_number_from_string (GtkWidget *parent,
2256 											const gchar *name)
2257 {
2258     GtkWidget *widget;
2259     gdouble number = 0;
2260 
2261     widget = g_object_get_data (G_OBJECT (parent), name);
2262 
2263     if (GTK_IS_SPIN_BUTTON  (widget))
2264     {
2265         number = gtk_spin_button_get_value (GTK_SPIN_BUTTON (widget));
2266     }
2267     else if (GTK_IS_ENTRY (widget))
2268     {
2269         const gchar *entry;
2270         gchar *tmp_str;
2271 
2272         entry = gtk_entry_get_text (GTK_ENTRY (widget));
2273 
2274         if (entry && strlen (entry) > 0)
2275         {
2276             number = utils_str_strtod (entry, NULL);
2277 
2278             tmp_str = utils_real_get_string_with_currency (gsb_real_double_to_real (number),
2279 														   etat.bet_currency,
2280 														   FALSE);
2281             gtk_entry_set_text (GTK_ENTRY (widget), tmp_str);
2282             g_free (tmp_str);
2283         }
2284     }
2285 
2286     return number;
2287 }
2288 
2289 /**
2290  *
2291  *
2292  * \param
2293  * \param
2294  * \param
2295  *
2296  * \return
2297  **/
bet_finance_update_amortization_tab_with_data(gint account_number,GtkWidget * parent,LoanStruct * s_loan)2298 void bet_finance_update_amortization_tab_with_data (gint account_number,
2299 													GtkWidget *parent,
2300 													LoanStruct *s_loan)
2301 {
2302     GtkWidget *label;
2303     GtkWidget *tree_view;
2304     GtkTreeModel *store;
2305     GtkTreeIter iter;
2306     GtkTreePath *path;
2307     GtkTreePath *sel_path;
2308 	gchar *str_capital_du = NULL;
2309     gchar *tmp_str;
2310     gint index = 0;
2311     gint nbre_echeances;
2312     gint type_taux;
2313     gdouble taux;
2314     gdouble taux_periodique;
2315     GDate *date;
2316     GDate *last_paid_date = NULL;
2317 	GDate *last_installment_paid = NULL;
2318 	gint index_last_installment_paid = 0;
2319     gboolean amortization_initial_date;
2320 	gboolean first_echeance = FALSE;
2321 	gint origin;
2322     AmortissementStruct *s_amortissement;
2323 
2324     devel_debug (NULL);
2325 
2326     s_amortissement = bet_data_finance_structure_amortissement_init ();
2327     s_amortissement->origin = SPP_ORIGIN_FINANCE;
2328 
2329     /* récupère le tableau d'amortissement */
2330     tree_view = g_object_get_data (G_OBJECT (parent), "bet_finance_tree_view");
2331 	origin = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tree_view), "origin"));
2332 	if (origin != SPP_ORIGIN_CONFIG)
2333 		bet_finance_ui_invers_cols_cap_ech_amortization (tree_view, s_loan->invers_cols_cap_ech);
2334 	amortization_initial_date = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tree_view),
2335 																	"amortization_initial_date"));
2336 
2337     /* remplit le tableau d'amortissement */
2338     store = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
2339     gtk_tree_store_clear (GTK_TREE_STORE (store));
2340 
2341     s_amortissement->devise = gsb_data_account_get_currency (account_number);
2342 
2343     /* récupère les paramètres du crédit */
2344     nbre_echeances = s_loan->duree;
2345 
2346 	date = gsb_date_copy (s_loan->first_date);
2347 	if (!date || !g_date_valid (date))
2348 		return;
2349 
2350 	s_amortissement->str_date = gsb_format_gdate (date);
2351 	if (strlen (s_amortissement->str_date) == 0)
2352 		return;
2353 
2354 	if (amortization_initial_date == FALSE)
2355 	{
2356 		last_paid_date = bet_data_finance_get_date_last_installment_paid (date);
2357 	/* set first line si necessaire */
2358 		if (s_loan->invers_cols_cap_ech)
2359 		{
2360 			str_capital_du = utils_real_get_string_with_currency (gsb_real_double_to_real (s_loan->capital),
2361 																  s_amortissement->devise,
2362 																  TRUE);
2363 
2364 			gtk_tree_store_append (GTK_TREE_STORE (store), &iter, NULL);
2365 			gtk_tree_store_set (GTK_TREE_STORE (store),
2366 								&iter,
2367 								BET_AMORTIZATION_NUMBER_COLUMN, 0,
2368 								BET_AMORTIZATION_DATE_COLUMN, "",
2369 								BET_AMORTIZATION_CAPITAL_DU_COLUMN, str_capital_du,
2370 								BET_AMORTIZATION_INTERETS_COLUMN, "",
2371 								BET_AMORTIZATION_PRINCIPAL_COLUMN, "",
2372 								BET_AMORTIZATION_FRAIS_COLUMN, "",
2373 								BET_AMORTIZATION_ECHEANCE_COLUMN, "",
2374 								- 1);
2375 			g_free (str_capital_du);
2376 		}
2377 	}
2378 	else
2379 	{
2380 		last_paid_date = gsb_date_copy (date);
2381 		last_installment_paid = bet_data_finance_get_date_last_installment_paid (date);
2382 		/* set first line si necessaire */
2383 		if (s_loan->invers_cols_cap_ech)
2384 		{
2385 			str_capital_du = utils_real_get_string_with_currency (gsb_real_double_to_real (s_loan->capital),
2386 																  s_amortissement->devise,
2387 																  TRUE);
2388 
2389 			gtk_tree_store_append (GTK_TREE_STORE (store), &iter, NULL);
2390 			gtk_tree_store_set (GTK_TREE_STORE (store),
2391 								&iter,
2392 								BET_AMORTIZATION_NUMBER_COLUMN, 0,
2393 								BET_AMORTIZATION_DATE_COLUMN, "",
2394 								BET_AMORTIZATION_CAPITAL_DU_COLUMN, str_capital_du,
2395 								BET_AMORTIZATION_INTERETS_COLUMN, "",
2396 								BET_AMORTIZATION_PRINCIPAL_COLUMN, "",
2397 								BET_AMORTIZATION_FRAIS_COLUMN, "",
2398 								BET_AMORTIZATION_ECHEANCE_COLUMN, "",
2399 								- 1);
2400 			g_free (str_capital_du);
2401 		}
2402 	}
2403 
2404     /* met à jour le titre du tableau */
2405     label = g_object_get_data (G_OBJECT (parent), "bet_finance_amortization_title");
2406     tmp_str = g_strconcat (_("Amortization Table"), _(" at "), gsb_format_gdate (last_paid_date), NULL);
2407     gtk_label_set_label (GTK_LABEL (label), tmp_str);
2408     g_free (tmp_str);
2409 
2410     /* set capital */
2411     s_amortissement->capital_du = s_loan->capital;
2412     label = g_object_get_data (G_OBJECT (parent), "bet_finance_capital");
2413     tmp_str = utils_real_get_string_with_currency (gsb_real_double_to_real (s_amortissement->capital_du),
2414 												   s_amortissement->devise, TRUE);
2415     gtk_label_set_label (GTK_LABEL (label), tmp_str);
2416     g_free (tmp_str);
2417 
2418     /* set taux */
2419     label = g_object_get_data (G_OBJECT (parent), "bet_finance_taux");
2420     taux = s_loan->annual_rate;
2421     type_taux = s_loan->type_taux;
2422     taux_periodique = bet_data_finance_get_taux_periodique (taux, type_taux);
2423     tmp_str = utils_str_dtostr (taux, BET_TAUX_DIGITS, FALSE);
2424     gtk_label_set_label (GTK_LABEL (label), tmp_str);
2425     g_free (tmp_str);
2426 
2427     /* set duration */
2428     label = g_object_get_data (G_OBJECT (parent), "bet_finance_duree");
2429     tmp_str = g_strconcat (utils_str_itoa (s_loan->duree), _(" months "), NULL);
2430     gtk_label_set_label (GTK_LABEL (label), tmp_str);
2431     g_free (tmp_str);
2432 
2433     /* set frais */
2434     s_amortissement->frais = s_loan->fees;
2435     s_amortissement->str_frais = utils_real_get_string_with_currency (
2436                         gsb_real_double_to_real (s_amortissement->frais),
2437                         s_amortissement->devise, TRUE);
2438 
2439 	/* set first echeance */
2440 	s_amortissement->num_echeance = 1;
2441 	if (s_loan->first_is_different)
2442 	{
2443 		s_amortissement->echeance = s_loan->first_capital;
2444 		s_amortissement->interets = s_loan->first_interests;
2445 		s_amortissement->echeance += s_amortissement->frais + s_amortissement->interets;
2446 		s_amortissement->str_echeance = utils_real_get_string_with_currency (gsb_real_double_to_real (s_amortissement->echeance),
2447 																			 s_amortissement->devise, TRUE);
2448 		s_amortissement->principal = bet_data_finance_get_principal (s_amortissement->echeance,
2449 																	 s_amortissement->interets,
2450 																	 s_amortissement->frais);
2451 
2452 		if (s_loan->invers_cols_cap_ech)
2453 		{
2454 			s_amortissement->capital_du -= s_amortissement->principal;
2455 			if (g_date_compare (date, last_paid_date) >= 0)
2456 				bet_finance_fill_amortization_ligne (store, s_amortissement);
2457 		}
2458 		else
2459 		{
2460 			if (g_date_compare (date, last_paid_date) >= 0)
2461 				bet_finance_fill_amortization_ligne (store, s_amortissement);
2462 			s_amortissement->capital_du -= s_amortissement->principal;
2463 		}
2464 
2465 		/* On recalcule la nouvelle échéance du crédit avec nouveau capital dû et nbre d'échéances -1 */
2466 		s_amortissement->echeance = bet_data_finance_get_echeance (s_amortissement->capital_du,
2467 																   taux_periodique, nbre_echeances-1);
2468 		s_amortissement->echeance += s_amortissement->frais;
2469 		s_amortissement->str_echeance = utils_real_get_string_with_currency (gsb_real_double_to_real (s_amortissement->echeance),
2470 																			 s_amortissement->devise, TRUE);
2471 	}
2472 	else
2473 	{
2474 		s_amortissement->echeance = bet_data_finance_get_echeance (s_amortissement->capital_du,
2475 																   taux_periodique, nbre_echeances);
2476 		s_amortissement->echeance += s_amortissement->frais;
2477 		s_amortissement->str_echeance = utils_real_get_string_with_currency (gsb_real_double_to_real (s_amortissement->echeance),
2478 																			 s_amortissement->devise, TRUE);
2479 		s_amortissement->interets = bet_data_finance_get_interets (s_amortissement->capital_du,
2480 																   taux_periodique);
2481 		s_amortissement->principal = bet_data_finance_get_principal (s_amortissement->echeance,
2482 																	 s_amortissement->interets,
2483 																	 s_amortissement->frais);
2484 		if (s_loan->invers_cols_cap_ech)
2485 		{
2486 			s_amortissement->capital_du -= s_amortissement->principal;
2487 			if (g_date_compare (date, last_paid_date) >= 0)
2488 				bet_finance_fill_amortization_ligne (store, s_amortissement);
2489 		}
2490 		else
2491 		{
2492 			if (g_date_compare (date, last_paid_date) >= 0)
2493 				bet_finance_fill_amortization_ligne (store, s_amortissement);
2494 			s_amortissement->capital_du -= s_amortissement->principal;
2495 		}
2496 	}
2497 
2498 	date = gsb_date_add_one_month (date, TRUE);
2499 	s_amortissement->str_date = gsb_format_gdate (date);
2500 
2501     /* set the other echeances */
2502 	for (index = 2; index <= nbre_echeances; index++)
2503     {
2504 		s_amortissement->num_echeance = index;
2505         s_amortissement->interets = bet_data_finance_get_interets (s_amortissement->capital_du,
2506 																   taux_periodique);
2507 
2508         if (index == nbre_echeances)
2509         {
2510             s_amortissement->echeance = bet_data_finance_get_last_echeance (
2511                         s_amortissement->capital_du,
2512                         s_amortissement->interets,
2513                         s_amortissement->frais);
2514             g_free (s_amortissement->str_echeance);
2515             s_amortissement->str_echeance = utils_real_get_string_with_currency (
2516                         gsb_real_double_to_real (s_amortissement->echeance),
2517                         s_amortissement-> devise, TRUE);
2518             s_amortissement->principal = s_amortissement->capital_du;
2519         }
2520         else
2521             s_amortissement->principal = bet_data_finance_get_principal (s_amortissement->echeance,
2522 																		 s_amortissement->interets,
2523 																		 s_amortissement->frais);
2524 
2525 		if (s_loan->invers_cols_cap_ech)
2526 		{
2527 			s_amortissement->capital_du -= s_amortissement->principal;
2528 			if (g_date_compare (date, last_paid_date) >= 0)
2529 				bet_finance_fill_amortization_ligne (store, s_amortissement);
2530 		}
2531 		else
2532 		{
2533 			if (g_date_compare (date, last_paid_date) >= 0)
2534 				bet_finance_fill_amortization_ligne (store, s_amortissement);
2535 			s_amortissement->capital_du -= s_amortissement->principal;
2536 		}
2537 		if (amortization_initial_date && !first_echeance)
2538 		{
2539 			if (g_date_compare (date, last_installment_paid) >= 0)
2540 			{
2541 				first_echeance = TRUE;
2542 				index_last_installment_paid = index;
2543 			}
2544 		}
2545 
2546         date = gsb_date_add_one_month (date, TRUE);
2547         s_amortissement->str_date = gsb_format_gdate (date);
2548 
2549 //~ if (index < 11)
2550 	//~ printf ("num_echeance = %d capital_du = %f, principal = %f interets = %f\n",
2551 			//~ s_amortissement->num_echeance, s_amortissement->capital_du, s_amortissement->principal, s_amortissement->interets);
2552     }
2553 
2554     bet_finance_struct_amortization_free (s_amortissement);
2555     g_date_free (date);
2556     g_date_free (last_paid_date);
2557 
2558     utils_set_tree_store_background_color (tree_view, BET_AMORTIZATION_BACKGROUND_COLOR);
2559 	path = gtk_tree_path_new_first ();
2560 	if (first_echeance)
2561 	{
2562 		tmp_str = g_strdup_printf ("%d", index_last_installment_paid-1);
2563 		sel_path = gtk_tree_path_new_from_string (tmp_str);
2564 		g_free (tmp_str);
2565 	}
2566 	else
2567 	{
2568 		sel_path = gtk_tree_path_new_first ();
2569 	}
2570 
2571     gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (tree_view), path, NULL, TRUE, 0.0, 0.0);
2572 	gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)), sel_path);
2573 
2574     gtk_tree_path_free (path);
2575 }
2576 
2577 /**
2578  *
2579  *
2580  * \param
2581  *
2582  * \return
2583  **/
2584 /* Local Variables: */
2585 /* c-basic-offset: 4 */
2586 /* End: */
2587