1 /* ************************************************************************** */
2 /*                                                                            */
3 /*     Copyright (C)    2000-2008 Cédric Auger (cedric@grisbi.org)            */
4 /*          2003-2008 Benjamin Drieu (bdrieu@april.org)                       */
5 /*          https://www.grisbi.org/                                           */
6 /*                                                                            */
7 /*  This program is free software; you can redistribute it and/or modify      */
8 /*  it under the terms of the GNU General Public License as published by      */
9 /*  the Free Software Foundation; either version 2 of the License, or         */
10 /*  (at your option) any later version.                                       */
11 /*                                                                            */
12 /*  This program is distributed in the hope that it will be useful,           */
13 /*  but WITHOUT ANY WARRANTY; without even the implied warranty of            */
14 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             */
15 /*  GNU General Public License for more details.                              */
16 /*                                                                            */
17 /*  You should have received a copy of the GNU General Public License         */
18 /*  along with this program; if not, write to the Free Software               */
19 /*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
20 /*                                                                            */
21 /* ************************************************************************** */
22 
23 /**
24  * \file gsb_transaction_data.c
25  * work with the transaction structure, no GUI here
26  */
27 
28 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32 
33 #include "include.h"
34 #include <glib/gi18n.h>
35 #include <errno.h>
36 
37 /*START_INCLUDE*/
38 #include "gsb_data_transaction.h"
39 #include "bet_data.h"
40 #include "classement_echeances.h"
41 #include "dialog.h"
42 #include "grisbi_win.h"
43 #include "gsb_currency.h"
44 #include "gsb_data_account.h"
45 #include "gsb_data_budget.h"
46 #include "gsb_data_category.h"
47 #include "gsb_data_currency.h"
48 #include "gsb_data_currency_link.h"
49 #include "gsb_data_payee.h"
50 #include "gsb_data_payment.h"
51 #include "gsb_file.h"
52 #include "gsb_real.h"
53 #include "gsb_transactions_list.h"
54 #include "gsb_transactions_list_sort.h"
55 #include "structures.h"
56 #include "utils_dates.h"
57 #include "utils_str.h"
58 #include "erreur.h"
59 /*END_INCLUDE*/
60 
61 
62 /**
63  * \struct
64  * Describe a transaction
65  */
66 struct _TransactionStruct
67 {
68     /** @name general stuff */
69     gint transaction_number;
70     gchar *transaction_id;              /**< filled by ofx */
71     gint account_number;
72     GsbReal transaction_amount;
73     gint party_number;                  /* payee in transaction */
74     gchar *notes;
75     gint marked_transaction;            /**<  OPERATION_NORMALE=nothing, OPERATION_POINTEE=P, OPERATION_TELEPOINTEE=T, OPERATION_RAPPROCHEE=R */
76     gint archive_number;                /**< if it's an archived transaction, contains the number of the archive */
77     gshort automatic_transaction;       /**< 0=manual, 1=automatic (scheduled transaction) */
78     gint reconcile_number;              /**< the number of reconciliation, carreful : can be filled without marked_transaction=OPERATION_RAPPROCHEE sometimes,
79                                              it happen if the user did ctrl R to un-R the transaction, we keep reconcile_number because most of them
80                                              will re-R after the change, and that value will help the user to find which statement it belong.
81                                              o always check marked_transaction before checking reconcile_number here */
82     guint financial_year_number;
83     gchar *voucher;
84     gchar *bank_references;
85 
86     /** @name dates of the transaction */
87     GDate *date;
88     GDate *value_date;
89 
90     /** @name currency stuff */
91     gint currency_number;
92     gint change_between_account_and_transaction;    /**< if 1 : 1 account_currency = (exchange_rate * amount) transaction_currency */
93     GsbReal exchange_rate;
94     GsbReal exchange_fees;
95 
96     /** @name category stuff */
97     gint category_number;
98     gint sub_category_number;
99     gint budgetary_number;
100     gint sub_budgetary_number;
101     gint transaction_number_transfer;   /**< -1 for a transfer to a deleted account, the contra-transaction number else */
102     gint split_of_transaction;          /**< 1 if it's a split of transaction */
103     gint mother_transaction_number;     /**< for a split, the mother's transaction number */
104 
105     /** @name method of payment */
106     gint method_of_payment_number;
107     gchar *method_of_payment_content;
108 };
109 
110 
111 /*START_STATIC*/
112 static void gsb_data_transaction_delete_all_transactions ( void );
113 static void gsb_data_transaction_free ( TransactionStruct *transaction);
114 static gint gsb_data_transaction_get_last_white_number (void);
115 static TransactionStruct *gsb_data_transaction_get_transaction_by_no ( gint transaction_number );
116 static gboolean gsb_data_transaction_save_transaction_pointer ( gpointer transaction );
117 /*END_STATIC*/
118 
119 /*START_EXTERN*/
120 /*END_EXTERN*/
121 
122 
123 /** the g_slist which contains the transactions structures not archived */
124 static GSList *transactions_list = NULL;
125 
126 /** that list contains all the transactions, archived and not archived */
127 static GSList *complete_transactions_list = NULL;
128 
129 /** the g_slist which contains all the white transactions structures
130  * ie : 1 general white line
131  * and 1 white line per split of transaction */
132 static GSList *white_transactions_list = NULL;
133 
134 /** 2 pointers to the 2 last transaction used (to increase the speed) */
135 static TransactionStruct *transaction_buffer[2];
136 
137 /** set the current buffer used */
138 static gint current_transaction_buffer;
139 
140 
141 /**
142  * set the transactions global variables to NULL, usually when we init all the global variables
143  *
144  * \param
145  *
146  * \return FALSE
147  * */
gsb_data_transaction_init_variables(void)148 gboolean gsb_data_transaction_init_variables ( void )
149 {
150     gsb_data_transaction_delete_all_transactions ();
151     return FALSE;
152 }
153 
154 
155 /**
156  * return a pointer to the g_slist of transactions structure
157  * it's not a copy, so we must not free or change it
158  * if we want to change something, use gsb_data_transaction_copy_transactions_list instead
159  * THIS IS THE LIST WITHOUT THE ARCHIVED TRANSACTIONS
160  *
161  * \param none
162  *
163  * \return the slist of transactions structures
164  * */
gsb_data_transaction_get_transactions_list(void)165 GSList *gsb_data_transaction_get_transactions_list ( void )
166 {
167     return transactions_list;
168 }
169 
170 /**
171  * return a pointer to the complete g_slist of transactions structure
172  * it's not a copy, so we must not free or change it
173  * if we want to change something, use gsb_data_transaction_copy_transactions_list instead
174  * THIS IS THE COMPLETE LIST (WITH THE ARCHIVED TRANSACTIONS)
175  *
176  * \param none
177  *
178  * \return the slist of transactions structures
179  * */
gsb_data_transaction_get_complete_transactions_list(void)180 GSList *gsb_data_transaction_get_complete_transactions_list ( void )
181 {
182     return complete_transactions_list;
183 }
184 
185 /**
186  * just append the archived transaction given in param
187  * into the non archived transactions list
188  * called when want to load archived transactions into Grisbi
189  *
190  * \param transaction_number the transaction to append
191  *
192  * \return TRUE ok, FALSE pb
193  * */
gsb_data_transaction_add_archived_to_list(gint transaction_number)194 gboolean gsb_data_transaction_add_archived_to_list ( gint transaction_number )
195 {
196     TransactionStruct *transaction;
197 
198     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
199 
200     if ( !transaction )
201 	    return FALSE;
202     transactions_list = g_slist_append ( transactions_list, transaction );
203 
204     return TRUE;
205 }
206 
207 
208 /**
209  * transitionnal fonction, give back the pointer to the transaction,
210  * normally deleted when the transfer from old transactions is finished
211  * set also in the transactions list, check if it's fast enough with only the transactions number ?
212  *
213  * \param transaction_number
214  *
215  * \return a pointer to the structure of the transation
216  * */
gsb_data_transaction_get_pointer_of_transaction(gint transaction_number)217 gpointer gsb_data_transaction_get_pointer_of_transaction ( gint transaction_number )
218 {
219     TransactionStruct *transaction;
220 
221     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
222 
223     return transaction;
224 }
225 
226 /**
227  * find the last number of transaction
228  *
229  * \param none
230  *
231  * \return the number
232  * */
gsb_data_transaction_get_last_number(void)233 gint gsb_data_transaction_get_last_number (void)
234 {
235     gint last_number = 0;
236     GSList *transactions_list_tmp;
237 
238     transactions_list_tmp = complete_transactions_list;
239 
240     while (transactions_list_tmp)
241     {
242 	TransactionStruct *transaction;
243 
244 	transaction = transactions_list_tmp -> data;
245 	if ( transaction -> transaction_number > last_number )
246 	    last_number = transaction -> transaction_number;
247 
248 	transactions_list_tmp = transactions_list_tmp -> next;
249     }
250     return last_number;
251 }
252 
253 
254 
255 /** find the last number of the white lines
256  * all the white lines have a number < 0, and it always exists at least
257  * one line, which number -1 which is the general white line (without mother)
258  * so we never return 0 to avoid -1 for a number of white split
259  *
260  * \param none
261  *
262  * \return the number
263  * */
gsb_data_transaction_get_last_white_number(void)264 gint gsb_data_transaction_get_last_white_number (void)
265 {
266     gint last_number = 0;
267     GSList *transactions_list_tmp;
268 
269     transactions_list_tmp = white_transactions_list;
270 
271     while (transactions_list_tmp)
272     {
273 	TransactionStruct *transaction;
274 
275 	transaction = transactions_list_tmp -> data;
276 	if ( transaction -> transaction_number < last_number )
277 	    last_number = transaction -> transaction_number;
278 
279 	transactions_list_tmp = transactions_list_tmp -> next;
280     }
281 
282     /* if the general white line has not been appened already, we
283      * return -1 to keep that number for the general white line
284      * (the number will be decreased after to numbered the new line) */
285 
286     if ( !last_number )
287 	last_number = -1;
288 
289     return last_number;
290 }
291 
292 /** get the number of the transaction and save the pointer in the buffer
293  * which will increase the speed later
294  * \param transaction a pointer to a transaction
295  * \return the number of the transaction
296  * */
gsb_data_transaction_get_transaction_number(gpointer transaction_pointer)297 gint gsb_data_transaction_get_transaction_number ( gpointer transaction_pointer )
298 {
299     TransactionStruct *transaction;
300 
301     transaction = transaction_pointer;
302 
303     if ( !transaction )
304 	return 0;
305 
306     /* if we want the transaction number, usually it's to make other stuff after that
307      * so we will save the adr of the transaction to increase the speed after */
308 
309     gsb_data_transaction_save_transaction_pointer ( transaction );
310     return transaction -> transaction_number;
311 }
312 
313 
314 /**
315  * save the pointer in a buffer to increase the speed later
316  *
317  * \param transaction the pointer to the transaction
318  *
319  * \return TRUE or FALSE if pb
320  * */
gsb_data_transaction_save_transaction_pointer(gpointer transaction)321 gboolean gsb_data_transaction_save_transaction_pointer ( gpointer transaction )
322 {
323     /* check if the transaction isn't already saved */
324 
325     if ( transaction == transaction_buffer[0]
326 	 ||
327 	 transaction == transaction_buffer[1] )
328 	return TRUE;
329 
330     current_transaction_buffer = !current_transaction_buffer;
331     transaction_buffer[current_transaction_buffer] = transaction;
332     return TRUE;
333 }
334 
335 
336 /**
337  * return the transaction which the number is in the parameter.
338  * the new transaction is stored in the buffer
339  *
340  * \param transaction_number
341  *
342  * \return a pointer to the transaction, NULL if not found
343  * */
gsb_data_transaction_get_transaction_by_no(gint transaction_number)344 TransactionStruct *gsb_data_transaction_get_transaction_by_no ( gint transaction_number )
345 {
346     GSList *transactions_list_tmp;
347 
348     if (!transaction_number)
349 	return NULL;
350 
351     /* check first if the transaction is in the buffer */
352     if ( transaction_buffer[0]
353 	 &&
354 	 transaction_buffer[0] -> transaction_number == transaction_number )
355 	return transaction_buffer[0];
356 
357     if ( transaction_buffer[1]
358 	 &&
359 	 transaction_buffer[1] -> transaction_number == transaction_number )
360 	return transaction_buffer[1];
361 
362     if ( transaction_number < 0 )
363 	transactions_list_tmp = white_transactions_list;
364     else
365 	transactions_list_tmp = complete_transactions_list;
366 
367     while ( transactions_list_tmp )
368     {
369 	TransactionStruct *transaction;
370 
371 	transaction = transactions_list_tmp -> data;
372 
373 	if ( transaction -> transaction_number == transaction_number )
374 	{
375 	    gsb_data_transaction_save_transaction_pointer ( transaction );
376 	    return transaction;
377 	}
378 
379 	transactions_list_tmp = transactions_list_tmp -> next;
380     }
381 
382     /* here, we didn't find any transaction with that number */
383     return NULL;
384 }
385 
386 
387 /** get the transaction_id
388  * \param transaction_number the number of the transaction
389  * \param no_account the number of account, may be -1, in that case we will look for the transaction in all accounts
390  * \return the id of the transaction
391  * */
gsb_data_transaction_get_transaction_id(gint transaction_number)392 const gchar *gsb_data_transaction_get_transaction_id ( gint transaction_number )
393 {
394     TransactionStruct *transaction;
395 
396     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
397 
398     if ( !transaction )
399 	return NULL;
400 
401     if ( transaction -> transaction_id )
402 	return transaction -> transaction_id;
403     else
404 	return "";
405 }
406 
407 
408 /** set the transaction_id
409  * \param transaction_number
410  * \param no_account
411  * \param transaction_id a gchar with the new transaction_id
412  * \return TRUE if ok
413  * */
gsb_data_transaction_set_transaction_id(gint transaction_number,const gchar * transaction_id)414 gboolean gsb_data_transaction_set_transaction_id ( gint transaction_number,
415                         const gchar *transaction_id )
416 {
417     TransactionStruct *transaction;
418 
419     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number );
420 
421     if ( !transaction )
422         return FALSE;
423 
424     g_free ( transaction -> transaction_id );
425 
426     if ( transaction_id )
427         transaction -> transaction_id = my_strdup ( transaction_id );
428     else
429         transaction -> transaction_id = NULL;
430 
431     return TRUE;
432 }
433 
434 
435 /**
436  * get the account_number
437  *
438  * \param transaction_number the number of the transaction
439  *
440  * \return the account of the transaction or -1 if problem
441  * */
gsb_data_transaction_get_account_number(gint transaction_number)442 gint gsb_data_transaction_get_account_number ( gint transaction_number )
443 {
444     TransactionStruct *transaction;
445 
446     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
447 
448     if ( !transaction )
449 	return -1;
450 
451     return transaction -> account_number;
452 }
453 
454 
455 /**
456  * set the account_number of the transaction
457  * if the transaction has some children, they change too
458  *
459  * \param transaction_number
460  * \param no_account
461  *
462  * \return TRUE if ok
463  * */
gsb_data_transaction_set_account_number(gint transaction_number,gint no_account)464 gboolean gsb_data_transaction_set_account_number ( gint transaction_number,
465                         gint no_account )
466 {
467     TransactionStruct *transaction;
468 
469     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
470 
471     if ( !transaction )
472 	return FALSE;
473 
474     gsb_data_account_set_balances_are_dirty ( transaction -> account_number );
475     transaction -> account_number = no_account;
476     gsb_data_account_set_balances_are_dirty ( no_account );
477 
478     /* if the transaction is a split, change all the children */
479     if (transaction -> split_of_transaction)
480     {
481 	GSList *tmp_list;
482 	GSList *save_tmp_list;
483 
484 	tmp_list = gsb_data_transaction_get_children (transaction -> transaction_number, FALSE);
485 	save_tmp_list = tmp_list;
486 
487 	while (tmp_list)
488 	{
489 	    transaction = tmp_list -> data;
490 	    transaction -> account_number = no_account;
491 	    tmp_list = tmp_list -> next;
492 	}
493 	g_slist_free (save_tmp_list);
494     }
495 
496     return TRUE;
497 }
498 
499 
500 
501 /**
502  * get the GDate of the transaction
503  *
504  * \param transaction_number the number of the transaction
505  *
506  * \return the GDate of the transaction
507  * */
gsb_data_transaction_get_date(gint transaction_number)508 const GDate *gsb_data_transaction_get_date ( gint transaction_number )
509 {
510     TransactionStruct *transaction;
511 
512     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
513 
514     if ( !transaction )
515     return NULL;
516 
517     return transaction -> date;
518 }
519 
520 
521 /**
522  * set the GDate of the transaction
523  * if the transaction has some children, they change too
524  *
525  * \param transaction_number
526  * \param no_account
527  *
528  * \return TRUE if ok
529  * */
gsb_data_transaction_set_date(gint transaction_number,const GDate * date)530 gboolean gsb_data_transaction_set_date ( gint transaction_number,
531                         const GDate *date )
532 {
533     TransactionStruct *transaction;
534 
535     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
536 
537     if ( !transaction )
538 	return FALSE;
539 
540     if (transaction -> date)
541         g_date_free (transaction -> date);
542     transaction -> date = gsb_date_copy (date);
543 
544     /* if the transaction is a split, change all the children */
545     if (transaction -> split_of_transaction)
546     {
547 		GSList *tmp_list;
548 		GSList *save_tmp_list;
549 
550 		tmp_list = gsb_data_transaction_get_children (transaction -> transaction_number, FALSE);
551 		save_tmp_list = tmp_list;
552 
553 		while (tmp_list)
554 		{
555 			transaction = tmp_list -> data;
556 
557 			if (transaction -> date)
558 				g_date_free (transaction -> date);
559 			transaction -> date = gsb_date_copy (date);
560 
561 			/* si l'opération fille est un transfert on regarde si la contre opération est rapprochée
562 			 * si elle ne l'est pas on peut mettre à jour la date */
563 			if ( transaction->transaction_number_transfer > 0 )
564 			{
565 				gint contra_marked_transaction = 0;
566 
567 				contra_marked_transaction = gsb_data_transaction_get_marked_transaction (
568 							transaction->transaction_number_transfer );
569 
570 				if ( contra_marked_transaction != OPERATION_RAPPROCHEE )
571 				{
572 					gsb_data_transaction_set_date ( transaction->transaction_number_transfer, date );
573 					gsb_transactions_list_update_transaction ( transaction->transaction_number_transfer );
574 				}
575 			}
576 
577 			tmp_list = tmp_list -> next;
578 	}
579 	g_slist_free (save_tmp_list);
580     }
581     return TRUE;
582 }
583 
584 
585 
586 
587 /** get the value GDate of the transaction
588  * \param transaction_number the number of the transaction
589  * \return the GDate of the transaction
590  * */
gsb_data_transaction_get_value_date(gint transaction_number)591 const GDate *gsb_data_transaction_get_value_date ( gint transaction_number )
592 {
593     TransactionStruct *transaction;
594 
595     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
596 
597     if ( !transaction )
598 	return NULL;
599 
600     return transaction -> value_date;
601 }
602 
603 
604 /**
605  * set the value GDate of the transaction
606  * if the transaction has some children, they change too
607  *
608  * \param transaction_number
609  * \param date the value date
610  *
611  * \return TRUE if ok
612  * */
gsb_data_transaction_set_value_date(gint transaction_number,const GDate * date)613 gboolean gsb_data_transaction_set_value_date ( gint transaction_number,
614                         const GDate *date )
615 {
616     TransactionStruct *transaction;
617 
618     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
619 
620     if ( !transaction )
621 	return FALSE;
622 
623     if (transaction ->  value_date)
624         g_date_free (transaction ->  value_date);
625     transaction ->  value_date = gsb_date_copy (date);
626 
627     /* if the transaction is a split, change all the children */
628     if (transaction -> split_of_transaction)
629     {
630 	GSList *tmp_list;
631 	GSList *save_tmp_list;
632 
633 	tmp_list = gsb_data_transaction_get_children (transaction -> transaction_number, FALSE);
634 	save_tmp_list = tmp_list;
635 
636 	while (tmp_list)
637 	{
638 	    transaction = tmp_list -> data;
639 
640 	    if (transaction ->  value_date)
641             g_date_free (transaction -> value_date);
642 	    transaction -> value_date = gsb_date_copy (date);
643 
644 	    tmp_list = tmp_list -> next;
645 	}
646 	g_slist_free (save_tmp_list);
647     }
648 
649     return TRUE;
650 }
651 
652 
653 /**
654  * get the value GDate of the transaction or the date if not exist
655  *
656  * \param transaction_number the number of the transaction
657  *
658  * \return the GDate of the transaction
659  * */
gsb_data_transaction_get_value_date_or_date(gint transaction_number)660 const GDate *gsb_data_transaction_get_value_date_or_date ( gint transaction_number )
661 {
662     TransactionStruct *transaction;
663 
664     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
665 
666     if ( !transaction )
667 	return NULL;
668 
669     if ( transaction -> value_date && g_date_valid ( transaction -> value_date ) )
670         return transaction -> value_date;
671     else
672         return transaction -> date;
673 }
674 
675 
676 /**
677  * get the amount of the transaction without any currency change
678  * (so just get the given amout)
679  *
680  * \param transaction_number the number of the transaction
681  *
682  * \return the amount of the transaction
683  * */
gsb_data_transaction_get_amount(gint transaction_number)684 GsbReal gsb_data_transaction_get_amount ( gint transaction_number )
685 {
686     TransactionStruct *transaction;
687 
688     transaction = gsb_data_transaction_get_transaction_by_no (transaction_number);
689 
690     if ( !transaction )
691 	return null_real;
692 
693     return transaction -> transaction_amount;
694 }
695 
696 
697 /** set the amount of the transaction
698  *
699  * \param transaction_number
700  * \param amount
701  *
702  * \return TRUE if ok
703  * */
gsb_data_transaction_set_amount(gint transaction_number,GsbReal amount)704 gboolean gsb_data_transaction_set_amount ( gint transaction_number,
705                         GsbReal amount )
706 {
707     TransactionStruct *transaction;
708 
709     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
710 
711     if ( !transaction )
712         return FALSE;
713 
714     transaction -> transaction_amount = amount;
715     gsb_data_account_set_balances_are_dirty ( transaction -> account_number );
716 
717     return TRUE;
718 }
719 
720 
721 
722 
723 
724 /**
725  * get the amount of the transaction, modified to be ok with the currency
726  * of the account
727  * !! we should never use -1 for the return_exponent because the numbers become to deep and
728  * 	the functions gsb_real_add and others can return an overflow
729  * 	try to pass a return_exponent by gsb_data_currency_get_floating_point before
730  *
731  * \param transaction_number the number of the transaction
732  * \param return_exponent the exponent we want to have for the returned number, or -1 for the exponent of the returned currency
733  *
734  * \return the amount of the transaction
735  * */
gsb_data_transaction_get_adjusted_amount(gint transaction_number,gint return_exponent)736 GsbReal gsb_data_transaction_get_adjusted_amount ( gint transaction_number,
737                         gint return_exponent )
738 {
739     TransactionStruct *transaction;
740 
741     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
742 
743     if ( !transaction )
744 	return null_real;
745 
746     return gsb_data_transaction_get_adjusted_amount_for_currency ( transaction_number,
747 								   gsb_data_account_get_currency ( transaction -> account_number ),
748 								   return_exponent );
749 }
750 
751 
752 
753 
754 /**
755  * get the amount of the transaction, modified to be ok with the currency
756  * given in param
757  *
758  * \param transaction_number 		the number of the transaction
759  * \param return_currency_number 	the currency we want to adjust the transaction's amount
760  * \param return_exponent 		the exponent we want to have for the returned number, or -1 for the exponent of the returned currency
761  *
762  * \return the amount of the transaction
763  * */
gsb_data_transaction_get_adjusted_amount_for_currency(gint transaction_number,gint return_currency_number,gint return_exponent)764 GsbReal gsb_data_transaction_get_adjusted_amount_for_currency ( gint transaction_number,
765                         gint return_currency_number,
766                         gint return_exponent )
767 {
768     TransactionStruct *transaction;
769     GsbReal amount = null_real;
770     gint link_number;
771 
772     if (return_exponent == -1)
773 	return_exponent = gsb_data_currency_get_floating_point (return_currency_number);
774 
775     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
776 
777     if ( ! (transaction && return_currency_number ) )
778         return gsb_real_adjust_exponent  ( null_real, return_exponent );
779 
780     /* if the transaction currency is the same of the account's one,
781      * we just return the transaction's amount */
782     if ( transaction -> currency_number == return_currency_number )
783 	{
784         return gsb_real_adjust_exponent  ( transaction -> transaction_amount, return_exponent );
785 	}
786 
787 	/* now we can adjust the amount */
788 	/* the exchange is saved in the transaction itself */
789 	if (transaction->exchange_rate.mantissa)
790     {
791 		gint account_currency;
792 
793         if ( transaction -> change_between_account_and_transaction )
794             amount = gsb_real_div (transaction -> transaction_amount, transaction -> exchange_rate);
795         else
796             amount = gsb_real_mul (transaction -> transaction_amount, transaction -> exchange_rate );
797 
798         /* The costs are still deducted from the transaction. In case of internal transfer there is no charge. */
799         amount = gsb_real_sub (amount, transaction -> exchange_fees);
800 
801 		account_currency = gsb_data_account_get_currency (transaction->account_number);
802 		if (account_currency != return_currency_number)
803 		{
804 			if ((link_number = gsb_data_currency_link_search (account_currency, return_currency_number)))
805 			{
806 				/* there is a hard link between the account currency and the return currency */
807 				if ( gsb_data_currency_link_get_first_currency (link_number) == account_currency)
808 					amount = gsb_real_mul (amount, gsb_data_currency_link_get_change_rate (link_number));
809 				else
810 					amount = gsb_real_div (amount, gsb_data_currency_link_get_change_rate (link_number));
811 			}
812 			else
813 			{
814 				GsbReal current_exchange;
815 				GsbReal current_exchange_fees;
816 
817 				gsb_currency_exchange_dialog (account_currency,
818 											  return_currency_number,
819 											  0,
820 											  null_real,
821 											  null_real,
822 											  TRUE);
823 
824 				current_exchange = gsb_currency_get_current_exchange ();
825 				current_exchange_fees = gsb_currency_get_current_exchange_fees ();
826 
827 				amount = gsb_real_div (amount, current_exchange);
828 				if (current_exchange_fees.mantissa != 0)
829 					amount = gsb_real_sub (amount, current_exchange_fees);
830 			}
831 		}
832     }
833     else if ( (link_number = gsb_data_currency_link_search ( transaction -> currency_number,
834 							return_currency_number ) ) )
835     {
836 		/* there is a hard link between the transaction currency and the return currency */
837         if ( gsb_data_currency_link_get_first_currency (link_number) == transaction -> currency_number)
838             amount = gsb_real_mul ( transaction -> transaction_amount,
839                         gsb_data_currency_link_get_change_rate (link_number));
840         else
841             amount = gsb_real_div ( transaction -> transaction_amount,
842                         gsb_data_currency_link_get_change_rate (link_number));
843 
844         /* The costs are still deducted from the transaction. In case of internal transfer there is no charge. */
845         amount = gsb_real_sub (amount, transaction -> exchange_fees);
846     }
847     else if ( return_currency_number > 0 && transaction -> currency_number > 0 )
848     {
849         GsbReal current_exchange;
850         GsbReal current_exchange_fees;
851 
852         gsb_currency_exchange_dialog ( return_currency_number,
853                         transaction -> currency_number,
854                         0,
855                         null_real,
856                         null_real,
857                         TRUE );
858 
859         current_exchange = gsb_currency_get_current_exchange ( );
860         current_exchange_fees = gsb_currency_get_current_exchange_fees ( );
861 
862         gsb_data_transaction_set_exchange_rate ( transaction_number,
863                         gsb_real_abs ( current_exchange ) );
864         gsb_data_transaction_set_change_between (transaction_number, 0 );
865         amount = gsb_real_div ( transaction -> transaction_amount,
866                         current_exchange );
867 
868         if ( transaction -> exchange_fees.mantissa == 0
869          && current_exchange_fees.mantissa != 0 )
870             amount = gsb_real_sub ( amount, current_exchange_fees );
871         else
872             amount = gsb_real_sub ( amount, transaction -> exchange_fees );
873 
874     }
875 
876     return gsb_real_adjust_exponent  ( amount, return_exponent );
877 }
878 
879 
880 
881 
882 /** get the currency_number
883  * \param transaction_number the number of the transaction
884  * \return the currency number of the transaction
885  * */
gsb_data_transaction_get_currency_number(gint transaction_number)886 gint gsb_data_transaction_get_currency_number ( gint transaction_number )
887 {
888     TransactionStruct *transaction;
889 
890     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
891 
892     if ( !transaction )
893 	return -1;
894 
895     return transaction -> currency_number;
896 }
897 
898 
899 /**
900  * set the currency_number
901  * if the transaction has some children, they change too
902  *
903  * \param transaction_number
904  * \param no_currency
905  *
906  * \return TRUE if ok
907  * */
gsb_data_transaction_set_currency_number(gint transaction_number,gint no_currency)908 gboolean gsb_data_transaction_set_currency_number ( gint transaction_number,
909                         gint no_currency )
910 {
911     TransactionStruct *transaction;
912 
913     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
914 
915     if ( !transaction )
916 	return FALSE;
917 
918     transaction -> currency_number = no_currency;
919 
920     /* if the transaction is a split, change all the children */
921     if (transaction -> split_of_transaction)
922     {
923 	GSList *tmp_list;
924 	GSList *save_tmp_list;
925 
926 	tmp_list = gsb_data_transaction_get_children (transaction -> transaction_number, FALSE);
927 	save_tmp_list = tmp_list;
928 
929 	while (tmp_list)
930 	{
931 	    transaction = tmp_list -> data;
932 	    transaction -> currency_number = no_currency;
933 	    tmp_list = tmp_list -> next;
934 	}
935 	g_slist_free (save_tmp_list);
936     }
937 
938     return TRUE;
939 }
940 
941 
942 
943 
944 /**
945  * get the change_between_account_and_transaction
946  * if the value is 1, we have : 1 account_currency = (exchange_rate * amount) transaction_currency
947  * else we have : 1 transaction_currency = (exchange_rate * amount) account_currency
948  *
949  * \param transaction_number the number of the transaction
950  *
951  * \return the currency number of the transaction
952  * */
gsb_data_transaction_get_change_between(gint transaction_number)953 gint gsb_data_transaction_get_change_between ( gint transaction_number )
954 {
955     TransactionStruct *transaction;
956 
957     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
958 
959     if ( !transaction )
960 	return -1;
961 
962     return transaction -> change_between_account_and_transaction;
963 }
964 
965 
966 /**
967  * set the change_between_account_and_transaction
968  * if the value is 1, we have : 1 account_currency = (exchange_rate * amount) transaction_currency
969  * else we have : 1 transaction_currency = (exchange_rate * amount) account_currency
970  * if the transaction has some children, they change too
971  *
972  * \param transaction_number
973  * \param value
974  *
975  * \return TRUE if ok
976  * */
gsb_data_transaction_set_change_between(gint transaction_number,gint value)977 gboolean gsb_data_transaction_set_change_between ( gint transaction_number,
978                         gint value )
979 {
980     TransactionStruct *transaction;
981 
982     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
983 
984     if ( !transaction )
985 	return FALSE;
986 
987     transaction -> change_between_account_and_transaction = value;
988 
989     /* if the transaction is a split, change all the children */
990     if (transaction -> split_of_transaction)
991     {
992 	GSList *tmp_list;
993 	GSList *save_tmp_list;
994 
995 	tmp_list = gsb_data_transaction_get_children (transaction -> transaction_number, FALSE);
996 	save_tmp_list = tmp_list;
997 
998 	while (tmp_list)
999 	{
1000 	    transaction = tmp_list -> data;
1001 	    transaction -> change_between_account_and_transaction = value;
1002 	    tmp_list = tmp_list -> next;
1003 	}
1004 	g_slist_free (save_tmp_list);
1005     }
1006 
1007     return TRUE;
1008 }
1009 
1010 
1011 
1012 
1013 /**
1014  * get the exchange_rate of the transaction
1015  *
1016  * \param transaction_number the number of the transaction
1017  *
1018  * \return the exchange_rate of the transaction
1019  * */
gsb_data_transaction_get_exchange_rate(gint transaction_number)1020 GsbReal gsb_data_transaction_get_exchange_rate ( gint transaction_number )
1021 {
1022     TransactionStruct *transaction;
1023 
1024 	transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1025 
1026     if ( !transaction )
1027 	return null_real;
1028 
1029     return transaction -> exchange_rate;
1030 }
1031 
1032 
1033 /**
1034  * set the exchange_rate of the transaction
1035  * if the transaction has some children, they change too
1036  *
1037  * \param transaction_number
1038  * \param rate
1039  *
1040  * \return TRUE if ok
1041  * */
gsb_data_transaction_set_exchange_rate(gint transaction_number,GsbReal rate)1042 gboolean gsb_data_transaction_set_exchange_rate ( gint transaction_number,
1043                         GsbReal rate )
1044 {
1045     TransactionStruct *transaction;
1046 
1047     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1048 
1049     if ( !transaction )
1050 	return FALSE;
1051 
1052     transaction -> exchange_rate = rate;
1053 
1054     /* if the transaction is a split, change all the children */
1055     if (transaction -> split_of_transaction)
1056     {
1057 	GSList *tmp_list;
1058 	GSList *save_tmp_list;
1059 
1060 	tmp_list = gsb_data_transaction_get_children (transaction -> transaction_number, FALSE);
1061 	save_tmp_list = tmp_list;
1062 
1063 	while (tmp_list)
1064 	{
1065 	    transaction = tmp_list -> data;
1066 	    transaction -> exchange_rate = rate;
1067 	    tmp_list = tmp_list -> next;
1068 	}
1069 	g_slist_free (save_tmp_list);
1070     }
1071     return TRUE;
1072 }
1073 
1074 
1075 
1076 /**
1077  * get the exchange_fees of the transaction
1078  *
1079  * \param transaction_number the number of the transaction
1080  *
1081  * \return the exchange_fees of the transaction
1082  * */
gsb_data_transaction_get_exchange_fees(gint transaction_number)1083 GsbReal gsb_data_transaction_get_exchange_fees ( gint transaction_number )
1084 {
1085     TransactionStruct *transaction;
1086 
1087     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1088 
1089     if ( !transaction )
1090 	return null_real;
1091 
1092     return transaction -> exchange_fees;
1093 }
1094 
1095 
1096 /**
1097  * set the exchange_fees of the transaction
1098  * if the transaction has some children, they change too
1099  *
1100  * \param transaction_number
1101  * \param rate
1102  *
1103  * \return TRUE if ok
1104  * */
gsb_data_transaction_set_exchange_fees(gint transaction_number,GsbReal rate)1105 gboolean gsb_data_transaction_set_exchange_fees ( gint transaction_number,
1106                         GsbReal rate )
1107 {
1108     TransactionStruct *transaction;
1109 
1110     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1111 
1112     if ( !transaction )
1113 	return FALSE;
1114 
1115     transaction -> exchange_fees = rate;
1116 
1117     /* if the transaction is a split, change all the children */
1118     if (transaction -> split_of_transaction)
1119     {
1120 	GSList *tmp_list;
1121 	GSList *save_tmp_list;
1122 
1123 	tmp_list = gsb_data_transaction_get_children (transaction -> transaction_number, FALSE);
1124 	save_tmp_list = tmp_list;
1125 
1126 	while (tmp_list)
1127 	{
1128 	    transaction = tmp_list -> data;
1129 	    transaction -> exchange_fees = rate;
1130 	    tmp_list = tmp_list -> next;
1131 	}
1132 	g_slist_free (save_tmp_list);
1133     }
1134     return TRUE;
1135 }
1136 
1137 
1138 
1139 
1140 /**
1141  * get the party_number
1142  *
1143  * \param transaction_number the number of the transaction
1144  *
1145  * \return the currency number of the transaction
1146  * */
gsb_data_transaction_get_party_number(gint transaction_number)1147 gint gsb_data_transaction_get_party_number ( gint transaction_number )
1148 {
1149     TransactionStruct *transaction;
1150 
1151     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1152 
1153     if ( !transaction )
1154 	return -1;
1155 
1156     return transaction -> party_number;
1157 }
1158 
1159 
1160 /**
1161  * set the party_number
1162  * if the transaction has some children, they change too
1163  *
1164  * \param transaction_number
1165  * \param value
1166  *
1167  * \return TRUE if ok
1168  * */
gsb_data_transaction_set_party_number(gint transaction_number,gint no_party)1169 gboolean gsb_data_transaction_set_party_number ( gint transaction_number,
1170                         gint no_party )
1171 {
1172     TransactionStruct *transaction;
1173 
1174     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1175 
1176     if ( !transaction )
1177 	return FALSE;
1178 
1179     transaction -> party_number = no_party;
1180 
1181     /* if the transaction is a split, change all the children */
1182     if (transaction -> split_of_transaction)
1183     {
1184 	GSList *tmp_list;
1185 	GSList *save_tmp_list;
1186 
1187 	tmp_list = gsb_data_transaction_get_children (transaction -> transaction_number, FALSE);
1188 	save_tmp_list = tmp_list;
1189 
1190 	while (tmp_list)
1191 	{
1192 	    transaction = tmp_list -> data;
1193 	    transaction -> party_number = no_party;
1194 	    tmp_list = tmp_list -> next;
1195 	}
1196 	g_slist_free (save_tmp_list);
1197     }
1198 
1199     return TRUE;
1200 }
1201 
1202 
1203 
1204 /**
1205  * get the category_number
1206  *
1207  * \param transaction_number the number of the transaction
1208  *
1209  * \return the category number of the transaction, -1 for error
1210  * */
gsb_data_transaction_get_category_number(gint transaction_number)1211 gint gsb_data_transaction_get_category_number ( gint transaction_number )
1212 {
1213     TransactionStruct *transaction;
1214 
1215     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1216 
1217     if ( !transaction )
1218 	return -1;
1219 
1220     return transaction -> category_number;
1221 }
1222 
1223 
1224 /** set the category_number
1225  * \param transaction_number
1226  * \param value
1227  * \return TRUE if ok
1228  * */
gsb_data_transaction_set_category_number(gint transaction_number,gint no_category)1229 gboolean gsb_data_transaction_set_category_number ( gint transaction_number,
1230                         gint no_category )
1231 {
1232     TransactionStruct *transaction;
1233 
1234     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1235 
1236     if ( !transaction )
1237 	return FALSE;
1238 
1239     transaction -> category_number = no_category;
1240 
1241     return TRUE;
1242 }
1243 
1244 
1245 /** get the sub_category_number
1246  * \param transaction_number the number of the transaction
1247  * \return the sub_category number of the transaction
1248  * */
gsb_data_transaction_get_sub_category_number(gint transaction_number)1249 gint gsb_data_transaction_get_sub_category_number ( gint transaction_number )
1250 {
1251     TransactionStruct *transaction;
1252 
1253     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1254 
1255     /* pbiava le 04/04/2009 uniformisation avec les autres fonctions similaires */
1256     if ( !transaction )
1257 	return -1;
1258 
1259     return transaction -> sub_category_number;
1260 }
1261 
1262 
1263 /**
1264  * set the sub_category_number
1265  *
1266  * \param transaction_number
1267  * \param value
1268  *
1269  * \return TRUE if ok
1270  * */
gsb_data_transaction_set_sub_category_number(gint transaction_number,gint no_sub_category)1271 gboolean gsb_data_transaction_set_sub_category_number ( gint transaction_number,
1272                         gint no_sub_category )
1273 {
1274     TransactionStruct *transaction;
1275 
1276     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1277 
1278     if ( !transaction )
1279 	return FALSE;
1280 
1281     transaction -> sub_category_number = no_sub_category;
1282 
1283     return TRUE;
1284 }
1285 
1286 
1287 /**
1288  * check if the transaction is a split (mother)
1289  *
1290  * \param transaction_number the number of the transaction
1291  *
1292  * \return TRUE if the transaction is a split of transaction
1293  * */
gsb_data_transaction_get_split_of_transaction(gint transaction_number)1294 gint gsb_data_transaction_get_split_of_transaction ( gint transaction_number )
1295 {
1296     TransactionStruct *transaction;
1297 
1298     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1299 
1300     if ( !transaction )
1301 	return -1;
1302 
1303     return transaction -> split_of_transaction;
1304 }
1305 
1306 
1307 /**
1308  * set the transaction as split or not
1309  *
1310  * \param transaction_number
1311  * \param is_split
1312  *
1313  * \return TRUE if ok
1314  * */
gsb_data_transaction_set_split_of_transaction(gint transaction_number,gint is_split)1315 gboolean gsb_data_transaction_set_split_of_transaction ( gint transaction_number,
1316                         gint is_split )
1317 {
1318     TransactionStruct *transaction;
1319 
1320     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1321 
1322     if ( !transaction )
1323 	return FALSE;
1324 
1325     transaction -> split_of_transaction = is_split;
1326 
1327     return TRUE;
1328 }
1329 
1330 
1331 /**
1332  * get the notes
1333  *
1334  * \param transaction_number the number of the transaction
1335  *
1336  * \return the notes of the transaction
1337  * */
gsb_data_transaction_get_notes(gint transaction_number)1338 const gchar *gsb_data_transaction_get_notes ( gint transaction_number )
1339 {
1340     TransactionStruct *transaction;
1341 
1342     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1343 
1344     if ( !transaction )
1345 	return NULL;
1346 
1347     return transaction -> notes;
1348 }
1349 
1350 
1351 /** set the notes
1352  * the notes parameter will be copy before stored in memory
1353  * \param transaction_number
1354  * \param no_account
1355  * \param notes a gchar with the new notes. This string is duplicated.
1356  * \return TRUE if ok
1357  * */
gsb_data_transaction_set_notes(gint transaction_number,const gchar * notes)1358 gboolean gsb_data_transaction_set_notes ( gint transaction_number,
1359                         const gchar *notes )
1360 {
1361     TransactionStruct *transaction;
1362 
1363     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1364     if ( !transaction )
1365         return FALSE;
1366 
1367     g_free ( transaction -> notes );
1368     transaction -> notes = my_strdup ( notes );
1369 
1370     return TRUE;
1371 }
1372 
1373 
1374 
1375 /**
1376  * get the method_of_payment_number
1377  * \param transaction_number the number of the transaction
1378  *
1379  * \return the method_of_payment_number
1380  * */
gsb_data_transaction_get_method_of_payment_number(gint transaction_number)1381 gint gsb_data_transaction_get_method_of_payment_number ( gint transaction_number )
1382 {
1383     TransactionStruct *transaction;
1384 
1385     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1386 
1387     if ( !transaction )
1388 	return -1;
1389 
1390     return transaction -> method_of_payment_number;
1391 }
1392 
1393 
1394 /**
1395  * set the method_of_payment_number
1396  * if the transaction has some children, they change too
1397  *
1398  * \param transaction_number
1399  * \param
1400  *
1401  * \return TRUE if ok
1402  * */
gsb_data_transaction_set_method_of_payment_number(gint transaction_number,gint number)1403 gboolean gsb_data_transaction_set_method_of_payment_number ( gint transaction_number,
1404                         gint number )
1405 {
1406     TransactionStruct *transaction;
1407 
1408     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1409 
1410     if ( !transaction )
1411 	return FALSE;
1412 
1413     transaction -> method_of_payment_number = number;
1414 
1415     /* if the transaction is a split, change all the children */
1416     if (transaction -> split_of_transaction)
1417     {
1418 	GSList *tmp_list;
1419 	GSList *save_tmp_list;
1420 
1421 	tmp_list = gsb_data_transaction_get_children (transaction -> transaction_number, FALSE);
1422 	save_tmp_list = tmp_list;
1423 
1424 	while (tmp_list)
1425 	{
1426 	    transaction = tmp_list -> data;
1427 	    transaction -> method_of_payment_number = number;
1428 	    tmp_list = tmp_list -> next;
1429 	}
1430 	g_slist_free (save_tmp_list);
1431     }
1432 
1433     return TRUE;
1434 }
1435 
1436 
1437 /**
1438  * get the method_of_payment_content
1439  *
1440  * \param transaction_number the number of the transaction
1441  * \return the method_of_payment_content of the transaction
1442  * */
gsb_data_transaction_get_method_of_payment_content(gint transaction_number)1443 const gchar *gsb_data_transaction_get_method_of_payment_content ( gint transaction_number )
1444 {
1445     TransactionStruct *transaction;
1446 
1447     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1448 
1449     if ( !transaction )
1450 	return NULL;
1451 
1452     return transaction -> method_of_payment_content;
1453 }
1454 
1455 
1456 /**
1457  * set the method_of_payment_content
1458  * dupplicate the parameter before storing it in the transaction
1459  *
1460  * \param transaction_number
1461  * \param no_account
1462  * \param method_of_payment_content a gchar with the new method_of_payment_content
1463  * \return TRUE if ok
1464  * */
gsb_data_transaction_set_method_of_payment_content(gint transaction_number,const gchar * method_of_payment_content)1465 gboolean gsb_data_transaction_set_method_of_payment_content ( gint transaction_number,
1466                         const gchar *method_of_payment_content )
1467 {
1468     TransactionStruct *transaction;
1469 
1470     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1471     if ( !transaction )
1472         return FALSE;
1473 
1474     g_free ( transaction -> method_of_payment_content );
1475     transaction -> method_of_payment_content = my_strdup ( method_of_payment_content );
1476 
1477     return TRUE;
1478 }
1479 
1480 
1481 
1482 /**
1483  * get the marked_transaction
1484  *
1485  * \param transaction_number the number of the transaction
1486  *
1487  * \return the marked_transaction : OPERATION_NORMALE, OPERATION_POINTEE, OPERATION_TELEPOINTEE, OPERATION_RAPPROCHEE
1488  * */
gsb_data_transaction_get_marked_transaction(gint transaction_number)1489 gint gsb_data_transaction_get_marked_transaction ( gint transaction_number )
1490 {
1491     TransactionStruct *transaction;
1492 
1493     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1494 
1495     if ( !transaction )
1496 	return -1;
1497 
1498     return transaction -> marked_transaction;
1499 }
1500 
1501 
1502 /**
1503  * set the marked_transaction
1504  * if the transaction has some children, they change too
1505  *
1506  * \param transaction_number
1507  * \param marked_transaction : OPERATION_NORMALE, OPERATION_POINTEE, OPERATION_TELEPOINTEE, OPERATION_RAPPROCHEE
1508  *
1509  * \return TRUE if ok
1510  * */
gsb_data_transaction_set_marked_transaction(gint transaction_number,gint marked_transaction)1511 gboolean gsb_data_transaction_set_marked_transaction ( gint transaction_number,
1512                         gint marked_transaction )
1513 {
1514     TransactionStruct *transaction;
1515 
1516     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1517 
1518     if ( !transaction )
1519 	return FALSE;
1520 
1521     gsb_data_account_set_balances_are_dirty ( transaction->account_number );
1522     transaction -> marked_transaction = marked_transaction;
1523 
1524     /* if the transaction is a split, change all the children */
1525     if (transaction -> split_of_transaction)
1526     {
1527         GSList *tmp_list;
1528         GSList *save_tmp_list;
1529 
1530         tmp_list = gsb_data_transaction_get_children (transaction -> transaction_number, FALSE);
1531         save_tmp_list = tmp_list;
1532 
1533         while (tmp_list)
1534         {
1535             transaction = tmp_list -> data;
1536             transaction -> marked_transaction = marked_transaction;
1537             tmp_list = tmp_list -> next;
1538         }
1539         g_slist_free (save_tmp_list);
1540     }
1541 
1542     return TRUE;
1543 }
1544 
1545 
1546 /**
1547  * get the number of the archive
1548  *
1549  * \param transaction_number the number of the transaction
1550  *
1551  * \return the archive number, 0 if not archived and -1 if transaction not found
1552  * */
gsb_data_transaction_get_archive_number(gint transaction_number)1553 gint gsb_data_transaction_get_archive_number ( gint transaction_number )
1554 {
1555     TransactionStruct *transaction;
1556 
1557     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1558 
1559     if ( !transaction )
1560 	return -1;
1561 
1562     return transaction -> archive_number;
1563 }
1564 
1565 
1566 /**
1567  * set the number of the archive if it's an archived transaction
1568  * add or remove the transaction from the list of transactions without archive according to the value
1569  *
1570  * \param transaction_number
1571  * \param archive_number or 0 if not an archive
1572  *
1573  * \return TRUE if ok
1574  * */
gsb_data_transaction_set_archive_number(gint transaction_number,gint archive_number)1575 gboolean gsb_data_transaction_set_archive_number ( gint transaction_number,
1576                         gint archive_number )
1577 {
1578     TransactionStruct *transaction;
1579 
1580     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1581 
1582     if ( !transaction )
1583         return FALSE;
1584 
1585     /* if the archive_number of the transaction is 0 for now, it's already in that list,
1586      * so we mustn't add it,
1587      * else, according to the new value, we remove it
1588     */
1589     if ( !transaction -> archive_number )
1590     {
1591         /* the transaction was not an archive, so it's into the 2 lists,
1592          * if we transform it as an archive, we remove it from the transactions_list */
1593         if ( archive_number )
1594             transactions_list = g_slist_remove ( transactions_list, transaction );
1595     }
1596 
1597     transaction -> archive_number = archive_number;
1598 
1599     return TRUE;
1600 }
1601 
1602 
1603 
1604 /** get the automatic_transaction
1605  * \param transaction_number the number of the transaction
1606  * \return 1 if the transaction was taken automaticly
1607  * */
gsb_data_transaction_get_automatic_transaction(gint transaction_number)1608 gint gsb_data_transaction_get_automatic_transaction ( gint transaction_number )
1609 {
1610     TransactionStruct *transaction;
1611 
1612     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1613 
1614     if ( !transaction )
1615 	return -1;
1616 
1617     return transaction -> automatic_transaction;
1618 }
1619 
1620 
1621 /** set the automatic_transaction
1622  * \param transaction_number
1623  * \param  automatic_transaction
1624  * \return TRUE if ok
1625  * */
gsb_data_transaction_set_automatic_transaction(gint transaction_number,gint automatic_transaction)1626 gboolean gsb_data_transaction_set_automatic_transaction ( gint transaction_number,
1627                         gint automatic_transaction )
1628 {
1629     TransactionStruct *transaction;
1630 
1631     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1632 
1633     if ( !transaction )
1634 	return FALSE;
1635 
1636     transaction -> automatic_transaction = automatic_transaction;
1637 
1638     return TRUE;
1639 }
1640 
1641 
1642 /** get the reconcile_number
1643  * \param transaction_number the number of the transaction
1644  * \return the reconcile_number
1645  * */
gsb_data_transaction_get_reconcile_number(gint transaction_number)1646 gint gsb_data_transaction_get_reconcile_number ( gint transaction_number )
1647 {
1648     TransactionStruct *transaction;
1649 
1650     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1651 
1652     if ( !transaction )
1653 	return -1;
1654 
1655     return transaction -> reconcile_number;
1656 }
1657 
1658 
1659 /**
1660  * set the reconcile_number
1661  * if the transaction has some children, they change too
1662  *
1663  * \param transaction_number
1664  * \param  reconcile_number
1665  *
1666  * \return TRUE if ok
1667  * */
gsb_data_transaction_set_reconcile_number(gint transaction_number,gint reconcile_number)1668 gboolean gsb_data_transaction_set_reconcile_number ( gint transaction_number,
1669                         gint reconcile_number )
1670 {
1671     TransactionStruct *transaction;
1672 
1673     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1674 
1675     if ( !transaction )
1676 	return FALSE;
1677 
1678     transaction -> reconcile_number = reconcile_number;
1679 
1680     /* if the transaction is a split, change all the children */
1681     if (transaction -> split_of_transaction)
1682     {
1683 	GSList *tmp_list;
1684 	GSList *save_tmp_list;
1685 
1686 	tmp_list = gsb_data_transaction_get_children (transaction -> transaction_number, FALSE);
1687 	save_tmp_list = tmp_list;
1688 
1689 	while (tmp_list)
1690 	{
1691 	    transaction = tmp_list -> data;
1692 	    transaction -> reconcile_number = reconcile_number;
1693 	    tmp_list = tmp_list -> next;
1694 	}
1695 	g_slist_free (save_tmp_list);
1696     }
1697 
1698     return TRUE;
1699 }
1700 
1701 
1702 /** get the financial_year_number
1703  * \param transaction_number the number of the transaction
1704  * \return the financial_year_number
1705  * */
gsb_data_transaction_get_financial_year_number(gint transaction_number)1706 gint gsb_data_transaction_get_financial_year_number ( gint transaction_number )
1707 {
1708     TransactionStruct *transaction;
1709 
1710     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1711 
1712 	if (!transaction)
1713 		return -1;
1714 	else if (transaction->split_of_transaction)
1715 		return 0;
1716 	else
1717 		return transaction->financial_year_number;
1718 }
1719 
1720 
1721 /**
1722  * set the financial_year_number
1723  *
1724  * \param transaction_number
1725  * \param  financial_year_number
1726  *
1727  * \return TRUE if ok
1728  * */
gsb_data_transaction_set_financial_year_number(gint transaction_number,gint financial_year_number)1729 gboolean gsb_data_transaction_set_financial_year_number ( gint transaction_number,
1730                         gint financial_year_number )
1731 {
1732     TransactionStruct *transaction;
1733 
1734     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1735 
1736     if ( !transaction )
1737 	return FALSE;
1738 
1739     transaction -> financial_year_number = financial_year_number;
1740 
1741     return TRUE;
1742 }
1743 
1744 
1745 
1746 /** get the budgetary_number
1747  * \param transaction_number the number of the transaction
1748  * \return the budgetary_number of the transaction
1749  * */
gsb_data_transaction_get_budgetary_number(gint transaction_number)1750 gint gsb_data_transaction_get_budgetary_number ( gint transaction_number )
1751 {
1752     TransactionStruct *transaction;
1753 
1754     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1755 
1756     if ( !transaction )
1757 	return -1;
1758 
1759     return transaction -> budgetary_number;
1760 }
1761 
1762 
1763 /** set the budgetary_number
1764  * \param transaction_number
1765  * \param budgetary_number
1766  * \return TRUE if ok
1767  * */
gsb_data_transaction_set_budgetary_number(gint transaction_number,gint budgetary_number)1768 gboolean gsb_data_transaction_set_budgetary_number ( gint transaction_number,
1769                         gint budgetary_number )
1770 {
1771     TransactionStruct *transaction;
1772 
1773     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1774 
1775     if ( !transaction )
1776 	return FALSE;
1777 
1778     transaction -> budgetary_number = budgetary_number;
1779 
1780     return TRUE;
1781 }
1782 
1783 
1784 /** get the  sub_budgetary_number
1785  * \param transaction_number the number of the transaction
1786  * \return the sub_budgetary_number number of the transaction
1787  * */
gsb_data_transaction_get_sub_budgetary_number(gint transaction_number)1788 gint gsb_data_transaction_get_sub_budgetary_number ( gint transaction_number )
1789 {
1790     TransactionStruct *transaction;
1791 
1792     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1793 
1794     if ( !transaction )
1795 	return -1;
1796 
1797     return transaction -> sub_budgetary_number;
1798 }
1799 
1800 
1801 /** set the sub_budgetary_number
1802  * \param transaction_number
1803  * \param sub_budgetary_number
1804  * \return TRUE if ok
1805  * */
gsb_data_transaction_set_sub_budgetary_number(gint transaction_number,gint sub_budgetary_number)1806 gboolean gsb_data_transaction_set_sub_budgetary_number ( gint transaction_number,
1807                         gint sub_budgetary_number )
1808 {
1809     TransactionStruct *transaction;
1810 
1811     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1812 
1813     if ( !transaction )
1814 	return FALSE;
1815 
1816     transaction -> sub_budgetary_number = sub_budgetary_number;
1817 
1818     return TRUE;
1819 }
1820 
1821 
1822 /** get the voucher
1823  * \param transaction_number the number of the transaction
1824  * \return  voucher
1825  * */
gsb_data_transaction_get_voucher(gint transaction_number)1826 const gchar *gsb_data_transaction_get_voucher ( gint transaction_number )
1827 {
1828     TransactionStruct *transaction;
1829 
1830     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1831 
1832     if ( !transaction )
1833 	return NULL;
1834 
1835     return transaction -> voucher;
1836 }
1837 
1838 
1839 /** set the voucher
1840  * it's a copy of the parameter which will be stored in the transaction
1841  * \param transaction_number
1842  * \param voucher. The string is duplicated.
1843  * \return TRUE if ok
1844  * */
gsb_data_transaction_set_voucher(gint transaction_number,const gchar * voucher)1845 gboolean gsb_data_transaction_set_voucher ( gint transaction_number,
1846                         const gchar *voucher )
1847 {
1848     TransactionStruct *transaction;
1849 
1850     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number );
1851     if ( !transaction )
1852         return FALSE;
1853 
1854     g_free ( transaction -> voucher );
1855 
1856     if ( voucher && strlen (voucher) )
1857         transaction -> voucher = my_strdup ( voucher );
1858     else
1859         transaction -> voucher = g_strdup ("");
1860 
1861     return TRUE;
1862 }
1863 
1864 
1865 
1866 /**
1867  * get the bank_references
1868  *
1869  * \param transaction_number the number of the transaction
1870  *
1871  * \return bank_references
1872  * */
gsb_data_transaction_get_bank_references(gint transaction_number)1873 const gchar *gsb_data_transaction_get_bank_references ( gint transaction_number )
1874 {
1875     TransactionStruct *transaction;
1876 
1877     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1878 
1879     if ( !transaction )
1880 	return NULL;
1881 
1882     return transaction -> bank_references;
1883 }
1884 
1885 
1886 /**
1887  * set the bank_references
1888  * it's a copy of the parameter which will be stored in the transaction
1889  *
1890  * \param transaction_number
1891  * \param bank_references. This string may be NULL. If not NULL, the string is duplicated.
1892  *
1893  * \return TRUE if ok
1894  * */
gsb_data_transaction_set_bank_references(gint transaction_number,const gchar * bank_references)1895 gboolean gsb_data_transaction_set_bank_references ( gint transaction_number,
1896                         const gchar *bank_references )
1897 {
1898     TransactionStruct *transaction;
1899 
1900     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1901     if ( !transaction )
1902         return FALSE;
1903 
1904     g_free ( transaction -> bank_references );
1905     transaction -> bank_references = my_strdup ( bank_references );
1906 
1907     return TRUE;
1908 }
1909 
1910 
1911 /**
1912  * get the  transaction_number_transfer
1913  *
1914  * \param transaction_number the number of the transaction
1915  *
1916  * \return the transaction_number_transfer number of the transaction
1917  * */
gsb_data_transaction_get_contra_transaction_number(gint transaction_number)1918 gint gsb_data_transaction_get_contra_transaction_number ( gint transaction_number )
1919 {
1920     TransactionStruct *transaction;
1921 
1922     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1923 
1924     if ( !transaction )
1925 	return -1;
1926 
1927     return transaction -> transaction_number_transfer;
1928 }
1929 
1930 /**
1931  * set the transaction_number_transfer
1932  *
1933  * \param transaction_number
1934  * \param transaction_number_transfer
1935  *
1936  * \return TRUE if ok
1937  * */
gsb_data_transaction_set_contra_transaction_number(gint transaction_number,gint transaction_number_transfer)1938 gboolean gsb_data_transaction_set_contra_transaction_number ( gint transaction_number,
1939                         gint transaction_number_transfer )
1940 {
1941     TransactionStruct *transaction;
1942 
1943     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1944 
1945     if ( !transaction )
1946 	return FALSE;
1947 
1948     transaction -> transaction_number_transfer = transaction_number_transfer;
1949 
1950     return TRUE;
1951 }
1952 
1953 
1954 /**
1955  * get the account number of the contra transaction
1956  * it's not saved into Grisbi, this function avoid just to get the contra-transaction
1957  * and find its account
1958  *
1959  * \param transaction_number the number of the transaction
1960  *
1961  * \return the account number of the contra-transaction
1962  * */
gsb_data_transaction_get_contra_transaction_account(gint transaction_number)1963 gint gsb_data_transaction_get_contra_transaction_account ( gint transaction_number )
1964 {
1965     TransactionStruct *transaction;
1966     TransactionStruct *contra_transaction;
1967 
1968     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
1969 
1970     if ( !transaction )
1971 	return -1;
1972 
1973     contra_transaction = gsb_data_transaction_get_transaction_by_no (transaction -> transaction_number_transfer);
1974     if (!contra_transaction)
1975 	return -1;
1976 
1977     return contra_transaction -> account_number;
1978 }
1979 
1980 
1981 
1982 
1983 /**
1984  * get the  mother_transaction_number
1985  *
1986  * \param transaction_number the number of the transaction
1987  *
1988  * \return the mother_transaction_number of the transaction or 0 if the transaction doen't exist
1989  * */
gsb_data_transaction_get_mother_transaction_number(gint transaction_number)1990 gint gsb_data_transaction_get_mother_transaction_number ( gint transaction_number )
1991 {
1992     TransactionStruct *transaction;
1993 
1994     transaction = gsb_data_transaction_get_transaction_by_no (transaction_number);
1995 
1996     if ( !transaction )
1997 	return 0;
1998 
1999     return transaction -> mother_transaction_number;
2000 }
2001 
2002 
2003 /**
2004  * set the mother_transaction_number
2005  *
2006  * \param transaction_number
2007  * \param mother_transaction_number
2008  *
2009  * \return TRUE if ok
2010  * */
gsb_data_transaction_set_mother_transaction_number(gint transaction_number,gint mother_transaction_number)2011 gboolean gsb_data_transaction_set_mother_transaction_number ( gint transaction_number,
2012                         gint mother_transaction_number )
2013 {
2014     TransactionStruct *transaction;
2015 
2016     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
2017 
2018     if ( !transaction )
2019 	return FALSE;
2020 
2021     transaction -> mother_transaction_number = mother_transaction_number;
2022 
2023     return TRUE;
2024 }
2025 
2026 
2027 
2028 /**
2029  * create a new transaction and append it to the list in the right account
2030  * set the transaction number given in param (if no number, give the last number + 1)
2031  * set the number of the account, the number of the transaction and the currency number
2032  * which is by default the currency of the account
2033  *
2034  * \param no_account the number of the account where the transaction should be made
2035  * \param transaction_number the number of the transaction
2036  *
2037  * \return the number of the new transaction
2038  * */
gsb_data_transaction_new_transaction_with_number(gint no_account,gint transaction_number)2039 gint gsb_data_transaction_new_transaction_with_number ( gint no_account,
2040                         gint transaction_number )
2041 {
2042     TransactionStruct *transaction;
2043 
2044     transaction = g_malloc0 ( sizeof ( TransactionStruct ));
2045 
2046     if ( !transaction )
2047     {
2048 	dialogue_error ( _("Cannot allocate memory, bad things will happen soon") );
2049 	return FALSE;
2050     }
2051 
2052     if ( !transaction_number )
2053 	transaction_number = gsb_data_transaction_get_last_number () + 1;
2054 
2055     transaction -> account_number = no_account;
2056     transaction -> transaction_number = transaction_number;
2057     transaction -> currency_number = gsb_data_account_get_currency (no_account);
2058     transaction -> voucher = g_strdup("");
2059     transaction -> bank_references = g_strdup("");
2060 
2061     /* we append the transaction to the complete transactions list and the non archive transaction list */
2062     transactions_list = g_slist_append ( transactions_list,
2063 					 transaction );
2064     complete_transactions_list = g_slist_append ( complete_transactions_list,
2065 						  transaction );
2066 
2067     gsb_data_transaction_save_transaction_pointer (transaction);
2068 
2069     return transaction -> transaction_number;
2070 }
2071 
2072 
2073 /**
2074  * create a new transaction with gsb_data_transaction_new_transaction_with_number
2075  * but set automatickly the last number
2076  *
2077  * \param no_account the number of the account where the transaction should be made
2078  *
2079  * \return the number of the new transaction
2080  * */
gsb_data_transaction_new_transaction(gint no_account)2081 gint gsb_data_transaction_new_transaction ( gint no_account )
2082 {
2083     return gsb_data_transaction_new_transaction_with_number ( no_account,
2084 							      gsb_data_transaction_get_last_number () + 1);
2085 }
2086 
2087 
2088 /**
2089  * create a new white line
2090  * if there is a mother transaction, it's a split and we increment in the negatives values
2091  * the number of that line
2092  * without mother transaction, it's the general white line, the number is -1
2093  *
2094  * if it's a child split, the account is set as for its mother,
2095  * if it's the last white line, the account is set to -1
2096  * that transaction is appended to the white transactions list
2097  *
2098  * \param mother_transaction_number the number of the mother's transaction if it's a split child ; 0 if not
2099  *
2100  * \return the number of the white line
2101  * */
gsb_data_transaction_new_white_line(gint mother_transaction_number)2102 gint gsb_data_transaction_new_white_line ( gint mother_transaction_number)
2103 {
2104     TransactionStruct *transaction;
2105 
2106     transaction = g_malloc0 ( sizeof ( TransactionStruct ));
2107 
2108     if ( !transaction )
2109     {
2110 	dialogue_error ( _("Cannot allocate memory, bad things will happen soon") );
2111 	return 0;
2112     }
2113 
2114     /* we fill some things for the child split to help to sort the list */
2115 
2116     transaction -> account_number = gsb_data_transaction_get_account_number (mother_transaction_number);
2117 
2118     if ( mother_transaction_number )
2119     {
2120 	transaction -> transaction_number = gsb_data_transaction_get_last_white_number () - 1;
2121 	transaction -> date = gsb_date_copy ( gsb_data_transaction_get_date (mother_transaction_number));
2122 	transaction -> party_number = gsb_data_transaction_get_party_number (mother_transaction_number);
2123 	transaction -> mother_transaction_number = mother_transaction_number;
2124     }
2125     else
2126 	transaction -> transaction_number = -1;
2127 
2128     white_transactions_list = g_slist_append ( white_transactions_list,
2129 					       transaction );
2130 
2131     gsb_data_transaction_save_transaction_pointer (transaction);
2132 
2133     return transaction -> transaction_number;
2134 }
2135 
2136 
2137 
2138 /**
2139  * copy the content of a transaction into the second one
2140  * the 2 transactions must exist before
2141  * only the account_number and the transaction_number will be modified in the target transaction
2142  * all the char are dupplicated,
2143  * 	transaction_id is set to NULL,
2144  * 	marked, reconcile number and archive number are set to 0
2145  *
2146  * \param source_transaction_number the transaction we want to copy
2147  * \param target_transaction_number the trnasaction we want to fill with the content of the first one
2148  * \param reset transaction_id, marked, reconcile number and archive number
2149  *
2150  * \return TRUE if ok, FALSE else
2151  * */
gsb_data_transaction_copy_transaction(gint source_transaction_number,gint target_transaction_number,gboolean reset_mark)2152 gboolean gsb_data_transaction_copy_transaction ( gint source_transaction_number,
2153                         gint target_transaction_number,
2154                         gboolean reset_mark )
2155 {
2156     TransactionStruct *source_transaction;
2157     TransactionStruct *target_transaction;
2158     gint target_transaction_account_number;
2159 
2160     source_transaction = gsb_data_transaction_get_transaction_by_no ( source_transaction_number);
2161     target_transaction = gsb_data_transaction_get_transaction_by_no ( target_transaction_number);
2162 
2163     if ( !source_transaction
2164 	 ||
2165 	 !target_transaction )
2166 	return FALSE;
2167 
2168     /* on sauvegarde le numéro de compte initial */
2169     target_transaction_account_number = target_transaction -> account_number;
2170 
2171     memcpy ( target_transaction,
2172 	     source_transaction,
2173 	     sizeof ( TransactionStruct ));
2174     target_transaction -> transaction_number = target_transaction_number;
2175     target_transaction -> account_number = target_transaction_account_number;
2176     if ( reset_mark )
2177     {
2178         target_transaction -> reconcile_number = 0;
2179         target_transaction -> marked_transaction = 0;
2180         target_transaction -> transaction_id = NULL;
2181     }
2182 
2183     /* make the archive_number */
2184     target_transaction -> archive_number = 0;
2185 
2186     /* make a new copy of all the pointers */
2187     if (source_transaction -> notes)
2188 		target_transaction -> notes = my_strdup ( source_transaction -> notes );
2189 
2190     if (source_transaction -> voucher)
2191 		target_transaction -> voucher = my_strdup ( source_transaction -> voucher );
2192 
2193     if (source_transaction -> bank_references)
2194 		target_transaction -> bank_references = my_strdup ( source_transaction -> bank_references );
2195 
2196     if (source_transaction->date && g_date_valid (source_transaction->date))
2197 		target_transaction -> date = gsb_date_copy (source_transaction -> date);
2198 
2199     if (source_transaction -> value_date)
2200 		target_transaction -> value_date = gsb_date_copy (source_transaction -> value_date);
2201 
2202     if (source_transaction -> method_of_payment_content)
2203 		target_transaction -> method_of_payment_content = my_strdup (source_transaction->method_of_payment_content);
2204 
2205 	return TRUE;
2206 }
2207 
2208 /**
2209  * internal function which is called to free the memory used by a TransactionStruct structure.
2210  */
gsb_data_transaction_free(TransactionStruct * transaction)2211 static void gsb_data_transaction_free ( TransactionStruct *transaction)
2212 {
2213     if ( ! transaction )
2214         return;
2215 
2216     gsb_data_account_set_balances_are_dirty ( transaction -> account_number );
2217 
2218     g_free ( transaction -> transaction_id );
2219     g_free ( transaction -> notes );
2220     g_free ( transaction -> voucher );
2221     g_free ( transaction -> bank_references );
2222     g_free ( transaction -> method_of_payment_content );
2223 
2224     if ( transaction -> date )
2225         g_date_free ( transaction -> date );
2226     if ( transaction -> value_date )
2227         g_date_free ( transaction -> value_date );
2228 
2229     g_free ( transaction );
2230 
2231     transaction_buffer[0] = NULL;
2232     transaction_buffer[1] = NULL;
2233 }
2234 
2235 /**
2236  * remove the transaction from the transaction's list
2237  * free the transaction
2238  * if there is a contra-transaction, remove it too
2239  * if there is some children, remove them and their contra-transaction if they exist
2240  *
2241  * \param transaction_number
2242  *
2243  * \return TRUE if ok
2244  * */
gsb_data_transaction_remove_transaction(gint transaction_number)2245 gboolean gsb_data_transaction_remove_transaction ( gint transaction_number )
2246 {
2247     TransactionStruct *transaction;
2248 
2249     transaction = gsb_data_transaction_get_transaction_by_no (transaction_number);
2250 
2251     if ( !transaction )
2252 	return FALSE;
2253 
2254     /* check if it's a transfer */
2255     if (transaction -> transaction_number_transfer)
2256     {
2257 	TransactionStruct *contra_transaction;
2258 
2259 	contra_transaction = gsb_data_transaction_get_transaction_by_no (transaction -> transaction_number_transfer);
2260 	if (contra_transaction)
2261 	{
2262 	    /* we remove the transaction from the counters */
2263 	    gsb_data_payee_remove_transaction_from_payee (contra_transaction -> transaction_number) ;
2264 	    gsb_data_category_remove_transaction_from_category (contra_transaction -> transaction_number);
2265 	    gsb_data_budget_remove_transaction_from_budget (contra_transaction -> transaction_number);
2266 
2267 	    /* we remove the transaction from the 2 lists */
2268 	    transactions_list = g_slist_remove ( transactions_list,
2269 						 contra_transaction );
2270 	    complete_transactions_list = g_slist_remove ( complete_transactions_list,
2271 							  contra_transaction );
2272 	    gsb_data_transaction_free (contra_transaction);
2273 	}
2274     }
2275 
2276     /* check if it's a split */
2277     if (transaction -> split_of_transaction)
2278     {
2279 	GSList *tmp_list;
2280 
2281 	tmp_list = gsb_data_transaction_get_children (transaction_number, FALSE);
2282 	while (tmp_list)
2283 	{
2284 	    TransactionStruct *child_transaction;
2285 	    TransactionStruct *contra_transaction;
2286 
2287 	    child_transaction = tmp_list -> data;
2288 
2289 	    contra_transaction = gsb_data_transaction_get_transaction_by_no (child_transaction -> transaction_number_transfer);
2290 	    if (contra_transaction)
2291 	    {
2292 		/* it's a transfer, delete the transfer */
2293 
2294 		/* we remove the transaction from the counters */
2295 		gsb_data_payee_remove_transaction_from_payee (contra_transaction -> transaction_number) ;
2296 		gsb_data_category_remove_transaction_from_category (contra_transaction -> transaction_number);
2297 		gsb_data_budget_remove_transaction_from_budget (contra_transaction -> transaction_number);
2298 
2299 		transactions_list = g_slist_remove ( transactions_list,
2300 						     contra_transaction );
2301 		complete_transactions_list = g_slist_remove ( complete_transactions_list,
2302 							      contra_transaction );
2303 		gsb_data_transaction_free (contra_transaction);
2304 	    }
2305 
2306 	    /* delete the child */
2307 	    /* we remove the child from the counters */
2308 	    gsb_data_payee_remove_transaction_from_payee (child_transaction -> transaction_number) ;
2309 	    gsb_data_category_remove_transaction_from_category (child_transaction -> transaction_number);
2310 	    gsb_data_budget_remove_transaction_from_budget (child_transaction -> transaction_number);
2311 
2312 	    transactions_list = g_slist_remove ( transactions_list,
2313 						 child_transaction );
2314 	    complete_transactions_list = g_slist_remove ( complete_transactions_list,
2315 							  child_transaction );
2316 	    gsb_data_transaction_free (child_transaction);
2317 	    tmp_list = tmp_list -> next;
2318 	}
2319     }
2320 
2321     /* we have now to remove the transaction from the counters */
2322     gsb_data_payee_remove_transaction_from_payee (transaction_number);
2323     gsb_data_category_remove_transaction_from_category (transaction_number);
2324     gsb_data_budget_remove_transaction_from_budget (transaction_number);
2325 
2326     /* now can remove safely the transaction */
2327     transactions_list = g_slist_remove ( transactions_list, transaction );
2328     complete_transactions_list = g_slist_remove ( complete_transactions_list, transaction );
2329 
2330     /* force the update module budget */
2331     gsb_data_account_set_bet_maj ( transaction -> account_number, BET_MAJ_ALL );
2332     gsb_file_set_modified ( TRUE );
2333 
2334     gsb_data_transaction_free (transaction);
2335 
2336     return TRUE;
2337 }
2338 
2339 /**
2340  * remove the transaction from the transaction's list
2341  * just do it and only for that transaction, check nothing
2342  * usefull when we need to delete a lot of transactions in one time
2343  * 	(example to delete an archive)
2344  *
2345  * \param transaction_number
2346  *
2347  * \return TRUE if ok
2348  * */
gsb_data_transaction_remove_transaction_without_check(gint transaction_number)2349 gboolean gsb_data_transaction_remove_transaction_without_check ( gint transaction_number )
2350 {
2351     TransactionStruct *transaction;
2352 
2353     transaction = gsb_data_transaction_get_transaction_by_no (transaction_number);
2354 
2355     if ( !transaction )
2356 	return FALSE;
2357 
2358     /* delete the transaction from the lists */
2359     transactions_list = g_slist_remove ( transactions_list,
2360 					 transaction );
2361     complete_transactions_list = g_slist_remove ( complete_transactions_list,
2362 						  transaction );
2363 
2364     /* we free the buffer to avoid big possibly crashes */
2365     transaction_buffer[0] = NULL;
2366     transaction_buffer[1] = NULL;
2367 
2368     g_free (transaction);
2369     return TRUE;
2370 }
2371 
2372 /**
2373  * Delete all transactions and free memory used by them
2374  */
gsb_data_transaction_delete_all_transactions(void)2375 void gsb_data_transaction_delete_all_transactions ( void )
2376 {
2377     if ( complete_transactions_list )
2378     {
2379         GSList* tmp_list = complete_transactions_list;
2380         while ( tmp_list )
2381         {
2382 	    TransactionStruct *transaction;
2383 	    transaction = tmp_list -> data;
2384 	    tmp_list = tmp_list -> next;
2385             gsb_data_transaction_free ( transaction );
2386 	}
2387         g_slist_free ( complete_transactions_list );
2388         complete_transactions_list = NULL;
2389     }
2390     if ( transactions_list )
2391     {
2392         g_slist_free ( transactions_list );
2393         transactions_list = NULL;
2394     }
2395     transaction_buffer[0] = NULL;
2396     transaction_buffer[1] = NULL;
2397     current_transaction_buffer = 0;
2398 }
2399 
2400 /**
2401  * find the children of the split given in param and
2402  * return their adress or their number in a GSList
2403  * the list sould be freed
2404  *
2405  * \param transaction_number a split of transaction
2406  * \param return_number TRUE if we want a list of numbers, FALSE if we want a list of adress
2407  *
2408  * \return a GSList of the address/numbers of the children, NULL if no child
2409  * */
gsb_data_transaction_get_children(gint transaction_number,gboolean return_number)2410 GSList *gsb_data_transaction_get_children ( gint transaction_number,
2411                         gboolean return_number)
2412 {
2413     TransactionStruct *transaction;
2414     GSList *children_list = NULL;
2415     GSList *tmp_list;
2416 
2417     transaction = gsb_data_transaction_get_transaction_by_no (transaction_number);
2418 
2419     if ( !transaction
2420 	 ||
2421 	 !transaction -> split_of_transaction)
2422 	return NULL;
2423 
2424     /* get the normal children */
2425     tmp_list = transactions_list;
2426     while ( tmp_list )
2427     {
2428 	TransactionStruct *tmp_transaction;
2429 
2430 	tmp_transaction = tmp_list -> data;
2431 
2432 	if ( tmp_transaction -> mother_transaction_number == transaction_number )
2433 	{
2434 	    if (return_number)
2435 		children_list = g_slist_append ( children_list,
2436 						 GINT_TO_POINTER (tmp_transaction -> transaction_number));
2437 	    else
2438 		children_list = g_slist_append ( children_list,
2439 						 tmp_transaction);
2440 	}
2441 	tmp_list = tmp_list -> next;
2442     }
2443 
2444     /* get the white line too */
2445     tmp_list = white_transactions_list;
2446     while ( tmp_list )
2447     {
2448 	TransactionStruct *tmp_transaction;
2449 
2450 	tmp_transaction = tmp_list -> data;
2451 
2452 	if ( tmp_transaction -> mother_transaction_number == transaction_number )
2453 	{
2454 	    if (return_number)
2455 		children_list = g_slist_append ( children_list,
2456 						 GINT_TO_POINTER (tmp_transaction -> transaction_number));
2457 	    else
2458 		children_list = g_slist_append ( children_list,
2459 						 tmp_transaction);
2460 	}
2461 	tmp_list = tmp_list -> next;
2462     }
2463 
2464     return children_list;
2465 }
2466 
2467 
2468 /**
2469  * find a transaction by its id
2470  *
2471  * \param id a string containing an id
2472  *
2473  * \return the number of transaction or 0 if none found
2474  * */
gsb_data_transaction_find_by_id(gchar * id,gint account_number)2475 gint gsb_data_transaction_find_by_id ( gchar *id, gint account_number )
2476 {
2477     GSList *tmp_list;
2478 
2479     if ( !id )
2480         return 0;
2481 
2482     tmp_list = g_slist_copy ( transactions_list );
2483 
2484     tmp_list = g_slist_sort (tmp_list,
2485                         (GCompareFunc) classement_sliste_transactions_par_date_decroissante );
2486 
2487     while (tmp_list)
2488     {
2489         TransactionStruct *transaction;
2490 
2491         transaction = tmp_list -> data;
2492 
2493         if ( transaction -> transaction_id
2494          &&
2495          !strcmp ( id, transaction -> transaction_id )
2496          &&
2497          account_number ==  transaction -> account_number )
2498             return transaction -> transaction_number;
2499 
2500         tmp_list = tmp_list -> next;
2501     }
2502 
2503     return 0;
2504 }
2505 
2506 
2507 
2508 /**
2509  * find the white line corresponding to the transaction
2510  * given in param and return the number
2511  * if the transaction is not a split, return -1, the general white line
2512  *
2513  * \param transaction_number a split transaction number
2514  *
2515  * \return the number of the white line of the split or -1
2516  * */
gsb_data_transaction_get_white_line(gint transaction_number)2517 gint gsb_data_transaction_get_white_line ( gint transaction_number )
2518 {
2519     TransactionStruct *transaction;
2520     GSList *tmp_list;
2521 
2522     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
2523 
2524     if ( !transaction
2525 	 ||
2526 	 !transaction -> split_of_transaction)
2527 	return -1;
2528 
2529     tmp_list = white_transactions_list;
2530 
2531     while ( tmp_list )
2532     {
2533 	TransactionStruct *tmp_transaction;
2534 
2535 	tmp_transaction = tmp_list -> data;
2536 
2537 	if ( tmp_transaction -> mother_transaction_number == transaction_number )
2538 	    return tmp_transaction -> transaction_number;
2539 
2540 	tmp_list = tmp_list -> next;
2541     }
2542     return -1;
2543 }
2544 
2545 
2546 /**
2547  * check if a number of cheque is not already used for a automatic numbering method of payment
2548  *
2549  * \param payment_number an automatic numbering method of payment
2550  * \param number the number we want to set as content for that method of payment
2551  * 		(ie the number of cheque...)
2552  *
2553  * \return the number of the transaction if one is found, FALSE if none found, so can use it
2554  * */
gsb_data_transaction_check_content_payment(gint payment_number,const gchar * number)2555 gint gsb_data_transaction_check_content_payment ( gint payment_number,
2556                         const gchar *number )
2557 {
2558     GSList *tmp_list;
2559 
2560     if (!gsb_data_payment_get_automatic_numbering (payment_number))
2561 	/* the method of payment is not an automatic numbering, return TRUE because
2562 	 * can always use this number */
2563 	return FALSE;
2564 
2565     if (!number)
2566 	return FALSE;
2567 
2568     tmp_list = transactions_list;
2569     while (tmp_list)
2570     {
2571 	TransactionStruct *transaction;
2572 
2573 	transaction = tmp_list -> data;
2574 
2575 	if ( transaction -> method_of_payment_number == payment_number
2576 	     &&
2577          transaction -> method_of_payment_content
2578          &&
2579 	     g_ascii_strcasecmp (transaction -> method_of_payment_content, number ) == 0 )
2580 	    return transaction -> transaction_number;
2581 
2582 	tmp_list = tmp_list -> next;
2583     }
2584     return FALSE;
2585 }
2586 
2587 
2588 /**
2589  * return a copy of the g_slist of transactions structure
2590  * sorted by date
2591  *  * THIS IS THE LIST WITHOUT THE ARCHIVED TRANSACTIONS
2592  *
2593  * \param none
2594  *
2595  * \return the slist of transactions structures
2596  * */
gsb_data_transaction_get_metatree_transactions_list(void)2597 GSList *gsb_data_transaction_get_metatree_transactions_list ( void )
2598 {
2599     GSList *list_tmp;
2600 	GrisbiWinEtat *w_etat;
2601 
2602 	w_etat = grisbi_win_get_w_etat ();
2603 
2604     if ( w_etat->metatree_add_archive_in_totals )
2605         list_tmp = g_slist_copy ( complete_transactions_list );
2606     else
2607         list_tmp = g_slist_copy ( transactions_list );
2608 
2609     switch ( w_etat->metatree_sort_transactions )
2610     {
2611         case 1 :
2612         list_tmp = g_slist_sort (list_tmp,
2613                         (GCompareFunc) classement_sliste_transactions_par_date );
2614         break;
2615         case 2 :
2616         list_tmp = g_slist_sort (list_tmp,
2617                         (GCompareFunc) classement_sliste_transactions_par_date_decroissante );
2618         break;
2619         default :
2620         break;
2621     }
2622 
2623     return list_tmp;
2624 }
2625 
2626 
2627 /**
2628  * get the id of the transaction
2629  *
2630  * \param transaction_number the number of the transaction
2631  *
2632  * \return the id of the transaction
2633  * */
gsb_data_transaction_get_id(gint transaction_number)2634 const gchar *gsb_data_transaction_get_id ( gint transaction_number )
2635 {
2636     TransactionStruct *transaction;
2637 
2638     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
2639 
2640     if ( !transaction )
2641         return NULL;
2642 
2643     return transaction -> transaction_id;
2644 }
2645 
2646 
2647 /**
2648  *
2649  *
2650  *
2651  *
2652  * */
gsb_data_transaction_get_last_transaction_with_div_sub_div(gint account_number,gint div_number,gint sub_div_nb,gint type_div)2653 GsbReal gsb_data_transaction_get_last_transaction_with_div_sub_div (
2654                         gint account_number,
2655                         gint div_number,
2656                         gint sub_div_nb,
2657                         gint type_div )
2658 {
2659     GSList *tmp_list;
2660 
2661     tmp_list = g_slist_copy ( transactions_list );
2662 
2663     tmp_list = g_slist_sort (tmp_list,
2664                         (GCompareFunc) classement_sliste_transactions_par_date_decroissante );
2665 
2666     while ( tmp_list )
2667     {
2668         TransactionStruct *transaction;
2669 
2670         transaction = tmp_list -> data;
2671 
2672         if ( type_div == 0
2673          && transaction -> account_number == account_number
2674          && transaction -> category_number == div_number
2675          && transaction -> sub_category_number == sub_div_nb )
2676             return transaction -> transaction_amount;
2677         else if ( type_div == 1
2678          && transaction -> account_number == account_number
2679          && transaction -> budgetary_number == div_number
2680          && transaction -> sub_budgetary_number == sub_div_nb )
2681             return transaction -> transaction_amount;
2682 
2683         tmp_list = tmp_list -> next;
2684     }
2685 
2686     return null_real;
2687 }
2688 
2689 
2690 /**
2691  * get floating point of the currency of the transaction given
2692  *
2693  * \param transaction_number the number of the transaction
2694  *
2695  * \return the floating_point of currency number of the transaction
2696  * */
gsb_data_transaction_get_currency_floating_point(gint transaction_number)2697 gint gsb_data_transaction_get_currency_floating_point ( gint transaction_number )
2698 {
2699     TransactionStruct *transaction;
2700     gint floating_point;
2701 
2702     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number);
2703 
2704     if ( !transaction )
2705         return -1;
2706     else
2707     {
2708         floating_point = gsb_data_currency_get_floating_point ( transaction -> currency_number );
2709         return floating_point;
2710     }
2711 }
2712 
2713 
2714 /**
2715  * remove the transaction from the transaction's list
2716  * not in complete_transaction_list
2717  *
2718  * \param transaction_number
2719  *
2720  * \return TRUE if ok
2721  * */
gsb_data_transaction_remove_transaction_in_transaction_list(gint transaction_number)2722 gboolean gsb_data_transaction_remove_transaction_in_transaction_list ( gint transaction_number )
2723 {
2724     TransactionStruct *transaction;
2725 
2726     transaction = gsb_data_transaction_get_transaction_by_no ( transaction_number );
2727 
2728     if ( !transaction )
2729         return FALSE;
2730 
2731     /* delete the transaction from the lists */
2732     transactions_list = g_slist_remove ( transactions_list, transaction );
2733 
2734     return TRUE;
2735 }
2736 
2737 
2738 /**
2739  * renvoie la liste des opérations concernées par un fichier importé.
2740  *
2741  * \param account_number
2742  * \param first_date_import     date de début de recherche
2743  *
2744  * \return
2745  **/
gsb_import_get_transactions_list_for_import(gint account_number,GDate * first_date_import)2746 GSList *gsb_import_get_transactions_list_for_import (gint account_number,
2747 													 GDate *first_date_import)
2748 {
2749     GSList *tmp_list;
2750     GSList *ope_list = NULL;
2751 	GSList *return_list = NULL;
2752 
2753 	devel_debug (NULL);
2754 
2755 	tmp_list = transactions_list;
2756     while (tmp_list)
2757     {
2758         TransactionStruct *transaction;
2759         GDate *ope_date;
2760 
2761         transaction = tmp_list->data;
2762 
2763         if ( transaction->value_date && g_date_valid (transaction->value_date))
2764             ope_date = transaction->value_date;
2765         else
2766             ope_date = transaction->date;
2767 
2768         if (transaction->account_number == account_number
2769 			&&
2770 			g_date_compare (ope_date, first_date_import) >= 0)
2771         {
2772             ope_list = g_slist_insert_sorted (ope_list,
2773 											  transaction,
2774 											  (GCompareFunc) classement_sliste_transactions_par_date_decroissante);
2775         }
2776 
2777         tmp_list = tmp_list->next;
2778     }
2779 
2780 	tmp_list = ope_list;
2781     while (tmp_list)
2782     {
2783         TransactionStruct *transaction;
2784 
2785         transaction = tmp_list->data;
2786 		return_list = g_slist_append (return_list, GINT_TO_POINTER (transaction->transaction_number));
2787 		tmp_list = tmp_list->next;
2788     }
2789 
2790     g_slist_free (ope_list);
2791 
2792     return return_list;
2793 }
2794 
2795 /*
2796  * get the real name of the category of the transaction
2797  * so return split of transaction, transfer : ..., categ : under_categ
2798  *
2799  * \param transaction the adr of the transaction
2800  *
2801  * \return the real name. It returns a newly allocated string which must be
2802  * freed when no more used.
2803  **/
gsb_data_transaction_get_category_real_name(gint transaction_number)2804 gchar *gsb_data_transaction_get_category_real_name (gint transaction_number)
2805 {
2806     gchar *tmp;
2807     gint contra_transaction_number;
2808 
2809     if (gsb_data_transaction_get_split_of_transaction (transaction_number))
2810 	tmp = g_strdup(_("Split of transaction"));
2811     else
2812     {
2813 	contra_transaction_number = gsb_data_transaction_get_contra_transaction_number (transaction_number);
2814 	switch (contra_transaction_number)
2815 	{
2816 	    case -1:
2817 		/* transfer to deleted account */
2818 		if (gsb_data_transaction_get_amount (transaction_number).mantissa < 0)
2819 		    tmp = g_strdup(_("Transfer to a deleted account"));
2820 		else
2821 		    tmp = g_strdup(_("Transfer from a deleted account"));
2822 		break;
2823 	    case 0:
2824 		/* normal category */
2825 		tmp = gsb_data_category_get_name (gsb_data_transaction_get_category_number (transaction_number),
2826 						   gsb_data_transaction_get_sub_category_number (transaction_number),
2827 						   NULL);
2828 		break;
2829 	    default:
2830 		/* transfer */
2831 		if (gsb_data_transaction_get_amount (transaction_number).mantissa < 0)
2832 		    tmp = g_strdup_printf (_("Transfer to %s"),
2833 					    gsb_data_account_get_name (gsb_data_transaction_get_account_number (contra_transaction_number)));
2834 		else
2835 		    tmp = g_strdup_printf (_("Transfer from %s"),
2836 					    gsb_data_account_get_name (gsb_data_transaction_get_account_number (contra_transaction_number)));
2837 	}
2838     }
2839     return tmp;
2840 }
2841 
2842 /**
2843  *
2844  *
2845  *
2846  *
2847  * */
2848 /* Local Variables: */
2849 /* c-basic-offset: 4 */
2850 /* End: */
2851