1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2017 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/>.
27 /****************************************************************************/
29 /****************************************************************************/
38 /* our global datas */
39 extern struct HomeBank
*GLOBALS
;
41 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
44 da_pay_free(Payee
*item
)
46 DB( g_print("da_pay_free\n") );
49 DB( g_print(" => %d, %s\n", item
->key
, item
->name
) );
60 DB( g_print("da_pay_malloc\n") );
61 return rc_alloc(sizeof(Payee
));
68 DB( g_print("da_pay_destroy\n") );
69 g_hash_table_destroy(GLOBALS
->h_pay
);
78 DB( g_print("da_pay_new\n") );
79 GLOBALS
->h_pay
= g_hash_table_new_full(g_int_hash
, g_int_equal
, (GDestroyNotify
)g_free
, (GDestroyNotify
)da_pay_free
);
81 // insert our 'no payee'
82 item
= da_pay_malloc();
83 item
->name
= g_strdup("");
88 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
89 static void da_pay_max_key_ghfunc(gpointer key
, Payee
*item
, guint32
*max_key
)
91 *max_key
= MAX(*max_key
, item
->key
);
94 static gboolean
da_pay_name_grfunc(gpointer key
, Payee
*item
, gchar
*name
)
96 if( name
&& item
->name
)
98 if(!strcasecmp(name
, item
->name
))
107 * Return value: the number of elements
112 return g_hash_table_size(GLOBALS
->h_pay
);
117 da_pay_create_none(void)
122 DB( g_print("da_pay_insert none\n") );
124 pay = da_pay_malloc();
125 new_key = g_new0(guint32, 1);
128 pay->name = g_strdup("");
130 DB( g_print(" -> insert id: %d\n", *new_key) );
132 g_hash_table_insert(GLOBALS->h_pay, new_key, pay);
143 * delete an payee from the GHashTable
145 * Return value: TRUE if the key was found and deleted
149 da_pay_remove(guint32 key
)
151 DB( g_print("da_pay_remove %d\n", key
) );
153 return g_hash_table_remove(GLOBALS
->h_pay
, &key
);
159 * insert an payee into the GHashTable
161 * Return value: TRUE if inserted
165 da_pay_insert(Payee
*item
)
169 DB( g_print("da_pay_insert\n") );
171 new_key
= g_new0(guint32
, 1);
172 *new_key
= item
->key
;
173 g_hash_table_insert(GLOBALS
->h_pay
, new_key
, item
);
182 * append a new payee into the GHashTable
184 * Return value: TRUE if inserted
188 da_pay_append(Payee
*item
)
193 DB( g_print("da_pay_append\n") );
195 /* ensure no duplicate */
196 //g_strstrip(item->name);
197 if( item
->name
!= NULL
)
199 existitem
= da_pay_get_by_name( item
->name
);
200 if( existitem
== NULL
)
202 new_key
= g_new0(guint32
, 1);
203 *new_key
= da_pay_get_max_key() + 1;
204 item
->key
= *new_key
;
206 DB( g_print(" -> append id: %d\n", *new_key
) );
208 g_hash_table_insert(GLOBALS
->h_pay
, new_key
, item
);
213 DB( g_print(" -> %s already exist: %d\n", item
->name
, item
->key
) );
219 * da_pay_get_max_key:
221 * Get the biggest key from the GHashTable
223 * Return value: the biggest key value
227 da_pay_get_max_key(void)
231 g_hash_table_foreach(GLOBALS
->h_pay
, (GHFunc
)da_pay_max_key_ghfunc
, &max_key
);
239 * da_pay_get_by_name:
241 * Get an payee structure by its name
243 * Return value: Payee * or NULL if not found
247 da_pay_get_by_name(gchar
*name
)
249 DB( g_print("da_pay_get_by_name\n") );
251 return g_hash_table_find(GLOBALS
->h_pay
, (GHRFunc
)da_pay_name_grfunc
, name
);
259 * Get an payee structure by key
261 * Return value: Payee * or NULL if not found
265 da_pay_get(guint32 key
)
267 //DB( g_print("da_pay_get\n") );
269 return g_hash_table_lookup(GLOBALS
->h_pay
, &key
);
273 void da_pay_consistency(Payee
*item
)
275 g_strstrip(item
->name
);
279 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
284 da_pay_debug_list_ghfunc(gpointer key
, gpointer value
, gpointer user_data
)
289 DB( g_print(" %d :: %s\n", *id
, item
->name
) );
294 da_pay_debug_list(void)
297 DB( g_print("\n** debug **\n") );
299 g_hash_table_foreach(GLOBALS
->h_pay
, da_pay_debug_list_ghfunc
, NULL
);
301 DB( g_print("\n** end debug **\n") );
308 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
311 payee_delete_unused(void)
315 lpay
= list
= g_hash_table_get_values(GLOBALS
->h_pay
);
318 Payee
*entry
= list
->data
;
320 if(entry
->usage_count
<= 0 && entry
->key
> 0)
321 da_pay_remove (entry
->key
);
322 list
= g_list_next(list
);
329 payee_fill_usage(void)
332 GList
*lst_acc
, *lnk_acc
;
336 lpay
= list
= g_hash_table_get_values(GLOBALS
->h_pay
);
339 Payee
*entry
= list
->data
;
340 entry
->usage_count
= 0;
341 list
= g_list_next(list
);
346 lst_acc
= g_hash_table_get_values(GLOBALS
->h_acc
);
347 lnk_acc
= g_list_first(lst_acc
);
348 while (lnk_acc
!= NULL
)
350 Account
*acc
= lnk_acc
->data
;
352 lnk_txn
= g_queue_peek_head_link(acc
->txn_queue
);
353 while (lnk_txn
!= NULL
)
355 Transaction
*txn
= lnk_txn
->data
;
356 Payee
*pay
= da_pay_get (txn
->kpay
);
361 lnk_txn
= g_list_next(lnk_txn
);
364 lnk_acc
= g_list_next(lnk_acc
);
366 g_list_free(lst_acc
);
369 list
= g_list_first(GLOBALS
->arc_list
);
372 Archive
*entry
= list
->data
;
373 Payee
*pay
= da_pay_get (entry
->kpay
);
377 list
= g_list_next(list
);
380 lrul
= list
= g_hash_table_get_values(GLOBALS
->h_rul
);
383 Assign
*entry
= list
->data
;
384 Payee
*pay
= da_pay_get (entry
->kpay
);
389 list
= g_list_next(list
);
397 payee_move(guint32 key1
, guint32 key2
)
399 GList
*lst_acc
, *lnk_acc
;
403 lst_acc
= g_hash_table_get_values(GLOBALS
->h_acc
);
404 lnk_acc
= g_list_first(lst_acc
);
405 while (lnk_acc
!= NULL
)
407 Account
*acc
= lnk_acc
->data
;
409 lnk_txn
= g_queue_peek_head_link(acc
->txn_queue
);
410 while (lnk_txn
!= NULL
)
412 Transaction
*txn
= lnk_txn
->data
;
414 if(txn
->kpay
== key1
)
417 txn
->flags
|= OF_CHANGED
;
419 lnk_txn
= g_list_next(lnk_txn
);
421 lnk_acc
= g_list_next(lnk_acc
);
423 g_list_free(lst_acc
);
426 list
= g_list_first(GLOBALS
->arc_list
);
429 Archive
*entry
= list
->data
;
430 if(entry
->kpay
== key1
)
434 list
= g_list_next(list
);
437 lrul
= list
= g_hash_table_get_values(GLOBALS
->h_rul
);
440 Assign
*entry
= list
->data
;
442 if(entry
->kpay
== key1
)
446 list
= g_list_next(list
);
453 payee_rename(Payee
*item
, const gchar
*newname
)
458 stripname
= g_strdup(newname
);
459 g_strstrip(stripname
);
461 existitem
= da_pay_get_by_name(stripname
);
463 if( existitem
!= NULL
)
465 if( existitem
->key
== item
->key
)
471 item
->name
= g_strdup(stripname
);
482 * payee_append_if_new:
484 * append a new payee into the GHashTable
486 * Return value: true/false + new payee
490 payee_append_if_new(gchar
*name
, Payee
**newpayee
)
492 gboolean retval
= FALSE
;
493 gchar
*stripname
= g_strdup(name
);
496 g_strstrip(stripname
);
497 item
= da_pay_get_by_name(stripname
);
500 item
= da_pay_malloc();
501 item
->name
= g_strdup(stripname
);
505 if( newpayee
!= NULL
)
514 payee_glist_name_compare_func(Payee
*a
, Payee
*b
)
516 return hb_string_utf8_compare(a
->name
, b
->name
);
521 payee_glist_key_compare_func(Payee
*a
, Payee
*b
)
523 return a
->key
- b
->key
;
527 GList
*payee_glist_sorted(gint column
)
529 GList
*list
= g_hash_table_get_values(GLOBALS
->h_pay
);
532 return g_list_sort(list
, (GCompareFunc
)payee_glist_key_compare_func
);
534 return g_list_sort(list
, (GCompareFunc
)payee_glist_name_compare_func
);
540 payee_load_csv(gchar
*filename
, gchar
**error
)
547 const gchar
*encoding
;
550 encoding
= homebank_file_getencoding(filename
);
554 io
= g_io_channel_new_file(filename
, "r", NULL
);
557 DB( g_print(" -> encoding should be %s\n", encoding
) );
558 if( encoding
!= NULL
)
560 g_io_channel_set_encoding(io
, encoding
, NULL
);
565 io_stat
= g_io_channel_read_line(io
, &tmpstr
, NULL
, NULL
, NULL
);
566 if( io_stat
== G_IO_STATUS_EOF
)
568 if( io_stat
== G_IO_STATUS_NORMAL
)
572 DB( g_print("\n + strip\n") );
573 hb_string_strip_crlf(tmpstr
);
575 DB( g_print(" + split '%s'\n", tmpstr
) );
576 str_array
= g_strsplit (tmpstr
, ";", 2);
577 // payee;category : later paymode?
579 nbcol
= g_strv_length (str_array
);
582 *error
= _("invalid CSV format");
584 DB( g_print(" + error %s\n", *error
) );
593 DB( g_print(" add pay:'%s' ?\n", str_array
[0]) );
594 added
= payee_append_if_new(str_array
[0], &pay
);
597 DB( g_print(" added: %p\n", pay
) );
598 GLOBALS
->changes_count
++;
606 DB( g_print(" add cat:'%s'\n", str_array
[1]) );
607 cat
= da_cat_append_ifnew_by_fullname(str_array
[1], FALSE
);
609 DB( g_print(" cat: %p %p\n", cat
, pay
) );
614 DB( g_print(" set default cat to %d\n", cat
->key
) );
615 pay
->kcat
= cat
->key
;
617 GLOBALS
->changes_count
++;
621 g_strfreev (str_array
);
627 g_io_channel_unref (io
);
635 payee_save_csv(gchar
*filename
)
641 io
= g_io_channel_new_file(filename
, "w", NULL
);
644 lpay
= list
= payee_glist_sorted(1);
648 Payee
*item
= list
->data
;
656 Category
*cat
= da_cat_get(item
->kcat
);
660 fullcatname
= da_cat_get_fullname (cat
);
664 if( fullcatname
!= NULL
)
665 outstr
= g_strdup_printf("%s;%s\n", item
->name
, fullcatname
);
667 outstr
= g_strdup_printf("%s;\n", item
->name
);
669 DB( g_print(" + export %s\n", outstr
) );
671 g_io_channel_write_chars(io
, outstr
, -1, NULL
, NULL
);
677 list
= g_list_next(list
);
681 g_io_channel_unref (io
);