1 /* ************************************************************************** */
2 /*                                                                            */
3 /*                                                                            */
4 /*     Copyright (C)	2000-2008 Cédric Auger (cedric@grisbi.org)	          */
5 /*			2003-2008 Benjamin Drieu (bdrieu@april.org)             	      */
6 /* 			https://www.grisbi.org				                              */
7 /*                                                                            */
8 /*  This program is free software; you can redistribute it and/or modify      */
9 /*  it under the terms of the GNU General Public License as published by      */
10 /*  the Free Software Foundation; either version 2 of the License, or         */
11 /*  (at your option) any later version.                                       */
12 /*                                                                            */
13 /*  This program is distributed in the hope that it will be useful,           */
14 /*  but WITHOUT ANY WARRANTY; without even the implied warranty of            */
15 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             */
16 /*  GNU General Public License for more details.                              */
17 /*                                                                            */
18 /*  You should have received a copy of the GNU General Public License         */
19 /*  along with this program; if not, write to the Free Software               */
20 /*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
21 /*                                                                            */
22 /* ************************************************************************** */
23 
24 /**
25  * \file gsb_data_payee_data.c
26  * work with the payee structure, no GUI here
27  **/
28 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32 
33 #include "include.h"
34 #include <glib/gi18n.h>
35 
36 /*START_INCLUDE*/
37 #include "gsb_data_payee.h"
38 #include "grisbi_win.h"
39 #include "gsb_combo_box.h"
40 #include "gsb_data_form.h"
41 #include "gsb_data_report.h"
42 #include "gsb_data_scheduled.h"
43 #include "gsb_data_transaction.h"
44 #include "gsb_form_widget.h"
45 #include "gtk_combofix.h"
46 #include "tiers_onglet.h"
47 #include "gsb_real.h"
48 #include "utils_str.h"
49 #include "meta_payee.h"
50 #include "structures.h"
51 #include "erreur.h"
52 /*END_INCLUDE*/
53 
54 /**
55  * \struct
56  * Describe a payee
57  */
58 typedef struct _PayeeStruct	PayeeStruct;
59 
60 struct _PayeeStruct
61 {
62     gint 		payee_number;
63     gchar *		payee_name;
64     gchar *		payee_description;
65     gchar *		payee_search_string;
66 	gint		ignore_case;
67 	gint		use_regex;
68 
69     gint		payee_nb_transactions;
70     GsbReal		payee_balance;
71 };
72 
73 /*START_STATIC*/
74 /** contains the g_slist of PayeeStruct */
75 static GSList *payee_list = NULL;
76 
77 /** a pointer to the last payee used (to increase the speed) */
78 static PayeeStruct *payee_buffer = NULL;
79 
80 /** a pointer to a "blank" payee structure, used in the list of payee
81  * to group the transactions without payee */
82 static PayeeStruct *empty_payee = NULL;
83 /*END_STATIC*/
84 
85 /*START_EXTERN*/
86 /*END_EXTERN*/
87 
88 /******************************************************************************/
89 /* Private functions                                                          */
90 /******************************************************************************/
91 /**
92  * This internal function is called to free the memory used by a PayeeStruct structure
93  *
94  * \param
95  *
96  * \return
97  **/
_gsb_data_payee_free(PayeeStruct * payee)98 static void _gsb_data_payee_free (PayeeStruct* payee)
99 {
100     if (! payee)
101         return;
102     if (payee->payee_name)
103         g_free (payee->payee_name);
104     if (payee->payee_description)
105         g_free (payee->payee_description);
106     if (payee->payee_search_string)
107         g_free (payee->payee_search_string);
108     g_free (payee);
109     if (payee_buffer == payee)
110 		payee_buffer = NULL;
111 }
112 
113 /**
114  * compare deux structures payees par le numéro de tiers
115  *
116  * \param	structure 1
117  * \param	structure 1
118  *
119  * \return -1, 0 ou 1 en fonction du résultat de la comparaison.
120  **/
gsb_data_payee_get_pointer_in_gslist(PayeeStruct * payee1,PayeeStruct * payee2)121 static gint gsb_data_payee_get_pointer_in_gslist (PayeeStruct *payee1,
122 												  PayeeStruct *payee2)
123 {
124     return (payee1->payee_number - payee2->payee_number);
125 }
126 
127 /**
128  * return a g_slist of names of all the payees
129  * it's not a copy of the gchar...
130  *
131  * \param none
132  *
133  * \return a g_slist of gchar *
134  **/
gsb_data_payee_get_name_list(void)135 static GSList *gsb_data_payee_get_name_list (void)
136 {
137     GSList *return_list;
138     GSList *tmp_list;
139 	GrisbiWinEtat *w_etat;
140 
141 	w_etat = grisbi_win_get_w_etat ();
142 
143 	return_list = NULL;
144 	if (w_etat->metatree_unarchived_payees)
145 	{
146 		tmp_list = gsb_data_payee_get_unarchived_payees_list ();
147 	}
148 	else
149 	{
150 		tmp_list= payee_list;
151 	}
152 	while (tmp_list)
153 	{
154 		PayeeStruct *payee;
155 
156 		payee = tmp_list->data;
157 
158 		if (payee->payee_name)
159 			return_list = g_slist_append (return_list, payee->payee_name);
160 
161 		tmp_list = tmp_list->next;
162 	}
163 	return_list = g_slist_sort (return_list, (GCompareFunc) my_strcasecmp);
164 
165 	return return_list;
166 }
167 
168 /**
169  * used with g_slist_find_custom to find a payee in the g_list
170  * by his name
171  *
172  * \param payee the struct of the current payee checked
173  * \param name the name we are looking for
174  *
175  * \return 0 if it's the same name
176  **/
gsb_data_payee_get_pointer_from_name_in_glist(PayeeStruct * payee,const gchar * name)177 static gint gsb_data_payee_get_pointer_from_name_in_glist (PayeeStruct *payee,
178 														   const gchar *name)
179 {
180     return (my_strcasecmp (payee->payee_name, name));
181 }
182 
183 /** find and return the last number of payee
184  *
185  * \param none
186  *
187  * \return last number of payee
188  **/
gsb_data_payee_max_number(void)189 static gint gsb_data_payee_max_number (void)
190 {
191     GSList *tmp;
192     gint number_tmp = 0;
193 
194     tmp = payee_list;
195     while (tmp)
196     {
197 		PayeeStruct *payee;
198 
199 		payee = tmp->data;
200 
201 		if (payee->payee_number > number_tmp)
202 			number_tmp = payee->payee_number;
203 
204 		tmp = tmp->next;
205     }
206     return number_tmp;
207 }
208 
209 /**
210  * reset the counters of the payees
211  *
212  * \param
213  *
214  * \return
215  **/
gsb_data_payee_reset_counters(void)216 static void gsb_data_payee_reset_counters (void)
217 {
218     GSList *list_tmp;
219 
220     list_tmp = payee_list;
221     while (list_tmp)
222     {
223 		PayeeStruct *payee;
224 
225 		payee = list_tmp->data;
226 		payee->payee_balance = null_real;
227 		payee->payee_nb_transactions = 0;
228 
229 		list_tmp = list_tmp->next;
230     }
231 
232     /* reset the blank payee counters */
233 
234     empty_payee->payee_balance = null_real;
235     empty_payee->payee_nb_transactions = 0;
236 }
237 
238 /******************************************************************************/
239 /* Public functions                                                           */
240 /******************************************************************************/
241 /**
242  * set the payees global variables to NULL, usually when we init all the global variables
243  *
244  * \param none
245  *
246  * \return FALSE
247  **/
gsb_data_payee_init_variables(gboolean cleanup)248 gboolean gsb_data_payee_init_variables (gboolean cleanup)
249 {
250     /* free the memory used by the actual list */
251     GSList *tmp_list;
252 
253 	tmp_list = payee_list;
254     while (tmp_list)
255     {
256 		PayeeStruct *payee;
257 		payee = tmp_list->data;
258 		tmp_list = tmp_list->next;
259 		_gsb_data_payee_free (payee);
260     }
261     g_slist_free (payee_list);
262 	if (cleanup)
263 	{
264 		payee_list = NULL;
265 		payee_buffer = NULL;
266 
267 		/* create the blank payee */
268 		if (empty_payee)
269 		{
270 			g_free (empty_payee->payee_name);
271 			g_free (empty_payee);
272 		}
273 		empty_payee = g_malloc0 (sizeof (PayeeStruct));
274 		empty_payee->payee_name = g_strdup(_("No payee"));
275 	}
276 
277 	return FALSE;
278 }
279 
280 /**
281  * find and return the structure of the payee asked
282  *
283  * \param no_payee number of payee
284  *
285  * \return the adr of the struct of the payee (NULL if doesn't exit)
286  **/
gsb_data_payee_get_structure(gint no_payee)287 gpointer gsb_data_payee_get_structure (gint no_payee)
288 {
289     GSList *tmp;
290 
291     if (!no_payee)
292 		return empty_payee;
293 
294     /* before checking all the payees, we check the buffer */
295     if (payee_buffer && payee_buffer->payee_number == no_payee)
296 		return payee_buffer;
297 
298     tmp = payee_list;
299     while (tmp)
300     {
301 		PayeeStruct *payee;
302 
303 		payee = tmp->data;
304 		if (payee->payee_number == no_payee)
305 		{
306 			payee_buffer = payee;
307 			return payee;
308 		}
309 
310 		tmp = tmp->next;
311     }
312     return NULL;
313 }
314 
315 /**
316  * return the empty_payee pointer
317  *
318  * \param
319  *
320  * \return a pointer to empty_category */
gsb_data_payee_get_empty_payee(void)321 gpointer gsb_data_payee_get_empty_payee (void)
322 {
323     return gsb_data_payee_get_structure (0);
324 }
325 
326 /**
327  * give the g_slist of payees structure
328  * usefull when want to check all payees
329  *
330  * \param none
331  *
332  * \return the g_slist of payees structure
333  **/
gsb_data_payee_get_payees_list(void)334 GSList *gsb_data_payee_get_payees_list (void)
335 {
336     return payee_list;
337 }
338 
339 /**
340  * return the number of the payees given in param
341  *
342  * \param payee_ptr a pointer to the struct of the payee
343  *
344  * \return the number of the payee, 0 if problem
345  **/
gsb_data_payee_get_no_payee(gpointer payee_ptr)346 gint gsb_data_payee_get_no_payee (gpointer payee_ptr)
347 {
348     PayeeStruct *payee;
349 
350     if (!payee_ptr)
351 		return 0;
352 
353     payee = payee_ptr;
354     payee_buffer = payee;
355     return payee->payee_number;
356 }
357 
358 
359 
360 /**
361  * create a new payee, give him a number, append it to the list
362  * and return the number
363  *
364  * \param name the name of the payee (can be freed after, it's a copy) or NULL
365  *
366  * \return the number of the new payee
367  **/
gsb_data_payee_new(const gchar * name)368 gint gsb_data_payee_new (const gchar *name)
369 {
370     PayeeStruct *payee;
371 
372     payee = g_malloc0 (sizeof (PayeeStruct));
373     payee->payee_number = gsb_data_payee_max_number () + 1;
374 
375     if (name)
376     {
377         GtkWidget *combofix;
378 
379         payee->payee_name = my_strdup (name);
380         combofix = gsb_form_widget_get_widget (TRANSACTION_FORM_PARTY);
381 
382         if (combofix && name)
383             gtk_combofix_append_text (GTK_COMBOFIX (combofix), name);
384     }
385     else
386         payee->payee_name = NULL;
387 
388     payee_list = g_slist_append (payee_list, payee);
389 
390     return payee->payee_number;
391 }
392 
393 /**
394  * remove a payee
395  * set all the payees of transaction which are this one to 0
396  * update combofix and mark file as modified
397  *
398  * \param no_payee the payee we want to remove
399  *
400  * \return TRUE ok
401  **/
gsb_data_payee_remove(gint no_payee)402 gboolean gsb_data_payee_remove (gint no_payee)
403 {
404     PayeeStruct *payee;
405     GtkWidget *combofix;
406 
407     payee = gsb_data_payee_get_structure (no_payee);
408 
409     if (!payee)
410         return FALSE;
411 
412     combofix = gsb_form_widget_get_widget (TRANSACTION_FORM_PARTY);
413     if (combofix)
414         gtk_combofix_remove_text (GTK_COMBOFIX (combofix), payee->payee_name);
415 
416     payee_list = g_slist_remove (payee_list, payee);
417     _gsb_data_payee_free (payee);
418 
419     return TRUE;
420 }
421 
422 /**
423  * set a new number for the payee
424  * normally used only while loading the file because
425  * the number are given automaticly
426  *
427  * \param no_payee the number of the payee
428  * \param new_no_payee the new number of the payee
429  *
430  * \return the new number or 0 if the payee doen't exist
431  **/
gsb_data_payee_set_new_number(gint no_payee,gint new_no_payee)432 gint gsb_data_payee_set_new_number (gint no_payee,
433 									gint new_no_payee)
434 {
435     PayeeStruct *payee;
436 
437     payee = gsb_data_payee_get_structure (no_payee);
438 
439     if (!payee)
440 		return 0;
441 
442     payee->payee_number = new_no_payee;
443     return new_no_payee;
444 }
445 
446 /**
447  * return the number of the payee which has the name in param
448  * create it if necessary
449  *
450  * \param name the name of the payee
451  * \param create TRUE if we want to create it if it doen't exist
452  *
453  * \return the number of the payee or 0 if problem
454  **/
gsb_data_payee_get_number_by_name(const gchar * name,gboolean create)455 gint gsb_data_payee_get_number_by_name (const gchar *name,
456 										gboolean create)
457 {
458     GSList *list_tmp;
459     gint payee_number = 0;
460 
461     list_tmp = g_slist_find_custom (payee_list,
462 									name,
463 									(GCompareFunc) gsb_data_payee_get_pointer_from_name_in_glist);
464     if (list_tmp)
465     {
466         PayeeStruct *payee;
467 
468         payee = list_tmp->data;
469         payee_number = payee->payee_number;
470     }
471     else
472     {
473         if (create)
474         {
475             payee_number = gsb_data_payee_new (name);
476         }
477     }
478     return payee_number;
479 }
480 
481 /**
482  * return the name of the payee
483  *
484  * \param no_payee the number of the payee
485  * \param can_return_null if problem, return NULL if TRUE or "No payee" if FALSE
486  *
487  * \return the name of the payee or NULL/No payee if problem
488  **/
gsb_data_payee_get_name(gint no_payee,gboolean can_return_null)489 const gchar *gsb_data_payee_get_name (gint no_payee,
490 									  gboolean can_return_null)
491 {
492     PayeeStruct *payee;
493 
494     payee = gsb_data_payee_get_structure (no_payee);
495 
496     if (!payee || !no_payee)
497     {
498 		if (can_return_null)
499 			return NULL;
500 		else
501 			return (_("No payee defined"));
502     }
503 
504     return payee->payee_name;
505 }
506 
507 /**
508  * set the name of the payee
509  * the value is dupplicate in memory
510  *
511  * \param no_payee the number of the payee
512  * \param name the name of the payee
513  *
514  * \return TRUE if ok or FALSE if problem
515  **/
gsb_data_payee_set_name(gint no_payee,const gchar * name)516 gboolean gsb_data_payee_set_name (gint no_payee,
517 								  const gchar *name)
518 {
519     PayeeStruct *payee;
520     GtkWidget *combofix;
521 
522     payee = gsb_data_payee_get_structure (no_payee);
523 
524     if (!payee)
525         return FALSE;
526 
527     combofix = gsb_form_widget_get_widget (TRANSACTION_FORM_PARTY);
528 
529     /* we free the last name */
530     if (payee->payee_name)
531     {
532 		if (combofix)
533 			gtk_combofix_remove_text (GTK_COMBOFIX (combofix), payee->payee_name);
534 		g_free (payee->payee_name);
535     }
536 
537     /* and copy the new one or set NULL */
538     payee->payee_name = my_strdup (name);
539 
540     if (combofix && name && strlen (name))
541         gtk_combofix_append_text (GTK_COMBOFIX (combofix), name);
542 
543     return TRUE;
544 }
545 
546 /**
547  * compare the name of the payee
548  *
549  * \param payee_ptr_a a pointer a pointer to the struct of the payee a
550  * \param payee_ptr_b a pointer a pointer to the struct of the payee b
551  *
552  * \return a > b or NULL if problem
553  **/
gsb_data_payee_compare_payees_by_name(gpointer payee_ptr_a,gpointer payee_ptr_b)554 gboolean gsb_data_payee_compare_payees_by_name (gpointer payee_ptr_a,
555                                                 gpointer payee_ptr_b)
556 {
557     PayeeStruct *payee_a;
558     PayeeStruct *payee_b;
559     gchar *name_a;
560     gchar *name_b;
561 
562 	if (!payee_ptr_a || !payee_ptr_b)
563 		return 0;
564 
565     payee_a = payee_ptr_a;
566     payee_b = payee_ptr_b;
567     name_a = payee_a->payee_name;
568     name_b = payee_b->payee_name;
569     return g_utf8_collate (name_a, name_b);
570 }
571 
572 /**
573  * return a g_slist of names of all the payees and
574  * the name of the reports which have to be with the payees
575  * it's not a copy of the gchar...
576  *
577  * \param none
578  *
579  * \return a g_slist of gchar *
580  **/
gsb_data_payee_get_name_and_report_list(void)581 GSList *gsb_data_payee_get_name_and_report_list (void)
582 {
583     GSList *return_list = NULL;
584     GSList *tmp_list;
585     GSList *pointer;
586 
587     /* for the transactions list, it's a complex type of list, so a g_slist
588      * which contains some g_slist of names of payees, one of the 2 g_slist
589      * is the selected reports names */
590 
591     tmp_list= gsb_data_payee_get_name_list ();
592     return_list = g_slist_append (return_list, tmp_list);
593 
594     /* we append the selected reports */
595     tmp_list = NULL;
596     pointer = gsb_data_report_get_report_list ();
597     while (pointer)
598     {
599 		gint report_number;
600 
601 		report_number = gsb_data_report_get_report_number (pointer->data);
602 
603 		if (gsb_data_report_get_append_in_payee (report_number))
604 		{
605 			gchar *tmp_str;
606 
607 			tmp_str = my_strdup (gsb_data_report_get_report_name (report_number));
608 			if (tmp_list)
609 				tmp_list = g_slist_append (tmp_list, g_strconcat ("\t", tmp_str, NULL));
610 			else
611 			{
612 				tmp_list = g_slist_append (tmp_list, g_strdup (_("Report")));
613 				tmp_list = g_slist_append (tmp_list, g_strconcat ("\t", tmp_str, NULL));
614 			}
615 			g_free (tmp_str);
616 		}
617 		pointer = pointer->next;
618     }
619 
620     if (tmp_list)
621         return_list = g_slist_append (return_list, tmp_list);
622 
623     return return_list;
624 }
625 
626 /**
627  *
628  *
629  * \param
630  *
631  * \return
632  **/
gsb_data_payee_free_name_and_report_list(GSList * liste)633 void gsb_data_payee_free_name_and_report_list (GSList *liste)
634 {
635     if (g_slist_length (liste) == 2)
636     {
637         GSList *tmp_list;
638 
639         tmp_list = g_slist_nth_data (liste, 1);
640         g_slist_free_full (tmp_list, (GDestroyNotify) g_free);
641     }
642     g_slist_free (liste->data);
643     g_slist_free (liste);
644 }
645 
646 /**
647  * return the description of the payee
648  *
649  * \param no_payee the number of the payee
650  *
651  * \return the description of the payee or NULL if problem
652  **/
gsb_data_payee_get_description(gint no_payee)653 const gchar *gsb_data_payee_get_description (gint no_payee)
654 {
655     PayeeStruct *payee;
656 
657     payee = gsb_data_payee_get_structure (no_payee);
658 
659     if (!payee)
660 		return NULL;
661 
662     return payee->payee_description;
663 }
664 
665 /**
666  * set the description of the payee
667  * the value is dupplicate in memory
668  *
669  * \param no_payee the number of the payee
670  * \param description the description of the payee
671  *
672  * \return TRUE if ok or FALSE if problem
673  **/
gsb_data_payee_set_description(gint no_payee,const gchar * description)674 gboolean gsb_data_payee_set_description (gint no_payee,
675 										 const gchar *description)
676 {
677     PayeeStruct *payee;
678 
679     payee = gsb_data_payee_get_structure (no_payee);
680 
681     if (!payee)
682 		return FALSE;
683 
684     /* we free the last name */
685     if (payee->payee_description)
686 		g_free (payee->payee_description);
687 
688     /* and copy the new one */
689     if (description)
690 		payee->payee_description = my_strdup (description);
691     else
692 		payee->payee_description = NULL;
693 
694     return TRUE;
695 }
696 
697 /**
698  * return nb_transactions of the payee
699  *
700  * \param no_payee the number of the payee
701  *
702  * \return nb_transactions of the payee or 0 if problem
703  **/
gsb_data_payee_get_nb_transactions(gint no_payee)704 gint gsb_data_payee_get_nb_transactions (gint no_payee)
705 {
706     PayeeStruct *payee;
707 
708     payee = gsb_data_payee_get_structure (no_payee);
709 
710     if (!payee)
711 		return 0;
712 
713     return payee->payee_nb_transactions;
714 }
715 
716 /**
717  * return balance of the payee
718  *
719  * \param no_payee the number of the payee
720  *
721  * \return balance of the payee or 0 if problem
722  **/
gsb_data_payee_get_balance(gint no_payee)723 GsbReal gsb_data_payee_get_balance (gint no_payee)
724 {
725     PayeeStruct *payee;
726 
727     payee = gsb_data_payee_get_structure (no_payee);
728 
729     if (!payee)
730 		return null_real;
731 
732     return payee->payee_balance;
733 }
734 
735 /**
736  * update the counters of the payees
737  *
738  * \param
739  *
740  * \return
741  **/
gsb_data_payee_update_counters(void)742 void gsb_data_payee_update_counters (void)
743 {
744     GSList *list_tmp_transactions;
745 	GrisbiWinEtat *w_etat;
746 
747 	w_etat = grisbi_win_get_w_etat ();
748 	gsb_data_payee_reset_counters ();
749 
750     if (w_etat->metatree_add_archive_in_totals)
751         list_tmp_transactions = gsb_data_transaction_get_complete_transactions_list ();
752     else
753         list_tmp_transactions = gsb_data_transaction_get_transactions_list ();
754 
755     while (list_tmp_transactions)
756     {
757 		gint transaction_number_tmp;
758 
759 		transaction_number_tmp = gsb_data_transaction_get_transaction_number (list_tmp_transactions->data);
760 		gsb_data_payee_add_transaction_to_payee (transaction_number_tmp);
761 
762 		list_tmp_transactions = list_tmp_transactions->next;
763     }
764 }
765 
766 /**
767  * add the given transaction to its payee in the counters
768  * if the transaction has no payee, add it to the blank payee
769  *
770  * \param transaction_number the transaction we want to work with
771  *
772  * \return
773  **/
gsb_data_payee_add_transaction_to_payee(gint transaction_number)774 void gsb_data_payee_add_transaction_to_payee (gint transaction_number)
775 {
776     PayeeStruct *payee;
777 	gint contra_number;
778 
779 	/* if the transaction is a split transaction or a contra transaction don't take it */
780 	if (gsb_data_transaction_get_mother_transaction_number (transaction_number))
781 	{
782 		return;
783 	}
784 	else if ((contra_number = gsb_data_transaction_get_contra_transaction_number (transaction_number)) > 0)
785 	{
786 		gint tmp_number;
787 
788 		tmp_number = gsb_data_transaction_get_contra_transaction_number (contra_number);
789 		if (tmp_number > contra_number)
790 			return;
791 	}
792 
793 	/* if no payee in that transaction and it's neither a split transaction, we work with empty_payee */
794     payee = gsb_data_payee_get_structure (gsb_data_transaction_get_party_number (transaction_number));
795 
796     /* should not happen, this is if the transaction has a payee which doesn't exists
797      * we show a debug warning and get without payee */
798     if (!payee)
799     {
800         gchar *tmpstr;
801 
802         tmpstr = g_strdup_printf ("The transaction %d has a payee %d but it doesn't exist.",
803 								  transaction_number,
804 								  gsb_data_transaction_get_party_number (transaction_number));
805         warning_debug (tmpstr);
806         g_free (tmpstr);
807         payee = empty_payee;
808     }
809 
810     payee->payee_nb_transactions ++;
811 	payee->payee_balance = gsb_real_add (payee->payee_balance,
812 										 gsb_data_transaction_get_adjusted_amount_for_currency
813 										 (transaction_number, payee_tree_currency (),
814 										  -1));
815 }
816 
817 /**
818  * remove the given transaction to its payee in the counters
819  * if the transaction has no payee, remove it to the blank payee
820  *
821  * \param transaction_number the transaction we want to work with
822  *
823  * \return
824  **/
gsb_data_payee_remove_transaction_from_payee(gint transaction_number)825 void gsb_data_payee_remove_transaction_from_payee (gint transaction_number)
826 {
827     PayeeStruct *payee;
828 
829     payee = gsb_data_payee_get_structure (gsb_data_transaction_get_party_number (transaction_number));
830 
831     /* if no payee in that transaction, and it's neither a split, neither a transfer,
832      * we work with empty_payee */
833 
834     if (!payee
835 		&& !gsb_data_transaction_get_split_of_transaction (transaction_number)
836 		&& gsb_data_transaction_get_contra_transaction_number (transaction_number) == 0)
837 	{
838         payee = empty_payee;
839 	}
840 
841     if (payee)
842     {
843         payee->payee_nb_transactions --;
844         payee->payee_balance = gsb_real_sub (payee->payee_balance,
845 											 gsb_data_transaction_get_adjusted_amount_for_currency (transaction_number,
846 																									payee_tree_currency (),
847 																									-1));
848 
849         if (!payee->payee_nb_transactions) /* Cope with float errors */
850             payee->payee_balance = null_real;
851     }
852 }
853 
854 /**
855  * remove all the payees which are not used
856  *
857  * \param button	the toolbar button
858  * \param null
859  *
860  * \return the number of payees removed
861  **/
gsb_data_payee_remove_unused(void)862 gint gsb_data_payee_remove_unused (void)
863 {
864     GSList *tmp_list;
865     GSList *used = NULL;
866     gint nb_removed = 0;
867 
868 	/* first we create a list of used categories */
869     tmp_list = gsb_data_transaction_get_complete_transactions_list ();
870     while (tmp_list)
871     {
872         gint payee_number;
873 		gint transaction_number;
874 
875 		transaction_number = gsb_data_transaction_get_transaction_number (tmp_list->data);
876         payee_number = gsb_data_transaction_get_party_number (transaction_number);
877         if (!g_slist_find (used, GINT_TO_POINTER (payee_number)))
878         {
879             used = g_slist_append (used, GINT_TO_POINTER (payee_number));
880         }
881         tmp_list = tmp_list->next;
882     }
883 
884     /* it also scans the list of sheduled transactions. fix bug 538 */
885     tmp_list = gsb_data_scheduled_get_scheduled_list ();
886     while (tmp_list)
887     {
888         gint payee_number;
889 		gint scheduled_number;
890 
891 		scheduled_number = gsb_data_scheduled_get_scheduled_number (tmp_list->data);
892         payee_number = gsb_data_scheduled_get_party_number (scheduled_number);
893         if (!g_slist_find (used, GINT_TO_POINTER (payee_number)))
894         {
895             used = g_slist_append (used, GINT_TO_POINTER (payee_number));
896         }
897         tmp_list = tmp_list->next;
898     }
899 
900     /* now check each payee to know if it is used */
901     tmp_list = gsb_data_payee_get_payees_list ();
902     while (tmp_list)
903     {
904         PayeeStruct *payee = tmp_list->data;
905 
906         tmp_list = tmp_list->next;
907         if (!used || !g_slist_find (used, GINT_TO_POINTER (payee->payee_number)))
908         {
909             /* payee not used */
910             payee_buffer = payee;	/* increase speed */
911             gsb_data_payee_remove (payee->payee_number);
912             nb_removed++;
913         }
914     }
915 
916 	return nb_removed;
917 }
918 
919 /**
920  *
921  *
922  * \param
923  *
924  * \return search string or an empty string if search string is NULL
925  **/
gsb_data_payee_get_search_string(gint no_payee)926 const gchar *gsb_data_payee_get_search_string (gint no_payee)
927 {
928     PayeeStruct *payee;
929 
930     payee = gsb_data_payee_get_structure (no_payee);
931 
932     if (!payee)
933         return "";
934 
935     if (payee->payee_search_string && strlen (payee->payee_search_string))
936         return payee->payee_search_string;
937     else
938         return "";
939 }
940 
941 /**
942  *
943  *
944  * \param
945  *
946  * \return
947  **/
gsb_data_payee_set_search_string(gint no_payee,const gchar * search_string)948 gboolean gsb_data_payee_set_search_string (gint no_payee, const gchar *search_string)
949 {
950     PayeeStruct *payee;
951 
952     payee = gsb_data_payee_get_structure (no_payee);
953 
954     if (!payee)
955         return FALSE;
956 
957     /* we free the last name */
958     if (payee->payee_search_string)
959         g_free (payee->payee_search_string);
960 
961     /* and copy the new one */
962     if (search_string)
963         payee->payee_search_string = my_strdup (search_string);
964     else
965         payee->payee_search_string = NULL;
966 
967     return TRUE;
968 }
969 
970 /**
971  * renvoie le nombre de tiers non utilisé (fonction à revoir)
972  *
973  * \param
974  *
975  * \return nb_unused
976  **/
gsb_data_payee_get_unused_payees(void)977 gint gsb_data_payee_get_unused_payees (void)
978 {
979     GSList *tmp_list;
980     GSList *used = NULL;
981     gint nb_unused = 0;
982 	GrisbiWinEtat *w_etat;
983 
984 	w_etat = grisbi_win_get_w_etat ();
985 
986     /* on tient compte de toutes les opérations : méthode courte*/
987     if (w_etat->metatree_add_archive_in_totals)
988     {
989         /* it scans the list of sheduled transactions. fix bug 538 */
990         tmp_list = gsb_data_scheduled_get_scheduled_list ();
991         while (tmp_list)
992         {
993             gint payee_number;
994 
995             payee_number = gsb_data_scheduled_get_party_number (
996                                 gsb_data_scheduled_get_scheduled_number (
997                                 tmp_list->data));
998             if (!g_slist_find (used, GINT_TO_POINTER (payee_number)))
999             {
1000                 used = g_slist_append (used, GINT_TO_POINTER (payee_number));
1001             }
1002             tmp_list = tmp_list->next;
1003         }
1004 
1005         /* now check each payee to know if it is used */
1006         tmp_list = gsb_data_payee_get_payees_list ();
1007         while (tmp_list)
1008         {
1009             PayeeStruct *payee = tmp_list->data;
1010 
1011             tmp_list = tmp_list->next;
1012 
1013             if (payee->payee_nb_transactions == 0
1014              &&
1015              (!used
1016               ||
1017               !g_slist_find (used, GINT_TO_POINTER (payee->payee_number))))
1018             {
1019                 /* payee not used */
1020                 nb_unused++;
1021             }
1022         }
1023 
1024         return nb_unused;
1025     }
1026 
1027     /* méthode longue */
1028     /* first we create a list of used payees */
1029     tmp_list = gsb_data_transaction_get_complete_transactions_list ();
1030     while (tmp_list)
1031     {
1032         gint payee_number;
1033 
1034         payee_number = gsb_data_transaction_get_party_number (
1035                     gsb_data_transaction_get_transaction_number (tmp_list->data));
1036         if (!g_slist_find (used, GINT_TO_POINTER (payee_number)))
1037         {
1038             used = g_slist_append (used, GINT_TO_POINTER (payee_number));
1039         }
1040         tmp_list = tmp_list->next;
1041     }
1042 
1043     /* it also scans the list of sheduled transactions. fix bug 538 */
1044     tmp_list = gsb_data_scheduled_get_scheduled_list ();
1045     while (tmp_list)
1046     {
1047         gint payee_number;
1048 
1049         payee_number = gsb_data_scheduled_get_party_number (
1050                         gsb_data_scheduled_get_scheduled_number (
1051                         tmp_list->data));
1052         if (!g_slist_find (used, GINT_TO_POINTER (payee_number)))
1053         {
1054             used = g_slist_append (used, GINT_TO_POINTER (payee_number));
1055         }
1056         tmp_list = tmp_list->next;
1057     }
1058 
1059     /* now check each payee to know if it is used */
1060     tmp_list = gsb_data_payee_get_payees_list ();
1061     while (tmp_list)
1062     {
1063         PayeeStruct *payee = tmp_list->data;
1064 
1065         tmp_list = tmp_list->next;
1066         if (!used || !g_slist_find (used, GINT_TO_POINTER (payee->payee_number)))
1067         {
1068             /* payee not used */
1069             nb_unused++;
1070         }
1071     }
1072     return nb_unused;
1073 }
1074 
1075 /**
1076  *
1077  *
1078  * \param
1079  *
1080  * \return
1081  **/
gsb_data_payee_get_ignore_case(gint no_payee)1082 gint gsb_data_payee_get_ignore_case (gint no_payee)
1083 {
1084     PayeeStruct *payee;
1085 
1086     payee = gsb_data_payee_get_structure (no_payee);
1087 
1088     if (!payee)
1089 		return 0;
1090 
1091     return payee->ignore_case;
1092 }
1093 
1094 /**
1095  *
1096  *
1097  * \param
1098  *
1099  * \return
1100  **/
gsb_data_payee_set_ignore_case(gint no_payee,gint ignore_case)1101 gboolean gsb_data_payee_set_ignore_case (gint no_payee,
1102 										 gint ignore_case)
1103 {
1104     PayeeStruct *payee;
1105 
1106     payee = gsb_data_payee_get_structure (no_payee);
1107 
1108     if (!payee)
1109 		return FALSE;
1110 
1111     payee->ignore_case = ignore_case;
1112 
1113 	return TRUE;
1114 }
1115 
1116 /**
1117  *
1118  *
1119  * \param
1120  *
1121  * \return
1122  **/
gsb_data_payee_get_use_regex(gint no_payee)1123 gint gsb_data_payee_get_use_regex (gint no_payee)
1124 {
1125     PayeeStruct *payee;
1126 
1127     payee = gsb_data_payee_get_structure (no_payee);
1128 
1129     if (!payee)
1130 		return 0;
1131 
1132     return payee->use_regex;
1133 }
1134 
1135 /**
1136  *
1137  *
1138  * \param
1139  *
1140  * \return
1141  **/
gsb_data_payee_set_use_regex(gint no_payee,gint use_regex)1142 gboolean gsb_data_payee_set_use_regex (gint no_payee,
1143 									   gint use_regex)
1144 {
1145     PayeeStruct *payee;
1146 
1147     payee = gsb_data_payee_get_structure (no_payee);
1148 
1149     if (!payee)
1150 		return FALSE;
1151 
1152     payee->use_regex = use_regex;
1153 
1154 	return TRUE;
1155 }
1156 
1157 /**
1158  * retourne la liste des tiers utilisés par les transactions.
1159  * Limite le nombre de tiers dans les gtkcombofix pour accelérer
1160  * l'affichage.
1161  *
1162  * \param
1163  *
1164  * \return
1165  **/
gsb_data_payee_get_unarchived_payees_list(void)1166 GSList *gsb_data_payee_get_unarchived_payees_list (void)
1167 {
1168 	GSList *tmp_list;
1169 	GSList *payees_list = NULL;
1170 	GSList *transactions_list;
1171 
1172 	transactions_list = gsb_data_transaction_get_transactions_list ();
1173 	while (transactions_list)
1174 	{
1175 		gint transaction_number;
1176 		gint payee_number;
1177 		PayeeStruct *payee;
1178 
1179 		transaction_number = gsb_data_transaction_get_transaction_number (transactions_list->data);
1180 		payee_number = gsb_data_transaction_get_party_number (transaction_number);
1181 		payee = gsb_data_payee_get_structure (payee_number);
1182 
1183 		if (payee)
1184 		{
1185 			tmp_list = g_slist_find_custom (payees_list,
1186 											payee,
1187 											(GCompareFunc) gsb_data_payee_get_pointer_in_gslist);
1188 			if (!tmp_list)
1189 			{
1190 				payees_list = g_slist_append (payees_list, payee);
1191 			}
1192 		}
1193 		transactions_list = transactions_list->next;
1194 	}
1195 	return payees_list;
1196 }
1197 
1198 /**
1199  *
1200  *
1201  * \param
1202  *
1203  * \return
1204  **/
1205 /* Local Variables: */
1206 /* c-basic-offset: 4 */
1207 /* End: */
1208