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/>.
27 /****************************************************************************/
29 /****************************************************************************/
38 /* our global datas */
39 extern struct HomeBank
*GLOBALS
;
41 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
48 da_pay_free(Payee
*item
)
50 DB( g_print("da_pay_free\n") );
53 DB( g_print(" => %d, %s\n", item
->key
, item
->name
) );
64 DB( g_print("da_pay_malloc\n") );
65 return rc_alloc(sizeof(Payee
));
72 DB( g_print("da_pay_destroy\n") );
73 g_hash_table_destroy(GLOBALS
->h_pay
);
82 DB( g_print("da_pay_new\n") );
83 GLOBALS
->h_pay
= g_hash_table_new_full(g_int_hash
, g_int_equal
, (GDestroyNotify
)g_free
, (GDestroyNotify
)da_pay_free
);
85 // insert our 'no payee'
86 item
= da_pay_malloc();
87 item
->name
= g_strdup("");
92 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
97 * Return value: the number of elements
102 return g_hash_table_size(GLOBALS
->h_pay
);
107 da_pay_max_key_ghfunc(gpointer key
, Payee
*item
, guint32
*max_key
)
109 *max_key
= MAX(*max_key
, item
->key
);
114 * da_pay_get_max_key:
116 * Get the biggest key from the GHashTable
118 * Return value: the biggest key value
122 da_pay_get_max_key(void)
126 g_hash_table_foreach(GLOBALS
->h_pay
, (GHFunc
)da_pay_max_key_ghfunc
, &max_key
);
134 * delete an payee from the GHashTable
136 * Return value: TRUE if the key was found and deleted
140 da_pay_remove(guint32 key
)
142 DB( g_print("da_pay_remove %d\n", key
) );
144 return g_hash_table_remove(GLOBALS
->h_pay
, &key
);
151 * insert an payee into the GHashTable
153 * Return value: TRUE if inserted
157 da_pay_insert(Payee
*item
)
161 DB( g_print("da_pay_insert\n") );
163 new_key
= g_new0(guint32
, 1);
164 *new_key
= item
->key
;
165 g_hash_table_insert(GLOBALS
->h_pay
, new_key
, item
);
174 * append a new payee into the GHashTable
176 * Return value: TRUE if inserted
180 da_pay_append(Payee
*item
)
184 DB( g_print("da_pay_append\n") );
186 existitem
= da_pay_get_by_name( item
->name
);
187 if( existitem
== NULL
)
189 item
->key
= da_pay_get_max_key() + 1;
194 DB( g_print(" -> %s already exist: %d\n", item
->name
, item
->key
) );
200 * da_pay_append_if_new:
202 * append a new payee into the GHashTable
204 * Return value: existing or new payee
208 da_pay_append_if_new(gchar
*rawname
)
210 Payee
*retval
= NULL
;
212 retval
= da_pay_get_by_name(rawname
);
215 retval
= da_pay_malloc();
216 retval
->key
= da_pay_get_max_key() + 1;
217 retval
->name
= g_strdup(rawname
);
218 g_strstrip(retval
->name
);
219 da_pay_insert(retval
);
227 da_pay_name_grfunc(gpointer key
, Payee
*item
, gchar
*name
)
229 if( name
&& item
->name
)
231 if(!strcasecmp(name
, item
->name
))
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
*rawname
)
249 Payee
*retval
= NULL
;
252 DB( g_print("da_pay_get_by_name\n") );
256 stripname
= g_strdup(rawname
);
257 g_strstrip(stripname
);
258 if( strlen(stripname
) == 0 )
259 retval
= da_pay_get(0);
261 retval
= g_hash_table_find(GLOBALS
->h_pay
, (GHRFunc
)da_pay_name_grfunc
, stripname
);
271 * Get an payee structure by key
273 * Return value: Payee * or NULL if not found
277 da_pay_get(guint32 key
)
279 //DB( g_print("da_pay_get\n") );
281 return g_hash_table_lookup(GLOBALS
->h_pay
, &key
);
285 void da_pay_consistency(Payee
*item
)
287 g_strstrip(item
->name
);
288 //5.2.4 we drop internal xfer here as it will disapear
289 if( item
->paymode
== PAYMODE_INTXFER
)
290 item
->paymode
= PAYMODE_XFER
;
294 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
299 da_pay_debug_list_ghfunc(gpointer key
, gpointer value
, gpointer user_data
)
304 DB( g_print(" %d :: %s\n", *id
, item
->name
) );
309 da_pay_debug_list(void)
312 DB( g_print("\n** debug **\n") );
314 g_hash_table_foreach(GLOBALS
->h_pay
, da_pay_debug_list_ghfunc
, NULL
);
316 DB( g_print("\n** end debug **\n") );
323 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
326 payee_delete_unused(void)
330 lpay
= list
= g_hash_table_get_values(GLOBALS
->h_pay
);
333 Payee
*entry
= list
->data
;
335 if(entry
->usage_count
<= 0 && entry
->key
> 0)
336 da_pay_remove (entry
->key
);
337 list
= g_list_next(list
);
344 payee_fill_usage(void)
347 GList
*lst_acc
, *lnk_acc
;
351 lpay
= list
= g_hash_table_get_values(GLOBALS
->h_pay
);
354 Payee
*entry
= list
->data
;
355 entry
->usage_count
= 0;
356 list
= g_list_next(list
);
361 lst_acc
= g_hash_table_get_values(GLOBALS
->h_acc
);
362 lnk_acc
= g_list_first(lst_acc
);
363 while (lnk_acc
!= NULL
)
365 Account
*acc
= lnk_acc
->data
;
367 lnk_txn
= g_queue_peek_head_link(acc
->txn_queue
);
368 while (lnk_txn
!= NULL
)
370 Transaction
*txn
= lnk_txn
->data
;
371 Payee
*pay
= da_pay_get (txn
->kpay
);
376 lnk_txn
= g_list_next(lnk_txn
);
379 lnk_acc
= g_list_next(lnk_acc
);
381 g_list_free(lst_acc
);
384 list
= g_list_first(GLOBALS
->arc_list
);
387 Archive
*entry
= list
->data
;
388 Payee
*pay
= da_pay_get (entry
->kpay
);
392 list
= g_list_next(list
);
395 lrul
= list
= g_hash_table_get_values(GLOBALS
->h_rul
);
398 Assign
*entry
= list
->data
;
399 Payee
*pay
= da_pay_get (entry
->kpay
);
404 list
= g_list_next(list
);
412 payee_move(guint32 key1
, guint32 key2
)
414 GList
*lst_acc
, *lnk_acc
;
418 lst_acc
= g_hash_table_get_values(GLOBALS
->h_acc
);
419 lnk_acc
= g_list_first(lst_acc
);
420 while (lnk_acc
!= NULL
)
422 Account
*acc
= lnk_acc
->data
;
424 lnk_txn
= g_queue_peek_head_link(acc
->txn_queue
);
425 while (lnk_txn
!= NULL
)
427 Transaction
*txn
= lnk_txn
->data
;
429 if(txn
->kpay
== key1
)
432 txn
->flags
|= OF_CHANGED
;
434 lnk_txn
= g_list_next(lnk_txn
);
436 lnk_acc
= g_list_next(lnk_acc
);
438 g_list_free(lst_acc
);
441 list
= g_list_first(GLOBALS
->arc_list
);
444 Archive
*entry
= list
->data
;
445 if(entry
->kpay
== key1
)
449 list
= g_list_next(list
);
452 lrul
= list
= g_hash_table_get_values(GLOBALS
->h_rul
);
455 Assign
*entry
= list
->data
;
457 if(entry
->kpay
== key1
)
461 list
= g_list_next(list
);
468 payee_rename(Payee
*item
, const gchar
*newname
)
472 gboolean retval
= FALSE
;
474 stripname
= g_strdup(newname
);
475 g_strstrip(stripname
);
477 existitem
= da_pay_get_by_name(stripname
);
479 if( existitem
!= NULL
&& existitem
->key
!= item
->key
)
481 DB( g_print("- error, same name already exist with other key %d <> %d\n",existitem
->key
, item
->key
) );
486 DB( g_print("- renaming\n") );
488 item
->name
= stripname
;
497 payee_glist_name_compare_func(Payee
*a
, Payee
*b
)
499 return hb_string_utf8_compare(a
->name
, b
->name
);
504 payee_glist_key_compare_func(Payee
*a
, Payee
*b
)
506 return a
->key
- b
->key
;
511 payee_glist_sorted(gint column
)
513 GList
*list
= g_hash_table_get_values(GLOBALS
->h_pay
);
516 return g_list_sort(list
, (GCompareFunc
)payee_glist_key_compare_func
);
518 return g_list_sort(list
, (GCompareFunc
)payee_glist_name_compare_func
);
523 payee_load_csv(gchar
*filename
, gchar
**error
)
530 const gchar
*encoding
;
533 encoding
= homebank_file_getencoding(filename
);
534 DB( g_print(" -> encoding should be %s\n", encoding
) );
538 io
= g_io_channel_new_file(filename
, "r", NULL
);
541 if( encoding
!= NULL
)
543 g_io_channel_set_encoding(io
, encoding
, NULL
);
548 io_stat
= g_io_channel_read_line(io
, &tmpstr
, NULL
, NULL
, NULL
);
549 if( io_stat
== G_IO_STATUS_EOF
)
551 if( io_stat
== G_IO_STATUS_NORMAL
)
555 DB( g_print("\n + strip\n") );
556 hb_string_strip_crlf(tmpstr
);
558 DB( g_print(" + split '%s'\n", tmpstr
) );
559 str_array
= g_strsplit (tmpstr
, ";", 2);
560 // payee;category : later paymode?
562 nbcol
= g_strv_length (str_array
);
565 *error
= _("invalid CSV format");
567 DB( g_print(" + error %s\n", *error
) );
572 Category
*cat
= NULL
;
576 DB( g_print(" add pay:'%s' ?\n", str_array
[0]) );
577 pay
= da_pay_append_if_new(str_array
[0]);
578 DB( g_print(" pay: %p\n", pay
) );
581 GLOBALS
->changes_count
++;
587 DB( g_print(" add cat:'%s'\n", str_array
[1]) );
588 cat
= da_cat_append_ifnew_by_fullname(str_array
[1]);
590 DB( g_print(" cat: %p %p\n", cat
, pay
) );
595 DB( g_print(" set default cat to %d\n", cat
->key
) );
596 pay
->kcat
= cat
->key
;
598 GLOBALS
->changes_count
++;
602 g_strfreev (str_array
);
608 g_io_channel_unref (io
);
616 payee_save_csv(gchar
*filename
)
622 io
= g_io_channel_new_file(filename
, "w", NULL
);
625 lpay
= list
= payee_glist_sorted(1);
629 Payee
*item
= list
->data
;
637 Category
*cat
= da_cat_get(item
->kcat
);
641 fullcatname
= cat
->fullname
;
645 if( fullcatname
!= NULL
)
646 outstr
= g_strdup_printf("%s;%s\n", item
->name
, fullcatname
);
648 outstr
= g_strdup_printf("%s;\n", item
->name
);
650 DB( g_print(" + export %s\n", outstr
) );
652 g_io_channel_write_chars(io
, outstr
, -1, NULL
, NULL
);
658 list
= g_list_next(list
);
662 g_io_channel_unref (io
);