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/>.
24 /****************************************************************************/
26 /****************************************************************************/
35 /* our global datas */
36 extern struct HomeBank
*GLOBALS
;
38 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
45 da_pay_free(Payee
*item
)
47 DB( g_print("da_pay_free\n") );
50 DB( g_print(" => %d, %s\n", item
->key
, item
->name
) );
61 DB( g_print("da_pay_malloc\n") );
62 return g_malloc0(sizeof(Payee
));
69 DB( g_print("da_pay_destroy\n") );
70 g_hash_table_destroy(GLOBALS
->h_pay
);
79 DB( g_print("da_pay_new\n") );
80 GLOBALS
->h_pay
= g_hash_table_new_full(g_int_hash
, g_int_equal
, (GDestroyNotify
)g_free
, (GDestroyNotify
)da_pay_free
);
82 // insert our 'no payee'
83 item
= da_pay_malloc();
84 item
->name
= g_strdup("");
89 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
94 * Return value: the number of elements
99 return g_hash_table_size(GLOBALS
->h_pay
);
104 da_pay_max_key_ghfunc(gpointer key
, Payee
*item
, guint32
*max_key
)
106 *max_key
= MAX(*max_key
, item
->key
);
111 * da_pay_get_max_key:
113 * Get the biggest key from the GHashTable
115 * Return value: the biggest key value
119 da_pay_get_max_key(void)
123 g_hash_table_foreach(GLOBALS
->h_pay
, (GHFunc
)da_pay_max_key_ghfunc
, &max_key
);
131 * delete an payee from the GHashTable
133 * Return value: TRUE if the key was found and deleted
137 da_pay_remove(guint32 key
)
139 DB( g_print("da_pay_remove %d\n", key
) );
141 return g_hash_table_remove(GLOBALS
->h_pay
, &key
);
148 * insert an payee into the GHashTable
150 * Return value: TRUE if inserted
154 da_pay_insert(Payee
*item
)
158 DB( g_print("da_pay_insert\n") );
160 new_key
= g_new0(guint32
, 1);
161 *new_key
= item
->key
;
162 g_hash_table_insert(GLOBALS
->h_pay
, new_key
, item
);
171 * append a new payee into the GHashTable
173 * Return value: TRUE if inserted
177 da_pay_append(Payee
*item
)
181 DB( g_print("da_pay_append\n") );
183 existitem
= da_pay_get_by_name( item
->name
);
184 if( existitem
== NULL
)
186 item
->key
= da_pay_get_max_key() + 1;
191 DB( g_print(" -> %s already exist: %d\n", item
->name
, item
->key
) );
197 * da_pay_append_if_new:
199 * append a new payee into the GHashTable
201 * Return value: existing or new payee
205 da_pay_append_if_new(gchar
*rawname
)
207 Payee
*retval
= NULL
;
209 retval
= da_pay_get_by_name(rawname
);
212 retval
= da_pay_malloc();
213 retval
->key
= da_pay_get_max_key() + 1;
214 retval
->name
= g_strdup(rawname
);
215 g_strstrip(retval
->name
);
216 da_pay_insert(retval
);
224 da_pay_name_grfunc(gpointer key
, Payee
*item
, gchar
*name
)
226 if( name
&& item
->name
)
228 if(!strcasecmp(name
, item
->name
))
236 * da_pay_get_by_name:
238 * Get an payee structure by its name
240 * Return value: Payee * or NULL if not found
244 da_pay_get_by_name(gchar
*rawname
)
246 Payee
*retval
= NULL
;
249 DB( g_print("da_pay_get_by_name\n") );
253 stripname
= g_strdup(rawname
);
254 g_strstrip(stripname
);
255 if( strlen(stripname
) == 0 )
256 retval
= da_pay_get(0);
258 retval
= g_hash_table_find(GLOBALS
->h_pay
, (GHRFunc
)da_pay_name_grfunc
, stripname
);
268 * Get an payee structure by key
270 * Return value: Payee * or NULL if not found
274 da_pay_get(guint32 key
)
276 //DB( g_print("da_pay_get\n") );
278 return g_hash_table_lookup(GLOBALS
->h_pay
, &key
);
282 void da_pay_consistency(Payee
*item
)
284 g_strstrip(item
->name
);
285 //5.2.4 we drop internal xfer here as it will disapear
286 if( item
->paymode
== PAYMODE_INTXFER
)
287 item
->paymode
= PAYMODE_XFER
;
291 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
296 da_pay_debug_list_ghfunc(gpointer key
, gpointer value
, gpointer user_data
)
301 DB( g_print(" %d :: %s\n", *id
, item
->name
) );
306 da_pay_debug_list(void)
309 DB( g_print("\n** debug **\n") );
311 g_hash_table_foreach(GLOBALS
->h_pay
, da_pay_debug_list_ghfunc
, NULL
);
313 DB( g_print("\n** end debug **\n") );
320 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
323 payee_delete_unused(void)
327 lpay
= list
= g_hash_table_get_values(GLOBALS
->h_pay
);
330 Payee
*entry
= list
->data
;
332 if(entry
->usage_count
<= 0 && entry
->key
> 0)
333 da_pay_remove (entry
->key
);
334 list
= g_list_next(list
);
341 payee_fill_usage(void)
344 GList
*lst_acc
, *lnk_acc
;
348 lpay
= list
= g_hash_table_get_values(GLOBALS
->h_pay
);
351 Payee
*entry
= list
->data
;
352 entry
->usage_count
= 0;
353 list
= g_list_next(list
);
358 lst_acc
= g_hash_table_get_values(GLOBALS
->h_acc
);
359 lnk_acc
= g_list_first(lst_acc
);
360 while (lnk_acc
!= NULL
)
362 Account
*acc
= lnk_acc
->data
;
364 lnk_txn
= g_queue_peek_head_link(acc
->txn_queue
);
365 while (lnk_txn
!= NULL
)
367 Transaction
*txn
= lnk_txn
->data
;
368 Payee
*pay
= da_pay_get (txn
->kpay
);
373 lnk_txn
= g_list_next(lnk_txn
);
376 lnk_acc
= g_list_next(lnk_acc
);
378 g_list_free(lst_acc
);
381 list
= g_list_first(GLOBALS
->arc_list
);
384 Archive
*entry
= list
->data
;
385 Payee
*pay
= da_pay_get (entry
->kpay
);
389 list
= g_list_next(list
);
392 lrul
= list
= g_hash_table_get_values(GLOBALS
->h_rul
);
395 Assign
*entry
= list
->data
;
396 Payee
*pay
= da_pay_get (entry
->kpay
);
401 list
= g_list_next(list
);
409 payee_move(guint32 key1
, guint32 key2
)
411 GList
*lst_acc
, *lnk_acc
;
415 lst_acc
= g_hash_table_get_values(GLOBALS
->h_acc
);
416 lnk_acc
= g_list_first(lst_acc
);
417 while (lnk_acc
!= NULL
)
419 Account
*acc
= lnk_acc
->data
;
421 lnk_txn
= g_queue_peek_head_link(acc
->txn_queue
);
422 while (lnk_txn
!= NULL
)
424 Transaction
*txn
= lnk_txn
->data
;
426 if(txn
->kpay
== key1
)
429 txn
->flags
|= OF_CHANGED
;
431 lnk_txn
= g_list_next(lnk_txn
);
433 lnk_acc
= g_list_next(lnk_acc
);
435 g_list_free(lst_acc
);
438 list
= g_list_first(GLOBALS
->arc_list
);
441 Archive
*entry
= list
->data
;
442 if(entry
->kpay
== key1
)
446 list
= g_list_next(list
);
449 lrul
= list
= g_hash_table_get_values(GLOBALS
->h_rul
);
452 Assign
*entry
= list
->data
;
454 if(entry
->kpay
== key1
)
458 list
= g_list_next(list
);
465 payee_rename(Payee
*item
, const gchar
*newname
)
469 gboolean retval
= FALSE
;
471 stripname
= g_strdup(newname
);
472 g_strstrip(stripname
);
474 existitem
= da_pay_get_by_name(stripname
);
476 if( existitem
!= NULL
&& existitem
->key
!= item
->key
)
478 DB( g_print("- error, same name already exist with other key %d <> %d\n",existitem
->key
, item
->key
) );
483 DB( g_print("- renaming\n") );
485 item
->name
= stripname
;
494 payee_glist_name_compare_func(Payee
*a
, Payee
*b
)
496 return hb_string_utf8_compare(a
->name
, b
->name
);
501 payee_glist_key_compare_func(Payee
*a
, Payee
*b
)
503 return a
->key
- b
->key
;
508 payee_glist_sorted(gint column
)
510 GList
*list
= g_hash_table_get_values(GLOBALS
->h_pay
);
513 return g_list_sort(list
, (GCompareFunc
)payee_glist_key_compare_func
);
515 return g_list_sort(list
, (GCompareFunc
)payee_glist_name_compare_func
);
520 payee_load_csv(gchar
*filename
, gchar
**error
)
527 const gchar
*encoding
;
530 encoding
= homebank_file_getencoding(filename
);
531 DB( g_print(" -> encoding should be %s\n", encoding
) );
535 io
= g_io_channel_new_file(filename
, "r", NULL
);
538 if( encoding
!= NULL
)
540 g_io_channel_set_encoding(io
, encoding
, NULL
);
545 io_stat
= g_io_channel_read_line(io
, &tmpstr
, NULL
, NULL
, NULL
);
546 if( io_stat
== G_IO_STATUS_EOF
)
548 if( io_stat
== G_IO_STATUS_NORMAL
)
552 DB( g_print("\n + strip\n") );
553 hb_string_strip_crlf(tmpstr
);
555 DB( g_print(" + split '%s'\n", tmpstr
) );
556 str_array
= g_strsplit (tmpstr
, ";", 2);
557 // payee;category : later paymode?
559 nbcol
= g_strv_length (str_array
);
562 *error
= _("invalid CSV format");
564 DB( g_print(" + error %s\n", *error
) );
569 Category
*cat
= NULL
;
573 DB( g_print(" add pay:'%s' ?\n", str_array
[0]) );
574 pay
= da_pay_append_if_new(str_array
[0]);
575 DB( g_print(" pay: %p\n", pay
) );
578 GLOBALS
->changes_count
++;
584 DB( g_print(" add cat:'%s'\n", str_array
[1]) );
585 cat
= da_cat_append_ifnew_by_fullname(str_array
[1]);
587 DB( g_print(" cat: %p %p\n", cat
, pay
) );
592 DB( g_print(" set default cat to %d\n", cat
->key
) );
593 pay
->kcat
= cat
->key
;
595 GLOBALS
->changes_count
++;
599 g_strfreev (str_array
);
605 g_io_channel_unref (io
);
613 payee_save_csv(gchar
*filename
)
619 io
= g_io_channel_new_file(filename
, "w", NULL
);
622 lpay
= list
= payee_glist_sorted(1);
626 Payee
*item
= list
->data
;
634 Category
*cat
= da_cat_get(item
->kcat
);
638 fullcatname
= cat
->fullname
;
642 if( fullcatname
!= NULL
)
643 outstr
= g_strdup_printf("%s;%s\n", item
->name
, fullcatname
);
645 outstr
= g_strdup_printf("%s;\n", item
->name
);
647 DB( g_print(" + export %s\n", outstr
) );
649 g_io_channel_write_chars(io
, outstr
, -1, NULL
, NULL
);
655 list
= g_list_next(list
);
659 g_io_channel_unref (io
);