]> Dogcows Code - chaz/homebank/blobdiff - src/hb-account.c
import homebank-5.2.6
[chaz/homebank] / src / hb-account.c
index da1f30a853285a2d3dbf1183c933559f2b55390e..b6888c9144f2838ca7f9eb1886d3f6643511fa53 100644 (file)
@@ -1,5 +1,5 @@
 /*  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.
  *
 extern struct HomeBank *GLOBALS;
 
 
-
-
-
-Account *
-da_acc_clone(Account *src_item)
-{
-Account *new_item = g_memdup(src_item, sizeof(Account));
-
-       DB( g_print("da_acc_clone\n") );
-       if(new_item)
-       {
-               //duplicate the string
-               new_item->name          = g_strdup(src_item->name);
-               new_item->number        = g_strdup(src_item->number);
-               new_item->bankname      = g_strdup(src_item->bankname);
-       }
-       return new_item;
-}
-
-
 void
 da_acc_free(Account *item)
 {
@@ -63,10 +43,13 @@ da_acc_free(Account *item)
        {
                DB( g_print(" => %d, %s\n", item->key, item->name) );
 
-               g_free(item->imp_name);
                g_free(item->name);
                g_free(item->number);
                g_free(item->bankname);
+               g_free(item->notes);
+               
+               g_queue_free (item->txn_queue);
+               
                g_free(item);
        }
 }
@@ -75,8 +58,13 @@ da_acc_free(Account *item)
 Account *
 da_acc_malloc(void)
 {
+Account *item;
+
        DB( g_print("da_acc_malloc\n") );
-       return g_malloc0(sizeof(Account));
+       item = g_malloc0(sizeof(Account));
+       item->kcur = GLOBALS->kcur;
+       item->txn_queue = g_queue_new ();
+       return item;
 }
 
 
@@ -97,30 +85,7 @@ da_acc_new(void)
 
 
 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
-static void da_acc_max_key_ghfunc(gpointer key, Account *item, guint32 *max_key)
-{
-       *max_key = MAX(*max_key, item->key);
-}
-
-static gboolean da_acc_name_grfunc(gpointer key, Account *item, gchar *name)
-{
-       if( name && item->name )
-       {
-               if(!strcasecmp(name, item->name))
-                       return TRUE;
-       }
-       return FALSE;
-}
 
-static gboolean da_acc_imp_name_grfunc(gpointer key, Account *item, gchar *name)
-{
-       if( name && item->imp_name )
-       {
-               if(!strcasecmp(name, item->imp_name))
-                       return TRUE;
-       }
-       return FALSE;
-}
 
 /**
  * da_acc_length:
@@ -134,12 +99,36 @@ da_acc_length(void)
 }
 
 
+static void da_acc_max_key_ghfunc(gpointer key, Account *item, guint32 *max_key)
+{
+       *max_key = MAX(*max_key, item->key);
+}
+
+
+/**
+ * da_acc_get_max_key:
+ *
+ * Get the biggest key from the GHashTable
+ *
+ * Return value: the biggest key value
+ *
+ */
+guint32
+da_acc_get_max_key(void)
+{
+guint32 max_key = 0;
+
+       g_hash_table_foreach(GLOBALS->h_acc, (GHFunc)da_acc_max_key_ghfunc, &max_key);
+       return max_key;
+}
+
+
 /**
  * da_acc_remove:
  *
- * remove an account from the GHashTable
+ * delete an account from the GHashTable
  *
- * Return value: TRUE if the key was found and removed
+ * Return value: TRUE if the key was found and deleted
  *
  */
 gboolean
@@ -185,27 +174,16 @@ gboolean
 da_acc_append(Account *item)
 {
 Account *existitem;
-guint32 *new_key;
 
        DB( g_print("da_acc_append\n") );
 
-       /* ensure no duplicate */
-       g_strstrip(item->name);
-       if(item->name != NULL)
+       existitem = da_acc_get_by_name( item->name );
+       if( existitem == NULL )
        {
-               existitem = da_acc_get_by_name( item->name );
-               if( existitem == NULL )
-               {
-                       new_key = g_new0(guint32, 1);
-                       *new_key = da_acc_get_max_key() + 1;
-                       item->key = *new_key;
-                       item->pos = da_acc_length() + 1;
-
-                       DB( g_print(" -> insert id: %d\n", *new_key) );
-
-                       g_hash_table_insert(GLOBALS->h_acc, new_key, item);
-                       return TRUE;
-               }
+               item->key = da_acc_get_max_key() + 1;
+               item->pos = da_acc_length() + 1;
+               da_acc_insert(item);
+               return TRUE;
        }
 
        DB( g_print(" -> %s already exist: %d\n", item->name, item->key) );
@@ -213,26 +191,17 @@ guint32 *new_key;
        return FALSE;
 }
 
