1 /* ************************************************************************** */
2 /* */
3 /* */
4 /* Copyright (C) 2000-2007 Cédric Auger (cedric@grisbi.org) */
5 /* 2003-2007 Benjamin Drieu (bdrieu@april.org) */
6 /* https://www.grisbi.org/ */
7 /* */
8 /* This program is free software; you can redistribute it and/or modify */
9 /* it under the terms of the GNU General Public License as published by */
10 /* the Free Software Foundation; either version 2 of the License, or */
11 /* (at your option) any later version. */
12 /* */
13 /* This program is distributed in the hope that it will be useful, */
14 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
15 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
16 /* GNU General Public License for more details. */
17 /* */
18 /* You should have received a copy of the GNU General Public License */
19 /* along with this program; if not, write to the Free Software */
20 /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
21 /* */
22 /* ************************************************************************** */
23
24 /**
25 * \file gsb_data_archive.c
26 * work with the archive structure, no GUI here
27 */
28
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include "include.h"
35
36 /*START_INCLUDE*/
37 #include "gsb_data_archive.h"
38 #include "dialog.h"
39 #include "gsb_data_transaction.h"
40 #include "utils_dates.h"
41 #include "utils_str.h"
42 /*END_INCLUDE*/
43
44
45 /**
46 * \struct
47 * Describe a archive
48 */
49 typedef struct
50 {
51 gint archive_number;
52 gchar *archive_name;
53
54 /* for the archive created by date,
55 * else the 2 values are NULL */
56 GDate *beginning_date;
57 GDate *end_date;
58
59 /* for the archive created by financial year,
60 * else the value is 0 */
61 gint fyear_number;
62
63 /* if created by report, this is the title of
64 * the report */
65 gchar *report_title;
66 } struct_archive;
67
68 /*START_STATIC*/
69 static void _gsb_data_archive_free ( struct_archive* archive);
70 static gpointer gsb_data_archive_get_structure ( gint archive_number );
71 static gint gsb_data_archive_max_number ( void );
72 /*END_STATIC*/
73
74 /*START_EXTERN*/
75 /*END_EXTERN*/
76
77 /** contains the g_slist of struct_archive */
78 static GSList *archive_list = NULL;
79
80 /** a pointer to the last archive used (to increase the speed) */
81 static struct_archive *archive_buffer;
82
83
84 /**
85 * set the archives global variables to NULL,
86 * usually when we init all the global variables
87 *
88 * \param
89 *
90 * \return FALSE
91 * */
gsb_data_archive_init_variables(void)92 gboolean gsb_data_archive_init_variables ( void )
93 {
94 if ( archive_list )
95 {
96 g_slist_free_full ( archive_list, (GDestroyNotify) _gsb_data_archive_free );
97 archive_list = NULL;
98 }
99
100 archive_buffer = NULL;
101
102 return FALSE;
103 }
104
105
106 /**
107 * find and return the structure of the archive asked
108 *
109 * \param archive_number number of archive
110 *
111 * \return the adr of the struct of the archive (NULL if doesn't exit)
112 * */
gsb_data_archive_get_structure(gint archive_number)113 gpointer gsb_data_archive_get_structure ( gint archive_number )
114 {
115 GSList *tmp;
116
117 if (!archive_number)
118 return NULL;
119
120 /* before checking all the archives, we check the buffer */
121
122 if ( archive_buffer
123 &&
124 archive_buffer -> archive_number == archive_number )
125 return archive_buffer;
126
127 tmp = archive_list;
128
129 while ( tmp )
130 {
131 struct_archive *archive;
132
133 archive = tmp -> data;
134
135 if ( archive -> archive_number == archive_number )
136 {
137 archive_buffer = archive;
138 return archive;
139 }
140
141 tmp = tmp -> next;
142 }
143 return NULL;
144 }
145
146
147 /**
148 * give the g_slist of archives structure
149 * usefull when want to check all archives
150 *
151 * \param none
152 *
153 * \return the g_slist of archives structure
154 * */
gsb_data_archive_get_archives_list(void)155 GSList *gsb_data_archive_get_archives_list ( void )
156 {
157 return archive_list;
158 }
159
160 /**
161 * return the number of the archives given in param
162 *
163 * \param archive_ptr a pointer to the struct of the archive
164 *
165 * \return the number of the archive, 0 if problem
166 * */
gsb_data_archive_get_no_archive(gpointer archive_ptr)167 gint gsb_data_archive_get_no_archive ( gpointer archive_ptr )
168 {
169 struct_archive *archive;
170
171 if ( !archive_ptr )
172 return 0;
173
174 archive = archive_ptr;
175 archive_buffer = archive;
176 return archive -> archive_number;
177 }
178
179
180 /**
181 * find and return the last number of archive
182 *
183 * \param none
184 *
185 * \return last number of archive
186 * */
gsb_data_archive_max_number(void)187 gint gsb_data_archive_max_number ( void )
188 {
189 GSList *tmp;
190 gint number_tmp = 0;
191
192 tmp = archive_list;
193
194 while ( tmp )
195 {
196 struct_archive *archive;
197
198 archive = tmp -> data;
199
200 if ( archive -> archive_number > number_tmp )
201 number_tmp = archive -> archive_number;
202
203 tmp = tmp -> next;
204 }
205 return number_tmp;
206 }
207
208
209 /**
210 * create a new archive, give him a number, append it to the list
211 * and return the number
212 *
213 * \param name the name of the archive (can be freed after, it's a copy) or NULL
214 *
215 * \return the number of the new archive
216 * */
gsb_data_archive_new(const gchar * name)217 gint gsb_data_archive_new ( const gchar *name )
218 {
219 struct_archive *archive;
220
221 archive = g_malloc0 ( sizeof ( struct_archive ));
222 if (!archive)
223 {
224 dialogue_error_memory ();
225 return 0;
226 }
227 archive -> archive_number = gsb_data_archive_max_number () + 1;
228
229 if (name)
230 archive -> archive_name = my_strdup (name);
231 else
232 archive -> archive_name = NULL;
233
234 archive_list = g_slist_append ( archive_list, archive );
235 archive_buffer = archive;
236
237 return archive -> archive_number;
238 }
239
240 /**
241 * This internal function is called to free the memory used by an struct_archive structure
242 */
_gsb_data_archive_free(struct_archive * archive)243 static void _gsb_data_archive_free ( struct_archive* archive)
244 {
245 if ( ! archive )
246 return;
247 if ( archive -> archive_name )
248 g_free ( archive -> archive_name );
249 if ( archive -> beginning_date )
250 g_date_free ( archive -> beginning_date );
251 if ( archive -> end_date )
252 g_date_free ( archive -> end_date );
253 if ( archive -> report_title )
254 g_free ( archive -> report_title );
255 g_free ( archive );
256 if ( archive_buffer == archive )
257 archive_buffer = NULL;
258 }
259
260 /**
261 * remove an archive
262 * remove too the archive from the transactions linked to it
263 *
264 * \param archive_number the archive we want to remove
265 *
266 * \return TRUE ok
267 * */
gsb_data_archive_remove(gint archive_number)268 gboolean gsb_data_archive_remove ( gint archive_number )
269 {
270 struct_archive *archive;
271 GSList *tmp_list;
272
273 archive = gsb_data_archive_get_structure ( archive_number );
274
275 if (!archive)
276 return FALSE;
277
278 /* remove the archive from the transactions */
279 tmp_list = gsb_data_transaction_get_complete_transactions_list ();
280 while (tmp_list)
281 {
282 gint transaction_number;
283
284 transaction_number = gsb_data_transaction_get_transaction_number (tmp_list -> data);
285 if (gsb_data_transaction_get_archive_number (transaction_number) == archive -> archive_number)
286 gsb_data_transaction_set_archive_number ( transaction_number,
287 0 );
288 tmp_list = tmp_list -> next;
289 }
290
291 /* remove the archive from the list */
292 archive_list = g_slist_remove ( archive_list,
293 archive );
294
295 _gsb_data_archive_free (archive);
296
297 return TRUE;
298 }
299
300
301 /**
302 * set a new number for the archive
303 * normally used only while loading the file because
304 * the number are given automaticly
305 *
306 * \param archive_number the number of the archive
307 * \param new_no_archive the new number of the archive
308 *
309 * \return the new number or 0 if the archive doen't exist
310 * */
gsb_data_archive_set_new_number(gint archive_number,gint new_no_archive)311 gint gsb_data_archive_set_new_number ( gint archive_number,
312 gint new_no_archive )
313 {
314 struct_archive *archive;
315
316 archive = gsb_data_archive_get_structure ( archive_number );
317
318 if (!archive)
319 return 0;
320
321 archive -> archive_number = new_no_archive;
322 return new_no_archive;
323 }
324
325
326 /**
327 * return the name of the archive
328 *
329 * \param archive_number the number of the archive
330 *
331 * \return the name of the archive or NULL if fail
332 * */
gsb_data_archive_get_name(gint archive_number)333 const gchar *gsb_data_archive_get_name ( gint archive_number )
334 {
335 struct_archive *archive;
336
337 archive = gsb_data_archive_get_structure ( archive_number );
338
339 if (!archive)
340 return NULL;
341
342 return archive -> archive_name;
343 }
344
345
346 /**
347 * set the name of the archive
348 * the value is dupplicate in memory
349 *
350 * \param archive_number the number of the archive
351 * \param name the name of the archive
352 *
353 * \return TRUE if ok or FALSE if problem
354 * */
gsb_data_archive_set_name(gint archive_number,const gchar * name)355 gboolean gsb_data_archive_set_name ( gint archive_number,
356 const gchar *name )
357 {
358 struct_archive *archive;
359
360 archive = gsb_data_archive_get_structure ( archive_number );
361
362 if (!archive)
363 return FALSE;
364
365 /* we free the last name */
366 if ( archive -> archive_name )
367 g_free (archive -> archive_name);
368
369 /* and copy the new one */
370 archive -> archive_name = my_strdup (name);
371
372 return TRUE;
373 }
374
375
376
377 /**
378 * return the beginning date of the archive
379 *
380 * \param archive_number the number of the archive
381 *
382 * \return the beginning date of the archive or NULL if fail
383 * */
gsb_data_archive_get_beginning_date(gint archive_number)384 GDate *gsb_data_archive_get_beginning_date ( gint archive_number )
385 {
386 struct_archive *archive;
387
388 archive = gsb_data_archive_get_structure ( archive_number );
389
390 if (!archive)
391 return NULL;
392
393 return archive -> beginning_date;
394 }
395
396
397 /**
398 * set the beginning date of the archive
399 * the value is dupplicate in memory
400 *
401 * \param archive_number the number of the archive
402 * \param date the beginning date of the archive
403 *
404 * \return TRUE if ok or FALSE if problem
405 * */
gsb_data_archive_set_beginning_date(gint archive_number,const GDate * date)406 gboolean gsb_data_archive_set_beginning_date ( gint archive_number,
407 const GDate *date )
408 {
409 struct_archive *archive;
410
411 archive = gsb_data_archive_get_structure ( archive_number );
412
413 if (!archive)
414 return FALSE;
415
416 /* we free the last date */
417 if ( archive -> beginning_date )
418 g_date_free (archive -> beginning_date);
419
420 /* and copy the new one */
421 archive -> beginning_date = gsb_date_copy (date);
422
423 return TRUE;
424 }
425
426
427 /**
428 * return the end date of the archive
429 *
430 * \param archive_number the number of the archive
431 *
432 * \return the end date of the archive or NULL if fail
433 * */
gsb_data_archive_get_end_date(gint archive_number)434 GDate *gsb_data_archive_get_end_date ( gint archive_number )
435 {
436 struct_archive *archive;
437
438 archive = gsb_data_archive_get_structure ( archive_number );
439
440 if (!archive)
441 return NULL;
442
443 return archive -> end_date;
444 }
445
446
447 /**
448 * set the end date of the archive
449 * the value is dupplicate in memory
450 *
451 * \param archive_number the number of the archive
452 * \param date the end date of the archive
453 *
454 * \return TRUE if ok or FALSE if problem
455 * */
gsb_data_archive_set_end_date(gint archive_number,const GDate * date)456 gboolean gsb_data_archive_set_end_date ( gint archive_number,
457 const GDate *date )
458 {
459 struct_archive *archive;
460
461 archive = gsb_data_archive_get_structure ( archive_number );
462
463 if (!archive)
464 return FALSE;
465
466 /* we free the last date */
467 if ( archive -> end_date )
468 g_date_free (archive -> end_date);
469
470 /* and copy the new one */
471 archive -> end_date = gsb_date_copy (date);
472
473 return TRUE;
474 }
475
476 /**
477 * return the fyear of the archive
478 *
479 * \param archive_number the number of the archive
480 *
481 * \return the fyear of the archive or 0 if fail
482 * */
gsb_data_archive_get_fyear(gint archive_number)483 gint gsb_data_archive_get_fyear ( gint archive_number )
484 {
485 struct_archive *archive;
486
487 archive = gsb_data_archive_get_structure ( archive_number );
488
489 if (!archive)
490 return 0;
491
492 return archive -> fyear_number;
493 }
494
495
496 /**
497 * set the fyear of the archive
498 *
499 * \param archive_number the number of the archive
500 * \param fyear_number the fyear of the archive
501 *
502 * \return TRUE if ok or FALSE if problem
503 * */
gsb_data_archive_set_fyear(gint archive_number,gint fyear_number)504 gboolean gsb_data_archive_set_fyear ( gint archive_number,
505 gint fyear_number )
506 {
507 struct_archive *archive;
508
509 archive = gsb_data_archive_get_structure ( archive_number );
510
511 if (!archive)
512 return FALSE;
513
514 archive -> fyear_number = fyear_number;
515
516 return TRUE;
517 }
518
519
520 /**
521 * return the report creation of the archive
522 *
523 * \param archive_number the number of the archive
524 *
525 * \return the report_title or NULL
526 * */
gsb_data_archive_get_report_title(gint archive_number)527 const gchar *gsb_data_archive_get_report_title ( gint archive_number )
528 {
529 struct_archive *archive;
530
531 archive = gsb_data_archive_get_structure ( archive_number );
532
533 if (!archive)
534 return NULL;
535
536 return archive -> report_title;
537 }
538
539
540 /**
541 * set the report_title value,
542 *
543 * \param archive_number the number of the archive
544 * \param report_title the title to set if created by a report
545 *
546 * \return TRUE if ok or FALSE if problem
547 * */
gsb_data_archive_set_report_title(gint archive_number,const gchar * report_title)548 gboolean gsb_data_archive_set_report_title ( gint archive_number,
549 const gchar *report_title )
550 {
551 struct_archive *archive;
552
553 archive = gsb_data_archive_get_structure ( archive_number );
554
555 if (!archive)
556 return FALSE;
557
558 if (archive -> report_title)
559 g_free (archive -> report_title);
560
561 archive -> report_title = my_strdup (report_title);
562
563 return TRUE;
564 }
565
566
567
568 /**
569 * get the archive corresponding to the given date
570 * if there is more than 1 archive corresponding to that date, return -1
571 *
572 * \param date
573 *
574 * \return the number of archive, 0 if none on that date, -1 if more than 1 on that date
575 * */
gsb_data_archive_get_from_date(const GDate * date)576 gint gsb_data_archive_get_from_date ( const GDate *date )
577 {
578 GSList *tmp_list;
579 gint return_value = 0;
580
581 if (!date)
582 return 0;
583
584 tmp_list = archive_list;
585 while (tmp_list)
586 {
587 struct_archive *archive;
588
589 archive = tmp_list -> data;
590
591 /* check the archive only if the dates are valid */
592 if (archive -> beginning_date && archive -> end_date)
593 {
594 if ( g_date_compare ( date, archive -> beginning_date) >= 0
595 &&
596 g_date_compare ( date, archive -> end_date) <= 0 )
597 {
598 if (return_value)
599 return_value = -1;
600 else
601 return_value = archive -> archive_number;
602 }
603 }
604 tmp_list = tmp_list -> next;
605 }
606 return return_value;
607 }
608
609
610
611
612 /**
613 * get the archive corresponding to the given financial year
614 *
615 * \param fyear_number
616 *
617 * \return the number of archive, 0 if none
618 * */
gsb_data_archive_get_from_fyear(gint fyear_number)619 gint gsb_data_archive_get_from_fyear ( gint fyear_number )
620 {
621 GSList *tmp_list;
622
623 tmp_list = archive_list;
624 while (tmp_list)
625 {
626 struct_archive *archive;
627
628 archive = tmp_list -> data;
629
630 if (archive -> fyear_number == fyear_number)
631 return archive -> archive_number;
632
633 tmp_list = tmp_list -> next;
634 }
635 return 0;
636 }
637
638
639
640