/* HomeBank -- Free, easy, personal accounting for everyone.
- * Copyright (C) 1995-2014 Maxime DOYEN
+ * Copyright (C) 1995-2019 Maxime DOYEN
*
* This file is part of HomeBank.
*
#include "homebank.h"
#include "hb-payee.h"
+#include "ext.h"
+#include "refcount.h"
+
/****************************************************************************/
/* Debug macros */
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
+//Payee *
+//da_pay_clone
+
+
void
da_pay_free(Payee *item)
{
DB( g_print("da_pay_free\n") );
- if(item != NULL)
+ if(rc_unref(item))
{
DB( g_print(" => %d, %s\n", item->key, item->name) );
g_free(item->name);
- g_free(item);
+ rc_free(item);
}
}
da_pay_malloc(void)
{
DB( g_print("da_pay_malloc\n") );
- return g_malloc0(sizeof(Payee));
+ return rc_alloc(sizeof(Payee));
}
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
-static void da_pay_max_key_ghfunc(gpointer key, Payee *item, guint32 *max_key)
-{
- *max_key = MAX(*max_key, item->key);
-}
-
-static gboolean da_pay_name_grfunc(gpointer key, Payee *item, gchar *name)
-{
- if( name && item->name )
- {
- if(!strcasecmp(name, item->name))
- return TRUE;
- }
- return FALSE;
-}
/**
* da_pay_length:
return g_hash_table_size(GLOBALS->h_pay);
}
-/*
-gboolean
-da_pay_create_none(void)
-{
-Payee *pay;
-guint32 *new_key;
-
- DB( g_print("da_pay_insert none\n") );
- pay = da_pay_malloc();
- new_key = g_new0(guint32, 1);
- *new_key = 0;
- pay->key = 0;
- pay->name = g_strdup("");
-
- DB( g_print(" -> insert id: %d\n", *new_key) );
+static void
+da_pay_max_key_ghfunc(gpointer key, Payee *item, guint32 *max_key)
+{
+ *max_key = MAX(*max_key, item->key);
+}
- g_hash_table_insert(GLOBALS->h_pay, new_key, pay);
+/**
+ * da_pay_get_max_key:
+ *
+ * Get the biggest key from the GHashTable
+ *
+ * Return value: the biggest key value
+ *
+ */
+guint32
+da_pay_get_max_key(void)
+{
+guint32 max_key = 0;
- return TRUE;
+ g_hash_table_foreach(GLOBALS->h_pay, (GHFunc)da_pay_max_key_ghfunc, &max_key);
+ return max_key;
}
-*/
/**
* da_pay_remove:
*
- * remove an payee from the GHashTable
+ * delete an payee from the GHashTable
*
- * Return value: TRUE if the key was found and removed
+ * Return value: TRUE if the key was found and deleted
*
*/
gboolean
return g_hash_table_remove(GLOBALS->h_pay, &key);
}
+
/**
* da_pay_insert:
*
da_pay_append(Payee *item)
{
Payee *existitem;
-guint32 *new_key;
DB( g_print("da_pay_append\n") );
- /* ensure no duplicate */
- //g_strstrip(item->name);
- if( item->name != NULL )
+ existitem = da_pay_get_by_name( item->name );
+ if( existitem == NULL )
{
- existitem = da_pay_get_by_name( item->name );
- if( existitem == NULL )
- {
- new_key = g_new0(guint32, 1);
- *new_key = da_pay_get_max_key() + 1;
- item->key = *new_key;
-
- DB( g_print(" -> append id: %d\n", *new_key) );
-
- g_hash_table_insert(GLOBALS->h_pay, new_key, item);
- return TRUE;
- }
+ item->key = da_pay_get_max_key() + 1;
+ da_pay_insert(item);
+ return TRUE;
}
DB( g_print(" -> %s already exist: %d\n", item->name, item->key) );
-
return FALSE;
}
+
/**
- * da_pay_get_max_key:
+ * da_pay_append_if_new:
*
- * Get the biggest key from the GHashTable
+ * append a new payee into the GHashTable
*
- * Return value: the biggest key value
+ * Return value: existing or new payee
*
*/
-guint32
-da_pay_get_max_key(void)
+Payee *
+da_pay_append_if_new(gchar *rawname)
{
-guint32 max_key = 0;
+Payee *retval = NULL;
- g_hash_table_foreach(GLOBALS->h_pay, (GHFunc)da_pay_max_key_ghfunc, &max_key);
- return max_key;
+ retval = da_pay_get_by_name(rawname);
+ if(retval == NULL)
+ {
+ retval = da_pay_malloc();
+ retval->key = da_pay_get_max_key() + 1;
+ retval->name = g_strdup(rawname);
+ g_strstrip(retval->name);
+ da_pay_insert(retval);
+ }
+
+ return retval;
}
+static gboolean
+da_pay_name_grfunc(gpointer key, Payee *item, gchar *name)
+{
+ if( name && item->name )
+ {
+ if(!strcasecmp(name, item->name))
+ return TRUE;
+ }
+ return FALSE;
+}
/**
*
*/
Payee *
-da_pay_get_by_name(gchar *name)
+da_pay_get_by_name(gchar *rawname)
{
+Payee *retval = NULL;
+gchar *stripname;
+
DB( g_print("da_pay_get_by_name\n") );
- return g_hash_table_find(GLOBALS->h_pay, (GHRFunc)da_pay_name_grfunc, name);
+ if( rawname )
+ {
+ stripname = g_strdup(rawname);
+ g_strstrip(stripname);
+ if( strlen(stripname) == 0 )
+ retval = da_pay_get(0);
+ else
+ retval = g_hash_table_find(GLOBALS->h_pay, (GHRFunc)da_pay_name_grfunc, stripname);
+ g_free(stripname);
+ }
+ return retval;
}
-
/**
* da_pay_get:
*
void da_pay_consistency(Payee *item)
{
g_strstrip(item->name);
+ //5.2.4 we drop internal xfer here as it will disapear
+ if( item->paymode == PAYMODE_INTXFER )
+ item->paymode = PAYMODE_XFER;
}
#endif
-
-
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
+void
+payee_delete_unused(void)
+{
+GList *lpay, *list;
+
+ lpay = list = g_hash_table_get_values(GLOBALS->h_pay);
+ while (list != NULL)
+ {
+ Payee *entry = list->data;
+ if(entry->usage_count <= 0 && entry->key > 0)
+ da_pay_remove (entry->key);
+ list = g_list_next(list);
+ }
+ g_list_free(lpay);
+}
-gboolean
-payee_is_used(guint32 key)
+void
+payee_fill_usage(void)
{
+GList *lpay;
+GList *lst_acc, *lnk_acc;
+GList *lnk_txn;
GList *lrul, *list;
- list = g_list_first(GLOBALS->ope_list);
+ lpay = list = g_hash_table_get_values(GLOBALS->h_pay);
while (list != NULL)
{
- Transaction *entry = list->data;
- if( key == entry->kpay )
- return TRUE;
+ Payee *entry = list->data;
+ entry->usage_count = 0;
list = g_list_next(list);
}
+ g_list_free(lpay);
+
+
+ lst_acc = g_hash_table_get_values(GLOBALS->h_acc);
+ lnk_acc = g_list_first(lst_acc);
+ while (lnk_acc != NULL)
+ {
+ Account *acc = lnk_acc->data;
+
+ lnk_txn = g_queue_peek_head_link(acc->txn_queue);
+ while (lnk_txn != NULL)
+ {
+ Transaction *txn = lnk_txn->data;
+ Payee *pay = da_pay_get (txn->kpay);
+
+ if(pay)
+ pay->usage_count++;
+
+ lnk_txn = g_list_next(lnk_txn);
+ }
+
+ lnk_acc = g_list_next(lnk_acc);
+ }
+ g_list_free(lst_acc);
+
list = g_list_first(GLOBALS->arc_list);
while (list != NULL)
{
Archive *entry = list->data;
- if( key == entry->kpay )
- return TRUE;
+ Payee *pay = da_pay_get (entry->kpay);
+
+ if(pay)
+ pay->usage_count++;
list = g_list_next(list);
}
while (list != NULL)
{
Assign *entry = list->data;
+ Payee *pay = da_pay_get (entry->kpay);
+
+ if(pay)
+ pay->usage_count++;
- if( key == entry->kpay)
- return TRUE;
list = g_list_next(list);
}
g_list_free(lrul);
-
- return FALSE;
}
+
void
payee_move(guint32 key1, guint32 key2)
{
+GList *lst_acc, *lnk_acc;
+GList *lnk_txn;
GList *lrul, *list;
- list = g_list_first(GLOBALS->ope_list);
- while (list != NULL)
+ lst_acc = g_hash_table_get_values(GLOBALS->h_acc);
+ lnk_acc = g_list_first(lst_acc);
+ while (lnk_acc != NULL)
{
- Transaction *entry = list->data;
- if(entry->kpay == key1)
+ Account *acc = lnk_acc->data;
+
+ lnk_txn = g_queue_peek_head_link(acc->txn_queue);
+ while (lnk_txn != NULL)
{
- entry->kpay = key2;
- entry->flags |= OF_CHANGED;
+ Transaction *txn = lnk_txn->data;
+
+ if(txn->kpay == key1)
+ {
+ txn->kpay = key2;
+ txn->flags |= OF_CHANGED;
+ }
+ lnk_txn = g_list_next(lnk_txn);
}
- list = g_list_next(list);
+ lnk_acc = g_list_next(lnk_acc);
}
+ g_list_free(lst_acc);
+
list = g_list_first(GLOBALS->arc_list);
while (list != NULL)
{
Payee *existitem;
gchar *stripname;
+gboolean retval = FALSE;
stripname = g_strdup(newname);
g_strstrip(stripname);
existitem = da_pay_get_by_name(stripname);
- if( existitem != NULL )
+ if( existitem != NULL && existitem->key != item->key)
{
- if( existitem->key == item->key )
- return TRUE;
+ DB( g_print("- error, same name already exist with other key %d <> %d\n",existitem->key, item->key) );
+ g_free(stripname);
}
else
{
+ DB( g_print("- renaming\n") );
g_free(item->name);
- item->name = g_strdup(stripname);
- return TRUE;
+ item->name = stripname;
+ retval = TRUE;
}
- g_free(stripname);
-
- return FALSE;
+ return retval;
}
-/**
- * payee_append_if_new:
- *
- * append a new payee into the GHashTable
- *
- * Return value: a new Payee or NULL
- *
- */
-Payee *
-payee_append_if_new(gchar *name)
-{
-gchar *stripname;
-Payee *item;
-
- stripname = g_strdup(name);
- g_strstrip(stripname);
- item = da_pay_get_by_name(stripname);
-
- if(item == NULL)
- {
- item = da_pay_malloc();
- item->name = g_strdup(stripname);
- da_pay_append(item);
- }
- else
- item = NULL;
-
- g_free(stripname);
-
- return item;
-}
-
static gint
payee_glist_name_compare_func(Payee *a, Payee *b)
{
}
-GList *payee_glist_sorted(gint column)
+GList *
+payee_glist_sorted(gint column)
{
GList *list = g_hash_table_get_values(GLOBALS->h_pay);
}
-
-void
-payee_load_csv(gchar *filename)
+gboolean
+payee_load_csv(gchar *filename, gchar **error)
{
+gboolean retval;
GIOChannel *io;
gchar *tmpstr;
gint io_stat;
+gchar **str_array;
const gchar *encoding;
+gint nbcol;
encoding = homebank_file_getencoding(filename);
+ DB( g_print(" -> encoding should be %s\n", encoding) );
+ retval = TRUE;
+ *error = NULL;
io = g_io_channel_new_file(filename, "r", NULL);
if(io != NULL)
{
- DB( g_print(" -> encoding should be %s\n", encoding) );
if( encoding != NULL )
{
g_io_channel_set_encoding(io, encoding, NULL);
{
if( tmpstr != NULL)
{
+ DB( g_print("\n + strip\n") );
hb_string_strip_crlf(tmpstr);
- DB( g_print(" read %s\n", tmpstr) );
+ DB( g_print(" + split '%s'\n", tmpstr) );
+ str_array = g_strsplit (tmpstr, ";", 2);
+ // payee;category : later paymode?
- if( payee_append_if_new( tmpstr ) )
+ nbcol = g_strv_length (str_array);
+ if( nbcol > 2 )
{
- GLOBALS->changes_count++;
+ *error = _("invalid CSV format");
+ retval = FALSE;
+ DB( g_print(" + error %s\n", *error) );
}
-
+ else
+ {
+ Payee *pay = NULL;
+ Category *cat = NULL;
+
+ if( nbcol >= 1 )
+ {
+ DB( g_print(" add pay:'%s' ?\n", str_array[0]) );
+ pay = da_pay_append_if_new(str_array[0]);
+ DB( g_print(" pay: %p\n", pay) );
+ if( pay != NULL )
+ {
+ GLOBALS->changes_count++;
+ }
+ }
+
+ if( nbcol == 2 )
+ {
+ DB( g_print(" add cat:'%s'\n", str_array[1]) );
+ cat = da_cat_append_ifnew_by_fullname(str_array[1]);
+
+ DB( g_print(" cat: %p %p\n", cat, pay) );
+ if( cat != NULL )
+ {
+ if( pay != NULL)
+ {
+ DB( g_print(" set default cat to %d\n", cat->key) );
+ pay->kcat = cat->key;
+ }
+ GLOBALS->changes_count++;
+ }
+ }
+ }
+ g_strfreev (str_array);
}
g_free(tmpstr);
}
g_io_channel_unref (io);
}
+ return retval;
}
while (list != NULL)
{
Payee *item = list->data;
+ gchar *fullcatname;
if(item->key != 0)
{
- outstr = g_strdup_printf("%s\n", item->name);
- g_io_channel_write_chars(io, outstr, -1, NULL, NULL);
+ fullcatname = NULL;
+ if( item->kcat > 0 )
+ {
+ Category *cat = da_cat_get(item->kcat);
+
+ if( cat != NULL )
+ {
+ fullcatname = cat->fullname;
+ }
+ }
- DB( g_print("%s", outstr) );
+ if( fullcatname != NULL )
+ outstr = g_strdup_printf("%s;%s\n", item->name, fullcatname);
+ else
+ outstr = g_strdup_printf("%s;\n", item->name);
+
+ DB( g_print(" + export %s\n", outstr) );
+
+ g_io_channel_write_chars(io, outstr, -1, NULL, NULL);
g_free(outstr);
+ g_free(fullcatname);
+
}
list = g_list_next(list);
}
g_io_channel_unref (io);
}
-
}
-