1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2019 Maxime DOYEN
4 * This file is part of HomeBank.
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.
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.
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/>.
21 #include "hb-hbfile.h"
22 #include "hb-archive.h"
23 #include "hb-transaction.h"
26 /****************************************************************************/
28 /****************************************************************************/
37 /* our global datas */
38 extern struct HomeBank
*GLOBALS
;
39 extern struct Preferences
*PREFS
;
42 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
45 gboolean
hbfile_file_isbackup(gchar
*filepath
)
47 gboolean retval
= FALSE
;
49 if( filepath
== NULL
)
52 if( g_str_has_suffix(filepath
, "xhb~") || g_str_has_suffix(filepath
, "bak") )
59 gboolean
hbfile_file_hasrevert(gchar
*filepath
)
63 bakfilepath
= hb_filename_new_with_extension(GLOBALS
->xhb_filepath
, "xhb~");
64 GLOBALS
->xhb_hasrevert
= g_file_test(bakfilepath
, G_FILE_TEST_EXISTS
);
66 //todo check here if need to return something
67 return GLOBALS
->xhb_hasrevert
;
72 guint64
hbfile_file_get_time_modified(gchar
*filepath
)
74 guint64 retval
= 0ULL;
78 DB( g_print("\n[hbfile] get time modified\n") );
80 gfile
= g_file_new_for_path(filepath
);
81 gfileinfo
= g_file_query_info (gfile
, G_FILE_ATTRIBUTE_TIME_MODIFIED
, 0, NULL
, NULL
);
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
);
88 g_object_unref(gfile
);
94 void hbfile_file_default(void)
96 DB( g_print("\n[hbfile] default\n") );
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;
104 DB( g_print("- path_hbfile is '%s'\n", PREFS
->path_hbfile
) );
105 DB( g_print("- xhb_filepath is '%s'\n", GLOBALS
->xhb_filepath
) );
111 static gint hbfile_file_load_xhb(gchar *filepath)
122 static void hbfile_file_load_backup_xhb(void)
124 //todo: get from dialog.c, and split between dilaog.c/hbfile.c
131 void hbfile_replace_basecurrency(Currency4217
*curfmt
)
136 DB( g_print("\n[hbfile] replace base currency\n") );
138 oldkcur
= GLOBALS
->kcur
;
139 da_cur_remove(oldkcur
);
140 item
= currency_add_from_user(curfmt
);
141 GLOBALS
->kcur
= item
->key
;
143 DB( g_print(" %d ==> %d %s\n", oldkcur
, GLOBALS
->kcur
, item
->iso_code
) );
147 void hbfile_change_basecurrency(guint32 key
)
152 // set every rate to 0
153 list
= g_hash_table_get_values(GLOBALS
->h_cur
);
156 Currency
*entry
= list
->data
;
158 if(entry
->key
!= GLOBALS
->kcur
)
164 list
= g_list_next(list
);
168 oldkcur
= GLOBALS
->kcur
;
171 // update account with old base currency
172 list
= g_hash_table_get_values(GLOBALS
->h_acc
);
175 Account
*acc
= list
->data
;
177 if( acc
->kcur
== oldkcur
)
180 list
= g_list_next(list
);
185 GLOBALS
->changes_count
++;
189 GList
*hbfile_transaction_get_all(void)
191 GList
*lst_acc
, *lnk_acc
;
197 lst_acc
= g_hash_table_get_values(GLOBALS
->h_acc
);
198 lnk_acc
= g_list_first(lst_acc
);
199 while (lnk_acc
!= NULL
)
201 Account
*acc
= lnk_acc
->data
;
203 //#1674045 ony rely on nosummary
204 //if( (acc->flags & (AF_CLOSED|AF_NOREPORT)) )
205 if( (acc
->flags
& (AF_NOREPORT
)) )
208 lnk_txn
= g_queue_peek_head_link(acc
->txn_queue
);
209 while (lnk_txn
!= NULL
)
211 list
= g_list_append(list
, lnk_txn
->data
);
212 lnk_txn
= g_list_next(lnk_txn
);
216 lnk_acc
= g_list_next(lnk_acc
);
218 g_list_free(lst_acc
);
220 return da_transaction_sort (list
);
224 static GQueue
*hbfile_transaction_get_partial_internal(guint32 minjulian
, guint32 maxjulian
, gushort exclusionflags
)
226 GList
*lst_acc
, *lnk_acc
;
230 txn_queue
= g_queue_new ();
232 lst_acc
= g_hash_table_get_values(GLOBALS
->h_acc
);
233 lnk_acc
= g_list_first(lst_acc
);
234 while (lnk_acc
!= NULL
)
236 Account
*acc
= lnk_acc
->data
;
238 if( (acc
->flags
& exclusionflags
) )
241 lnk_txn
= g_queue_peek_tail_link(acc
->txn_queue
);
242 while (lnk_txn
!= NULL
)
244 Transaction
*txn
= lnk_txn
->data
;
246 if( txn
->date
< minjulian
) //no need to go below mindate
249 if( !(txn
->status
== TXN_STATUS_REMIND
)
250 && (txn
->date
>= minjulian
)
251 && (txn
->date
<= maxjulian
)
254 g_queue_push_head (txn_queue
, txn
);
257 lnk_txn
= g_list_previous(lnk_txn
);
261 lnk_acc
= g_list_next(lnk_acc
);
263 g_list_free(lst_acc
);
269 GQueue
*hbfile_transaction_get_partial(guint32 minjulian
, guint32 maxjulian
)
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
));
277 GQueue
*hbfile_transaction_get_partial_budget(guint32 minjulian
, guint32 maxjulian
)
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
));
285 void hbfile_sanity_check(void)
287 GList
*lst_acc
, *lnk_acc
;
291 DB( g_print("\n[hbfile] !! sanity_check !! \n") );
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
)
298 Account
*acc
= lnk_acc
->data
;
300 lnk_txn
= g_queue_peek_head_link(acc
->txn_queue
);
301 while (lnk_txn
!= NULL
)
303 Transaction
*txn
= lnk_txn
->data
;
305 da_transaction_consistency(txn
);
306 lnk_txn
= g_list_next(lnk_txn
);
308 lnk_acc
= g_list_next(lnk_acc
);
310 g_list_free(lst_acc
);
313 DB( g_print(" - scheduled/template\n") );
314 list
= g_list_first(GLOBALS
->arc_list
);
317 Archive
*entry
= list
->data
;
319 da_archive_consistency(entry
);
320 list
= g_list_next(list
);
324 DB( g_print(" - account\n") );
325 lxxx
= list
= g_hash_table_get_values(GLOBALS
->h_acc
);
328 Account
*item
= list
->data
;
330 da_acc_consistency(item
);
331 list
= g_list_next(list
);
336 DB( g_print(" - payee\n") );
337 lxxx
= list
= g_hash_table_get_values(GLOBALS
->h_pay
);
340 Payee
*item
= list
->data
;
342 da_pay_consistency(item
);
343 list
= g_list_next(list
);
348 DB( g_print(" - category\n") );
349 lxxx
= list
= g_hash_table_get_values(GLOBALS
->h_cat
);
352 Category
*item
= list
->data
;
354 da_cat_consistency(item
);
355 list
= g_list_next(list
);
362 void hbfile_anonymize(void)
364 GList
*lst_acc
, *lnk_acc
;
369 DB( g_print("\n[hbfile] anonymize\n") );
372 hbfile_change_owner(g_strdup("An0nym0us"));
373 GLOBALS
->changes_count
++;
374 GLOBALS
->hbfile_is_new
= TRUE
;
377 hbfile_change_filepath(g_build_filename(PREFS
->path_hbfile
, "anonymized.xhb", NULL
));
380 lxxx
= list
= g_hash_table_get_values(GLOBALS
->h_acc
);
383 Account
*item
= list
->data
;
385 item
->name
= g_strdup_printf("account %d", item
->key
);
386 g_free(item
->number
);
388 g_free(item
->bankname
);
389 item
->bankname
= NULL
;
391 GLOBALS
->changes_count
++;
392 list
= g_list_next(list
);
397 lxxx
= list
= g_hash_table_get_values(GLOBALS
->h_pay
);
400 Payee
*item
= list
->data
;
405 item
->name
= g_strdup_printf("payee %d", item
->key
);
406 GLOBALS
->changes_count
++;
408 list
= g_list_next(list
);
413 lxxx
= list
= g_hash_table_get_values(GLOBALS
->h_cat
);
416 Category
*item
= list
->data
;
421 item
->name
= g_strdup_printf("category %d", item
->key
);
422 GLOBALS
->changes_count
++;
424 list
= g_list_next(list
);
429 lxxx
= list
= g_hash_table_get_values(GLOBALS
->h_tag
);
432 Tag
*item
= list
->data
;
437 item
->name
= g_strdup_printf("tag %d", item
->key
);
438 GLOBALS
->changes_count
++;
440 list
= g_list_next(list
);
445 lxxx
= list
= g_hash_table_get_values(GLOBALS
->h_rul
);
448 Assign
*item
= list
->data
;
453 item
->text
= g_strdup_printf("assign %d", item
->key
);
454 GLOBALS
->changes_count
++;
456 list
= g_list_next(list
);
462 list
= g_list_first(GLOBALS
->arc_list
);
465 Archive
*item
= list
->data
;
468 item
->memo
= g_strdup_printf("archive %d", cnt
++);
469 GLOBALS
->changes_count
++;
471 //later split anonymize also
473 list
= g_list_next(list
);
477 lst_acc
= g_hash_table_get_values(GLOBALS
->h_acc
);
478 lnk_acc
= g_list_first(lst_acc
);
479 while (lnk_acc
!= NULL
)
481 Account
*acc
= lnk_acc
->data
;
483 lnk_txn
= g_queue_peek_head_link(acc
->txn_queue
);
484 while (lnk_txn
!= NULL
)
486 Transaction
*item
= lnk_txn
->data
;
492 item
->memo
= g_strdup_printf("memo %d", item
->date
);
493 GLOBALS
->changes_count
++;
495 if(item
->flags
& OF_SPLIT
)
497 cnt
= da_splits_length (item
->splits
);
500 split
= da_splits_get(item
->splits
, i
);
501 if( split
== NULL
) break;
503 if(split
->memo
!= NULL
)
506 split
->memo
= g_strdup_printf("memo %d", i
);
507 GLOBALS
->changes_count
++;
510 lnk_txn
= g_list_next(lnk_txn
);
512 lnk_acc
= g_list_next(lnk_acc
);
514 g_list_free(lst_acc
);
519 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
522 void hbfile_change_owner(gchar
*owner
)
524 g_free(GLOBALS
->owner
);
525 GLOBALS
->owner
= (owner
!= NULL
) ? owner
: NULL
;
529 void hbfile_change_filepath(gchar
*filepath
)
531 g_free(GLOBALS
->xhb_filepath
);
532 GLOBALS
->xhb_filepath
= (filepath
!= NULL
) ? filepath
: NULL
;
536 void hbfile_cleanup(gboolean file_clear
)
540 DB( g_print("\n[hbfile] cleanup\n") );
541 DB( g_print("- file clear is %d\n", file_clear
) );
544 txn
= g_trash_stack_pop(&GLOBALS
->txn_stk
);
547 da_transaction_free (txn
);
548 txn
= g_trash_stack_pop(&GLOBALS
->txn_stk
);
551 da_transaction_destroy();
552 da_archive_destroy(GLOBALS
->arc_list
);
553 g_hash_table_destroy(GLOBALS
->h_memo
);
561 hbfile_change_owner(NULL
);
564 hbfile_change_filepath(NULL
);
569 void hbfile_setup(gboolean file_clear
)
572 DB( g_print("\n[hbfile] setup\n") );
573 DB( g_print("- file clear is %d\n", file_clear
) );
575 // Allocate data storage
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
;
587 if(file_clear
== TRUE
)
589 hbfile_file_default();
593 GLOBALS
->hbfile_is_new
= FALSE
;
596 hbfile_change_owner(g_strdup(_("Unknown")));
600 GLOBALS
->vehicle_category
= 0;
602 GLOBALS
->auto_smode
= 1;
603 GLOBALS
->auto_nbdays
= 0;
604 GLOBALS
->auto_weekday
= 1;
606 GLOBALS
->changes_count
= 0;
608 GLOBALS
->xhb_hasrevert
= FALSE
;