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