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