-/**
- * da_acc_get_max_key:
- *
- * Get the biggest key from the GHashTable
- *
- * Return value: the biggest key value
- *
- */
-guint32
-da_acc_get_max_key(void)
-{
-guint32 max_key = 0;
 
-       g_hash_table_foreach(GLOBALS->h_acc, (GHFunc)da_acc_max_key_ghfunc, &max_key);
-       return max_key;
+static gboolean da_acc_name_grfunc(gpointer key, Account *item, gchar *name)
+{
+       if( name && item->name )
+       {
+               if(!strcasecmp(name, item->name))
+                       return TRUE;
+       }
+       return FALSE;
 }
 
-
-
-
 /**
  * da_acc_get_by_name:
  *
@@ -242,19 +211,24 @@ guint32 max_key = 0;
  *
  */
 Account *
-da_acc_get_by_name(gchar *name)
+da_acc_get_by_name(gchar *rawname)
 {
+Account *retval = NULL;
+gchar *stripname;
+
        DB( g_print("da_acc_get_by_name\n") );
 
-       return g_hash_table_find(GLOBALS->h_acc, (GHRFunc)da_acc_name_grfunc, name);
-}
+       if( rawname )
+       {
+               stripname = g_strdup(rawname);
+               g_strstrip(stripname);
+               if( strlen(stripname) > 0 )
+                       retval = g_hash_table_find(GLOBALS->h_acc, (GHRFunc)da_acc_name_grfunc, stripname);
 
-Account *
-da_acc_get_by_imp_name(gchar *name)
-{
-       DB( g_print("da_acc_get_by_imp_name\n") );
+               g_free(stripname);
+       }
 
-       return g_hash_table_find(GLOBALS->h_acc, (GHRFunc)da_acc_imp_name_grfunc, name);
+       return retval; 
 }
 
 
@@ -350,57 +324,68 @@ GList *list = g_hash_table_get_values(GLOBALS->h_acc);
 gboolean
 account_is_used(guint32 key)
 {
+Account *acc;
 GList *list;
+GList *lst_acc, *lnk_acc;
+GList *lnk_txn;
+gboolean retval;
 
-       list = g_list_first(GLOBALS->ope_list);
-       while (list != NULL)
-       {
-       Transaction *entry = list->data;
-               if( key == entry->kacc || key == entry->kxferacc)
-                       return TRUE;
-               list = g_list_next(list);
-       }
+       retval = FALSE;
+       lst_acc = NULL;
 
-       list = g_list_first(GLOBALS->arc_list);
-       while (list != NULL)
+       acc = da_acc_get(key);
+       if( g_queue_get_length(acc->txn_queue) > 0 )
        {
-       Archive *entry = list->data;
-               if( key == entry->kacc || key == entry->kxferacc)
-                       return TRUE;
-               list = g_list_next(list);
+               retval = TRUE;
+               goto end;
        }
 
-       return FALSE;
-}
-
-void
-account_move(guint32 key1, guint32 key2)
-{
-GList *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->kacc == key1)
-                       entry->kacc = key2;
-               if(entry->kxferacc == key1)
-                       entry->kxferacc = key2;
-               list = g_list_next(list);
+       Account *acc = lnk_acc->data;
+       
+               if(acc->key != key)
+               {
+                       lnk_txn = g_queue_peek_head_link(acc->txn_queue);
+                       while (lnk_txn != NULL)
+                       {
+                       Transaction *entry = lnk_txn->data;
+                       
+                               if( key == entry->kxferacc)
+                               {
+                                       retval = TRUE;
+                                       goto end;
+                               }
+
+                               lnk_txn = g_list_next(lnk_txn);
+                       }
+               }
+               lnk_acc = g_list_next(lnk_acc);
        }
 
        list = g_list_first(GLOBALS->arc_list);
        while (list != NULL)
        {
        Archive *entry = list->data;
-               if(entry->kacc == key1)
-                       entry->kacc = key2;
-               if(entry->kxferacc == key1)
-                       entry->kxferacc = key2;
+
+               if( key == entry->kacc || key == entry->kxferacc)
+               {
+                       retval = TRUE;
+                       goto end;
+               }
+
                list = g_list_next(list);
        }
