]> Dogcows Code - chaz/homebank/blob - src/hb-hbfile.c
import homebank-5.2.4
[chaz/homebank] / src / hb-hbfile.c
1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2019 Maxime DOYEN
3 *
4 * This file is part of HomeBank.
5 *
6 * HomeBank is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * HomeBank is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "homebank.h"
21 #include "hb-hbfile.h"
22 #include "hb-archive.h"
23 #include "hb-transaction.h"
24
25
26 /****************************************************************************/
27 /* Debug macros */
28 /****************************************************************************/
29 #define MYDEBUG 0
30
31 #if MYDEBUG
32 #define DB(x) (x);
33 #else
34 #define DB(x);
35 #endif
36
37 /* our global datas */
38 extern struct HomeBank *GLOBALS;
39 extern struct Preferences *PREFS;
40
41
42 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
43
44
45 gboolean hbfile_file_isbackup(gchar *filepath)
46 {
47 gboolean retval = FALSE;
48
49 if( filepath == NULL )
50 return FALSE;
51
52 if( g_str_has_suffix(filepath, "xhb~") || g_str_has_suffix(filepath, "bak") )
53 retval = TRUE;
54
55 return retval;
56 }
57
58
59 gboolean hbfile_file_hasrevert(gchar *filepath)
60 {
61 gchar *bakfilepath;
62
63 bakfilepath = hb_filename_new_with_extension(GLOBALS->xhb_filepath, "xhb~");
64 GLOBALS->xhb_hasrevert = g_file_test(bakfilepath, G_FILE_TEST_EXISTS);
65 g_free(bakfilepath);
66 //todo check here if need to return something
67 return GLOBALS->xhb_hasrevert;
68 }
69
70
71 //#1750161
72 guint64 hbfile_file_get_time_modified(gchar *filepath)
73 {
74 guint64 retval = 0ULL;
75 GFile *gfile;
76 GFileInfo *gfileinfo;
77
78 DB( g_print("\n[hbfile] get time modified\n") );
79
80 gfile = g_file_new_for_path(filepath);
81 gfileinfo = g_file_query_info (gfile, G_FILE_ATTRIBUTE_TIME_MODIFIED, 0, NULL, NULL);
82 if( gfileinfo )
83 {
84 retval = g_file_info_get_attribute_uint64 (gfileinfo, G_FILE_ATTRIBUTE_TIME_MODIFIED);
85 DB( g_print("- '%s' last access = %lu\n", filepath, retval) );
86 g_object_unref(gfileinfo);
87 }
88 g_object_unref(gfile);
89
90 return retval;
91 }
92
93
94 void hbfile_file_default(void)
95 {
96 DB( g_print("\n[hbfile] default\n") );
97
98 //todo: maybe translate this also
99 hbfile_change_filepath(g_build_filename(PREFS->path_hbfile, "untitled.xhb", NULL));
100 GLOBALS->hbfile_is_new = TRUE;
101 GLOBALS->hbfile_is_bak = FALSE;
102 GLOBALS->xhb_timemodified = 0ULL;
103
104 DB( g_print("- path_hbfile is '%s'\n", PREFS->path_hbfile) );
105 DB( g_print("- xhb_filepath is '%s'\n", GLOBALS->xhb_filepath) );
106 }
107
108
109
110 /*
111 static gint hbfile_file_load_xhb(gchar *filepath)
112 {
113
114
115
116
117
118
119 }
120
121
122 static void hbfile_file_load_backup_xhb(void)
123 {
124 //todo: get from dialog.c, and split between dilaog.c/hbfile.c
125
126
127
128 }
129 */
130
131 void hbfile_replace_basecurrency(Currency4217 *curfmt)
132 {
133 Currency *item;
134 guint32 oldkcur;
135
136 DB( g_print("\n[hbfile] replace base currency\n") );
137
138 oldkcur = GLOBALS->kcur;
139 da_cur_remove(oldkcur);
140 item = currency_add_from_user(curfmt);
141 GLOBALS->kcur = item->key;
142
143 DB( g_print(" %d ==> %d %s\n", oldkcur, GLOBALS->kcur, item->iso_code) );
144 }
145
146
147 void hbfile_change_basecurrency(guint32 key)
148 {
149 GList *list;
150 guint32 oldkcur;
151
152 // set every rate to 0
153 list = g_hash_table_get_values(GLOBALS->h_cur);
154 while (list != NULL)
155 {
156 Currency *entry = list->data;
157
158 if(entry->key != GLOBALS->kcur)
159 {
160 entry->rate = 0.0;
161 entry->mdate = 0;
162 }
163
164 list = g_list_next(list);
165 }
166 g_list_free(list);
167
168 oldkcur = GLOBALS->kcur;
169 GLOBALS->kcur = key;
170
171 // update account with old base currency
172 list = g_hash_table_get_values(GLOBALS->h_acc);
173 while (list != NULL)
174 {
175 Account *acc = list->data;
176
177 if( acc->kcur == oldkcur )
178 acc->kcur = key;
179
180 list = g_list_next(list);
181 }
182 g_list_free(list);
183
184
185 GLOBALS->changes_count++;
186 }
187
188
189 GList *hbfile_transaction_get_all(void)
190 {
191 GList *lst_acc, *lnk_acc;
192 GList *lnk_txn;
193 GList *list;
194
195 list = NULL;
196
197 lst_acc = g_hash_table_get_values(GLOBALS->h_acc);
198 lnk_acc = g_list_first(lst_acc);
199 while (lnk_acc != NULL)
200 {
201 Account *acc = lnk_acc->data;
202
203 //#1674045 ony rely on nosummary
204 //if( (acc->flags & (AF_CLOSED|AF_NOREPORT)) )
205 if( (acc->flags & (AF_NOREPORT)) )
206 goto next_acc;
207
208 lnk_txn = g_queue_peek_head_link(acc->txn_queue);
209 while (lnk_txn != NULL)
210 {
211 list = g_list_append(list, lnk_txn->data);
212 lnk_txn = g_list_next(lnk_txn);
213 }
214
215 next_acc:
216 lnk_acc = g_list_next(lnk_acc);
217 }
218 g_list_free(lst_acc);
219
220 return da_transaction_sort (list);
221 }
222
223
224 static GQueue *hbfile_transaction_get_partial_internal(guint32 minjulian, guint32 maxjulian, gushort exclusionflags)
225 {
226 GList *lst_acc, *lnk_acc;
227 GList *lnk_txn;
228 GQueue *txn_queue;
229
230 txn_queue = g_queue_new ();
231
232 lst_acc = g_hash_table_get_values(GLOBALS->h_acc);
233 lnk_acc = g_list_first(lst_acc);
234 while (lnk_acc != NULL)
235 {
236 Account *acc = lnk_acc->data;
237
238 if( (acc->flags & exclusionflags) )
239 goto next_acc;
240
241 lnk_txn = g_queue_peek_tail_link(acc->txn_queue);
242 while (lnk_txn != NULL)
243 {
244 Transaction *txn = lnk_txn->data;
245
246 if( txn->date < minjulian ) //no need to go below mindate
247 break;
248
249 if( !(txn->status == TXN_STATUS_REMIND)
250 && (txn->date >= minjulian)
251 && (txn->date <= maxjulian)
252 )
253 {
254 g_queue_push_head (txn_queue, txn);
255 }
256
257 lnk_txn = g_list_previous(lnk_txn);
258 }
259
260 next_acc:
261 lnk_acc = g_list_next(lnk_acc);
262 }
263 g_list_free(lst_acc);
264
265 return txn_queue;
266 }
267
268
269 GQueue *hbfile_transaction_get_partial(guint32 minjulian, guint32 maxjulian)
270 {
271 //#1674045 ony rely on nosummary
272 //return hbfile_transaction_get_partial_internal(minjulian, maxjulian, (AF_CLOSED|AF_NOREPORT));
273 return hbfile_transaction_get_partial_internal(minjulian, maxjulian, (AF_NOREPORT));
274 }
275
276
277 GQueue *hbfile_transaction_get_partial_budget(guint32 minjulian, guint32 maxjulian)
278 {
279 //#1674045 ony rely on nosummary
280 //return hbfile_transaction_get_partial_internal(minjulian, maxjulian, (AF_CLOSED|AF_NOREPORT|AF_NOBUDGET));
281 return hbfile_transaction_get_partial_internal(minjulian, maxjulian, (AF_NOREPORT|AF_NOBUDGET));
282 }
283
284
285 void hbfile_sanity_check(void)
286 {
287 GList *lst_acc, *lnk_acc;
288 GList *lnk_txn;
289 GList *lxxx, *list;
290
291 DB( g_print("\n[hbfile] !! sanity_check !! \n") );
292
293 DB( g_print(" - transaction\n") );
294 lst_acc = g_hash_table_get_values(GLOBALS->h_acc);
295 lnk_acc = g_list_first(lst_acc);
296 while (lnk_acc != NULL)
297 {
298 Account *acc = lnk_acc->data;
299
300 lnk_txn = g_queue_peek_head_link(acc->txn_queue);
301 while (lnk_txn != NULL)
302 {
303 Transaction *txn = lnk_txn->data;
304
305 da_transaction_consistency(txn);
306 lnk_txn = g_list_next(lnk_txn);
307 }
308 lnk_acc = g_list_next(lnk_acc);
309 }
310 g_list_free(lst_acc);
311
312
313 DB( g_print(" - scheduled/template\n") );
314 list = g_list_first(GLOBALS->arc_list);
315 while (list != NULL)
316 {
317 Archive *entry = list->data;
318
319 da_archive_consistency(entry);
320 list = g_list_next(list);
321 }
322
323
324 DB( g_print(" - account\n") );
325 lxxx = list = g_hash_table_get_values(GLOBALS->h_acc);
326 while (list != NULL)
327 {
328 Account *item = list->data;
329
330 da_acc_consistency(item);
331 list = g_list_next(list);
332 }
333 g_list_free(lxxx);
334
335
336 DB( g_print(" - payee\n") );
337 lxxx = list = g_hash_table_get_values(GLOBALS->h_pay);
338 while (list != NULL)
339 {
340 Payee *item = list->data;
341
342 da_pay_consistency(item);
343 list = g_list_next(list);
344 }
345 g_list_free(lxxx);
346
347
348 DB( g_print(" - category\n") );
349 lxxx = list = g_hash_table_get_values(GLOBALS->h_cat);
350 while (list != NULL)
351 {
352 Category *item = list->data;
353
354 da_cat_consistency(item);
355 list = g_list_next(list);
356 }
357 g_list_free(lxxx);
358
359 }
360
361
362 void hbfile_anonymize(void)
363 {
364 GList *lst_acc, *lnk_acc;
365 GList *lnk_txn;
366 GList *lxxx, *list;
367 guint cnt, i;
368
369 DB( g_print("\n[hbfile] anonymize\n") );
370
371 // owner
372 hbfile_change_owner(g_strdup("An0nym0us"));
373 GLOBALS->changes_count++;
374 GLOBALS->hbfile_is_new = TRUE;
375
376 // filename
377 hbfile_change_filepath(g_build_filename(PREFS->path_hbfile, "anonymized.xhb", NULL));
378
379 // accounts
380 lxxx = list = g_hash_table_get_values(GLOBALS->h_acc);
381 while (list != NULL)
382 {
383 Account *item = list->data;
384 g_free(item->name);
385 item->name = g_strdup_printf("account %d", item->key);
386 g_free(item->number);
387 item->number = NULL;
388 g_free(item->bankname);
389 item->bankname = NULL;
390
391 GLOBALS->changes_count++;
392 list = g_list_next(list);
393 }
394 g_list_free(lxxx);
395
396 //payees
397 lxxx = list = g_hash_table_get_values(GLOBALS->h_pay);
398 while (list != NULL)
399 {
400 Payee *item = list->data;
401
402 if(item->key != 0)
403 {
404 g_free(item->name);
405 item->name = g_strdup_printf("payee %d", item->key);
406 GLOBALS->changes_count++;
407 }
408 list = g_list_next(list);
409 }
410 g_list_free(lxxx);
411
412 //categories
413 lxxx = list = g_hash_table_get_values(GLOBALS->h_cat);
414 while (list != NULL)
415 {
416 Category *item = list->data;
417
418 if(item->key != 0)
419 {
420 g_free(item->name);
421 item->name = g_strdup_printf("category %d", item->key);
422 GLOBALS->changes_count++;
423 }
424 list = g_list_next(list);
425 }
426 g_list_free(lxxx);
427
428 //tags
429 lxxx = list = g_hash_table_get_values(GLOBALS->h_tag);
430 while (list != NULL)
431 {
432 Tag *item = list->data;
433
434 if(item->key != 0)
435 {
436 g_free(item->name);
437 item->name = g_strdup_printf("tag %d", item->key);
438 GLOBALS->changes_count++;
439 }
440 list = g_list_next(list);
441 }
442 g_list_free(lxxx);
443
444 //assigns
445 lxxx = list = g_hash_table_get_values(GLOBALS->h_rul);
446 while (list != NULL)
447 {
448 Assign *item = list->data;
449
450 if(item->key != 0)
451 {
452 g_free(item->text);
453 item->text = g_strdup_printf("assign %d", item->key);
454 GLOBALS->changes_count++;
455 }
456 list = g_list_next(list);
457 }
458 g_list_free(lxxx);
459
460 //archives
461 cnt = 0;
462 list = g_list_first(GLOBALS->arc_list);
463 while (list != NULL)
464 {
465 Archive *item = list->data;
466
467 g_free(item->memo);
468 item->memo = g_strdup_printf("archive %d", cnt++);
469 GLOBALS->changes_count++;
470
471 //later split anonymize also
472
473 list = g_list_next(list);
474 }
475
476 //transaction
477 lst_acc = g_hash_table_get_values(GLOBALS->h_acc);
478 lnk_acc = g_list_first(lst_acc);
479 while (lnk_acc != NULL)
480 {
481 Account *acc = lnk_acc->data;
482
483 lnk_txn = g_queue_peek_head_link(acc->txn_queue);
484 while (lnk_txn != NULL)
485 {
486 Transaction *item = lnk_txn->data;
487 Split *split;
488
489 g_free(item->info);
490 item->info = NULL;
491 g_free(item->memo);
492 item->memo = g_strdup_printf("memo %d", item->date);
493 GLOBALS->changes_count++;
494
495 if(item->flags & OF_SPLIT)
496 {
497 cnt = da_splits_length (item->splits);
498 for(i=0;i<cnt;i++)
499 {
500 split = da_splits_get(item->splits, i);
501 if( split == NULL ) break;
502
503 if(split->memo != NULL)
504 g_free(split->memo);
505
506 split->memo = g_strdup_printf("memo %d", i);
507 GLOBALS->changes_count++;
508 }
509 }
510 lnk_txn = g_list_next(lnk_txn);
511 }
512 lnk_acc = g_list_next(lnk_acc);
513 }
514 g_list_free(lst_acc);
515
516 }
517
518
519 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
520
521
522 void hbfile_change_owner(gchar *owner)
523 {
524 g_free(GLOBALS->owner);
525 GLOBALS->owner = (owner != NULL) ? owner : NULL;
526 }
527
528
529 void hbfile_change_filepath(gchar *filepath)
530 {
531 g_free(GLOBALS->xhb_filepath);
532 GLOBALS->xhb_filepath = (filepath != NULL) ? filepath : NULL;
533 }
534
535
536 void hbfile_cleanup(gboolean file_clear)
537 {
538 Transaction *txn;
539
540 DB( g_print("\n[hbfile] cleanup\n") );
541 DB( g_print("- file clear is %d\n", file_clear) );
542
543 // Free data storage
544 txn = g_trash_stack_pop(&GLOBALS->txn_stk);
545 while( txn != NULL )
546 {
547 da_transaction_free (txn);
548 txn = g_trash_stack_pop(&GLOBALS->txn_stk);
549 }
550
551 da_transaction_destroy();
552 da_archive_destroy(GLOBALS->arc_list);
553 g_hash_table_destroy(GLOBALS->h_memo);
554 da_asg_destroy();
555 da_tag_destroy();
556 da_cat_destroy();
557 da_pay_destroy();
558 da_acc_destroy();
559 da_cur_destroy();
560
561 hbfile_change_owner(NULL);
562
563 if(file_clear)
564 hbfile_change_filepath(NULL);
565
566 }
567
568
569 void hbfile_setup(gboolean file_clear)
570 {
571
572 DB( g_print("\n[hbfile] setup\n") );
573 DB( g_print("- file clear is %d\n", file_clear) );
574
575 // Allocate data storage
576 da_cur_new();
577 da_acc_new();
578 da_pay_new();
579 da_cat_new();
580 da_tag_new();
581 da_asg_new();
582
583 GLOBALS->h_memo = g_hash_table_new_full(g_str_hash, g_str_equal, (GDestroyNotify)g_free, NULL);
584 GLOBALS->arc_list = NULL;
585 GLOBALS->txn_stk = NULL;
586
587 if(file_clear == TRUE)
588 {
589 hbfile_file_default();
590 }
591 else
592 {
593 GLOBALS->hbfile_is_new = FALSE;
594 }
595
596 hbfile_change_owner(g_strdup(_("Unknown")));
597
598 GLOBALS->kcur = 1;
599
600 GLOBALS->vehicle_category = 0;
601
602 GLOBALS->auto_smode = 1;
603 GLOBALS->auto_nbdays = 0;
604 GLOBALS->auto_weekday = 1;
605
606 GLOBALS->changes_count = 0;
607
608 GLOBALS->xhb_hasrevert = FALSE;
609
610 }
611
This page took 0.056077 seconds and 4 git commands to generate.