X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fhomebank;a=blobdiff_plain;f=src%2Fhb-account.c;h=b6888c9144f2838ca7f9eb1886d3f6643511fa53;hp=da1f30a853285a2d3dbf1183c933559f2b55390e;hb=5499ff44ef50b751b58f27fd13594f7dd4f959b7;hpb=27f6e3b112df235c8e9afc9911b1f6bce208a001 diff --git a/src/hb-account.c b/src/hb-account.c index da1f30a..b6888c9 100644 --- a/src/hb-account.c +++ b/src/hb-account.c @@ -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. * @@ -35,26 +35,6 @@ 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;idate <= 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); +}