+
+end:
+       g_list_free(lst_acc);
+
+       return retval;
 }
 
+
 static gchar *
 account_get_stripname(gchar *name)
 {
@@ -430,59 +415,78 @@ account_rename(Account *item, gchar *newname)
 Account *existitem;
 gchar *stripname = account_get_stripname(newname);
 
-       existitem = da_acc_get_by_name(stripname);
-       if( existitem == NULL )
+       if( strlen(stripname) > 0 )
        {
-               g_free(item->name);
-               item->name = g_strdup(stripname);
-               return TRUE;
-       }
-
-       g_free(stripname);
+               existitem = da_acc_get_by_name(stripname);
+               if( existitem == NULL )
+               {
+                       g_free(item->name);
+                       item->name = g_strdup(stripname);
+                       return TRUE;
+               }
 
+               g_free(stripname);
+       }
+       
        return FALSE;
 }
 
-/* when we change the currency of an account, we must ensure
- * xfer transaction account will be set to same currency
+
+/* 
+ * change the account currency
+ * change every txn to currency
+ * ensure dst xfer transaction account will be set to same currency
  */
- /*
-void account_set_currency(Account *item, guint32 kcur)
+void account_set_currency(Account *acc, guint32 kcur)
 {
 GList *list;
-Account *acc;
+Account *dstacc;
+gboolean *xfer_list;
+guint32 maxkey, i;
+
+       DB( g_print("\n[account] set currency\n") );
 
-       if(item->kcur != kcur)
+       if(acc->kcur == kcur)
        {
-               item->kcur = kcur;
-       
-               list = g_list_first(GLOBALS->ope_list);
-               while (list != NULL)
+               DB( g_print(" - already ok, return\n") );
+               return;
+       }
+
+       DB( g_print(" - set for '%s'\n", acc->name)  );
+
+       maxkey = da_acc_get_max_key () + 1;
+       xfer_list = g_malloc0(sizeof(gboolean) * maxkey );
+       DB( g_print(" - alloc for %d account\n", da_acc_length() ) );
+
+       list = g_queue_peek_head_link(acc->txn_queue);
+       while (list != NULL)
+       {
+       Transaction *txn = list->data;
+
+               txn->kcur = kcur;
+               if( (txn->paymode == PAYMODE_INTXFER) && (txn->kxferacc > 0) && (txn->kxfer > 0) )
                {
-               Transaction *entry = list->data;
-                       if(entry->paymode == PAYMODE_INTXFER)
-                       {
-                               if(entry->kacc == item->key)
-                               {
-                                       // change target account
-                                       acc = da_acc_get (entry->kxferacc);
-                                       acc->kcur = kcur;
-                               }
-                               if(entry->kxferacc == item->key)
-                               {
-                                       // change source account
-                                       acc = da_acc_get (entry->kacc);
-                                       acc->kcur = kcur;
-                               }
-                       }
-                       
-                       list = g_list_next(list);
+                       xfer_list[txn->kxferacc] = TRUE;
                }
+               list = g_list_next(list);
        }
+
+       acc->kcur = kcur;
+       DB( g_print(" - '%s'\n", acc->name) );
        
-}
-*/
+       for(i=1;i<maxkey;i++)
+       {
+               DB( g_print(" - %d '%d'\n", i, xfer_list[i]) );
+               if( xfer_list[i] == TRUE )
+               {
+                       dstacc = da_acc_get(i);
+                       account_set_currency(dstacc, kcur);
+               }
+       }
 
+       g_free(xfer_list);
+
+}
 
 
 /**
@@ -495,7 +499,8 @@ static void account_balances_sub_internal(Account *acc, Transaction *trn)
        if(trn->date <= GLOBALS->today)
                acc->bal_today -= trn->amount;
 
-       if(trn->flags & OF_VALID)
+       if(trn->status == TXN_STATUS_RECONCILED)
+       //if(trn->flags & OF_VALID)
                acc->bal_bank -= trn->amount;
 }
 
@@ -509,7 +514,8 @@ static void account_balances_add_internal(Account *acc, Transaction *trn)
        if(trn->date <= GLOBALS->today)
                acc->bal_today += trn->amount;
 
-       if(trn->flags & OF_VALID)
+       if(trn->status == TXN_STATUS_RECONCILED)
+       //if(trn->flags & OF_VALID)
                acc->bal_bank += trn->amount;
 }
 
@@ -519,7 +525,9 @@ static void account_balances_add_internal(Account *acc, Transaction *trn)
  */
 gboolean account_balances_sub(Transaction *trn)
 {
-       if(!(trn->flags & OF_REMIND))
+
+       if(!(trn->status == TXN_STATUS_REMIND))
+       //if(!(trn->flags & OF_REMIND))
        {
                Account *acc = da_acc_get(trn->kacc);
                if(acc == NULL) return FALSE;
@@ -535,7 +543,8 @@ gboolean account_balances_sub(Transaction *trn)
  */
 gboolean account_balances_add(Transaction *trn)
 {
-       if(!(trn->flags & OF_REMIND))
+       if(!(trn->status == TXN_STATUS_REMIND))
+       //if(!(trn->flags & OF_REMIND))
        {
                Account *acc = da_acc_get(trn->kacc);
                if(acc == NULL) return FALSE;
@@ -546,49 +555,65 @@ gboolean account_balances_add(Transaction *trn)
 }
 
 
-
-
-
-
+//todo: optim called 2 times from dsp_mainwindow
 void account_compute_balances(void)
 {
-GList *lacc, *list;
-Account *acc;
-Transaction *trn;
+GList *lst_acc, *lnk_acc;
+GList *lnk_txn;
 
        DB( g_print("\naccount_compute_balances start\n") );
 
-       /* set initial amount */
-       lacc = list = g_hash_table_get_values(GLOBALS->h_acc);
-       while (list != NULL)
+       lst_acc = g_hash_table_get_values(GLOBALS->h_acc);
+       lnk_acc = g_list_first(lst_acc);
+       while (lnk_acc != NULL)
        {
-               acc = list->data;
+       Account *acc = lnk_acc->data;
+       
+               /* set initial amount */
                acc->bal_bank = acc->initial;
                acc->bal_today = acc->initial;
                acc->bal_future = acc->initial;
-               list = g_list_next(list);
-       }
-       g_list_free(lacc);
-
-
-       /* compute every transaction */
-       list = g_list_first(GLOBALS->ope_list);
-       while (list != NULL)
-       {
-               trn = list->data;
-
-               if(!(trn->flags & OF_REMIND))
+               
+               /* add every txn */
+               lnk_txn = g_queue_peek_head_link(acc->txn_queue);
+               while (lnk_txn != NULL)
                {
-                       account_balances_add(trn);
+               Transaction *txn = lnk_txn->data;
+               
+                       if(!(txn->status == TXN_STATUS_REMIND))
+                       {
+                               account_balances_add_internal(acc, txn);
+                       }
+                       lnk_txn = g_list_next(lnk_txn);
                }
-               list = g_list_next(list);
+               
+               lnk_acc = g_list_next(lnk_acc);
        }
+       g_list_free(lst_acc);
 
        DB( g_print("\naccount_compute_balances end\n") );
 
 }
 
 
+void account_convert_euro(Account *acc)
+{
+GList *lnk_txn;
+
+       lnk_txn = g_queue_peek_head_link(acc->txn_queue);
+       while (lnk_txn != NULL)
+       {
+       Transaction *txn = lnk_txn->data;
+       gdouble oldamount = txn->amount;
 
+               txn->amount = hb_amount_to_euro(oldamount);
+               DB( g_print("%10.6f => %10.6f, %s\n", oldamount, txn->amount, txn->memo) );
+               //todo: sync child xfer
+               lnk_txn = g_list_next(lnk_txn);
+       }
 
+       acc->initial = hb_amount_to_euro(acc->initial);
+       acc->warning = hb_amount_to_euro(acc->warning);
+       acc->minimum = hb_amount_to_euro(acc->minimum);
+}
 
This page took 0.03089 seconds and 4 git commands to generate.