/* HomeBank -- Free, easy, personal accounting for everyone.
- * Copyright (C) 1995-2014 Maxime DOYEN
+ * Copyright (C) 1995-2018 Maxime DOYEN
*
* This file is part of HomeBank.
*
#include "hb-transaction.h"
#include "hb-xml.h"
+#include "ext.h"
+
+#include "ui-dialogs.h"
+
/****************************************************************************/
/* Debug macros */
/****************************************************************************/
extern struct HomeBank *GLOBALS;
extern struct Preferences *PREFS;
-typedef struct _ParseContext ParseContext;
-struct _ParseContext
-{
- gdouble version;
-};
+/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
-static void homebank_upgrade_to_v02(void);
-static void homebank_upgrade_to_v03(void);
-static void homebank_upgrade_to_v04(void);
-static void homebank_upgrade_to_v05(void);
-static void homebank_upgrade_lower_v06(void);
-static void homebank_upgrade_to_v06(void);
-static void homebank_upgrade_to_v07(void);
-static void homebank_upgrade_to_v08(void);
-static void
-start_element_handler (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- gpointer user_data,
- GError **error)
+// v0.1 to v0.2 : we must change account reference by making a +1 to its index references
+static void homebank_upgrade_to_v02(void)
{
-ParseContext *ctx = user_data;
-//GtkUIManager *self = ctx->self;
-gint i, j;
+GList *lst_acc, *lnk_acc;
+GList *list;
+GHashTable *h_old_acc;
+
- //DB( g_print("** start element: %s\n", element_name) );
+ DB( g_print("\n[hb-xml] homebank_upgrade_to_v02\n") );
- switch(element_name[0])
+ //keep old hashtable with us
+ h_old_acc = GLOBALS->h_acc;
+ da_acc_new();
+
+ lst_acc = g_hash_table_get_values(h_old_acc);
+ lnk_acc = g_list_first(lst_acc);
+ while (lnk_acc != NULL)
{
- //get file version
- /*
- case 'h':
- {
- if(!strcmp (element_name, "homebank"))
- {
- if(!strcmp (attribute_names[0], "v" ))
- {
- version = g_ascii_strtod(attribute_values[0], NULL);
- DB( g_print(" version %f\n", version) );
- }
+ Account *acc = lnk_acc->data;
- }
- }
- */
+ acc->key++;
+ acc->pos++;
+ da_acc_insert (acc);
- case 'a':
+ list = g_queue_peek_head_link(acc->txn_queue);
+ while (list != NULL)
{
- if(!strcmp (element_name, "account"))
- {
- Account *entry = da_acc_malloc();
+ Transaction *entry = list->data;
+ entry->kacc++;
+ entry->kxferacc++;
+ list = g_list_next(list);
+ }
+ lnk_acc = g_list_next(lnk_acc);
+ }
+ g_list_free(lst_acc);
- for (i = 0; attribute_names[i] != NULL; i++)
- {
- //DB( g_print(" att=%s val=%s\n", attribute_names[i], attribute_values[i]) );
-
- if(!strcmp (attribute_names[i], "key" )) { entry->key = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "flags" )) { entry->flags = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "pos" )) { entry->pos = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "type" )) { entry->type = atoi(attribute_values[i]); }
- //else if(!strcmp (attribute_names[i], "curr" )) { entry->kcur = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "name" )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->name = g_strdup(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "number" )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->number = g_strdup(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "bankname")) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->bankname = g_strdup(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "initial" )) { entry->initial = g_ascii_strtod(attribute_values[i], NULL); }
- else if(!strcmp (attribute_names[i], "minimum" )) { entry->minimum = g_ascii_strtod(attribute_values[i], NULL); }
- else if(!strcmp (attribute_names[i], "cheque1" )) { entry->cheque1 = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "cheque2" )) { entry->cheque2 = atoi(attribute_values[i]); }
+ //we loose some small memory here
+ g_hash_table_steal_all(h_old_acc);
- }
+ list = g_list_first(GLOBALS->arc_list);
+ while (list != NULL)
+ {
+ Archive *entry = list->data;
+ entry->kacc++;
+ entry->kxferacc++;
+ list = g_list_next(list);
+ }
+}
- //version upgrade: type was added in 0.2
- //todo: for stock account
- /*
- if(version <= 0.1)
- {
- entry->type = ACC_TYPE_BANK;
- DB( g_print(" acctype forced to BANK\n") );
- }
- */
+// v0.2 to v0.3 : we must assume categories exists : bugs 303886, 303738
+static void homebank_upgrade_to_v03(void)
+{
+GList *lst_acc, *lnk_acc;
+GList *list;
- DB( g_print(" version %f\n", ctx->version) );
+ DB( g_print("\n[hb-xml] homebank_upgrade_to_v03\n") );
- //upgrade to v0.2 file
- // we must change account reference by making a +1 to its index references
- if( ctx->version == 0.1 )
- {
- entry->key++;
- entry->pos = entry->key;
- }
+ 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;
- //all attribute loaded: append
- da_acc_insert(entry);
- }
+ list = g_queue_peek_head_link(acc->txn_queue);
+ while (list != NULL)
+ {
+ Transaction *entry = list->data;
- //assign
- else if(!strcmp (element_name, "asg"))
- {
- Assign *entry = da_asg_malloc();
- gint exact = 0;
+ da_transaction_consistency(entry);
+ list = g_list_next(list);
+ }
+ lnk_acc = g_list_next(lnk_acc);
+ }
+ g_list_free(lst_acc);
- for (i = 0; attribute_names[i] != NULL; i++)
- {
- //DB( g_print(" att=%s val=%s\n", attribute_names[i], attribute_values[i]) );
-
- if(!strcmp (attribute_names[i], "key" )) { entry->key = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "flags" )) { entry->flags = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "field" )) { entry->field = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "name" )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->name = g_strdup(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "payee" )) { entry->kpay = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "category")) { entry->kcat = atoi(attribute_values[i]); }
- //else if(!strcmp (attribute_names[i], "paymode" )) { entry->paymode = atoi(attribute_values[i]); }
- // prior v08
- else if(!strcmp (attribute_names[i], "exact" )) { exact = atoi(attribute_values[i]); }
- }
- /* in v08 exact moved to flag */
- if( ctx->version <= 0.7)
- {
- entry->flags = (ASGF_DOCAT|ASGF_DOPAY);
- if( exact > 0 )
- entry->flags |= ASGF_EXACT;
- }
+ list = g_list_first(GLOBALS->arc_list);
+ while (list != NULL)
+ {
+ Archive *entry = list->data;
- //all attribute loaded: append
- da_asg_append(entry);
+ da_archive_consistency(entry);
+ list = g_list_next(list);
+ }
+}
- }
+static void homebank_upgrade_to_v04(void)
+{
+ DB( g_print("\n[hb-xml] homebank_upgrade_to_v04\n") );
- }
- break;
+ GLOBALS->arc_list = da_archive_sort(GLOBALS->arc_list);
+}
- case 'p':
- {
- if(!strcmp (element_name, "pay"))
- {
- Payee *entry = da_pay_malloc();
- for (i = 0; attribute_names[i] != NULL; i++)
- {
- //DB( g_print(" att=%s val=%s\n", attribute_names[i], attribute_values[i]) );
+// v0.4 to v0.5 :
+// we must assume kxferacc exists in archives for internal xfer : bug 528923
+// if not, delete automation from the archive
+static void homebank_upgrade_to_v05(void)
+{
+GList *list;
- if(!strcmp (attribute_names[i], "key" )) { entry->key = atoi(attribute_values[i]); }
- //else if(!strcmp (attribute_names[i], "flags")) { entry->flags = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "name" )) { entry->name = g_strdup(attribute_values[i]); }
- }
+ DB( g_print("\n[hb-xml] homebank_upgrade_to_v05\n") );
- //all attribute loaded: append
- da_pay_insert(entry);
+ list = g_list_first(GLOBALS->arc_list);
+ while (list != NULL)
+ {
+ Archive *entry = list->data;
- }
- else if(!strcmp (element_name, "properties"))
- {
- for (i = 0; attribute_names[i] != NULL; i++)
- {
- if(!strcmp (attribute_names[i], "title" )) { g_free(GLOBALS->owner); GLOBALS->owner = g_strdup(attribute_values[i]); }
- //else if(!strcmp (attribute_names[i], "curr" )) { GLOBALS->kcur = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "car_category")) { GLOBALS->vehicle_category = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "auto_smode" )) { GLOBALS->auto_smode = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "auto_weekday")) { GLOBALS->auto_weekday = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "auto_nbdays" )) { GLOBALS->auto_nbdays = atoi(attribute_values[i]); }
- }
- }
- }
- break;
+ da_archive_consistency(entry);
+ list = g_list_next(list);
+ }
+}
- case 'c':
- {
- if(!strcmp (element_name, "cat"))
- {
- Category *entry = da_cat_malloc();
- gboolean budget;
- for (i = 0; attribute_names[i] != NULL; i++)
- {
- //DB( g_print(" att=%s val=%s\n", attribute_names[i], attribute_values[i]) );
+// v0.5 to v0.6 : we must change kxferacc to 0 on non Xfer transactions
+//#677351
+static void homebank_upgrade_to_v06(void)
+{
+GList *lst_acc, *lnk_acc;
+GList *list;
- if(!strcmp (attribute_names[i], "key" )) { entry->key = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "parent")) { entry->parent = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "flags" )) { entry->flags = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "name" )) { entry->name = g_strdup(attribute_values[i]); }
+ DB( g_print("\n[hb-xml] homebank_upgrade_to_v06\n") );
- budget = FALSE;
- for(j=0;j<=12;j++)
- {
- gchar *tmpname;
+ 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;
- tmpname = g_strdup_printf ("b%d", j);
- if(!(strcmp (attribute_names[i], tmpname))) { entry->budget[j] = g_ascii_strtod(attribute_values[i], NULL); }
- g_free(tmpname);
+ list = g_queue_peek_head_link(acc->txn_queue);
+ while (list != NULL)
+ {
+ Transaction *entry = list->data;
+ da_transaction_consistency(entry);
+ list = g_list_next(list);
+ }
+ lnk_acc = g_list_next(lnk_acc);
+ }
+ g_list_free(lst_acc);
- if(entry->budget[j]) budget = TRUE;
- }
- if(budget == TRUE)
- entry->flags |= GF_BUDGET;
- }
+ list = g_list_first(GLOBALS->arc_list);
+ while (list != NULL)
+ {
+ Archive *entry = list->data;
+ da_archive_consistency(entry);
+ list = g_list_next(list);
+ }
+}
- //all attribute loaded: append
- da_cat_insert( entry);
- }
-/* else if(!strcmp (element_name, "cur"))
- {
- Currency *entry = da_cur_malloc ();
- for (i = 0; attribute_names[i] != NULL; i++)
- {
- //DB( g_print(" att=%s val=%s\n", attribute_names[i], attribute_values[i]) );
-
- if(!strcmp (attribute_names[i], "key" )) { entry->key = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "name" )) { entry->name = g_strdup(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "iso" )) { entry->iso_code = g_strdup(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "symb" )) { entry->symbol = g_strdup(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "syprf" )) { entry->sym_prefix = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "dchar" )) { entry->decimal_char = g_strdup(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "gchar" )) { entry->grouping_char = g_strdup(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "frac" )) { entry->frac_digits = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "rate" )) { entry->rate = g_ascii_strtod(attribute_values[i], NULL); }
- else if(!strcmp (attribute_names[i], "mdate ")) { entry->mdate = atoi(attribute_values[i]); }
+// v0.7 AF_BUDGET deleted instead of AF_NOBUDGET
+static void homebank_upgrade_to_v07(void)
+{
+GList *lacc, *list;
- }
+ DB( g_print("\n[hb-xml] homebank_upgrade_to_v07\n") );
- //all attribute loaded: append
- da_cur_insert (entry);
- }
- */
- }
- break;
+ lacc = list = g_hash_table_get_values(GLOBALS->h_acc);
+ while (list != NULL)
+ {
+ Account *acc = list->data;
- case 't':
+ if( acc->flags & AF_OLDBUDGET ) // budget include
{
- if(!strcmp (element_name, "tags"))
- {
- Tag *entry = da_tag_malloc();
-
- for (i = 0; attribute_names[i] != NULL; i++)
- {
- //DB( g_print(" att=%s val=%s\n", attribute_names[i], attribute_values[i]) );
-
- if(!strcmp (attribute_names[i], "key" )) { entry->key = atoi(attribute_values[i]); }
- //else if(!strcmp (attribute_names[i], "flags")) { entry->flags = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "name" )) { entry->name = g_strdup(attribute_values[i]); }
- }
-
- //all attribute loaded: append
- da_tag_insert(entry);
-
- }
+ acc->flags &= ~(AF_OLDBUDGET);
}
-
- case 'f':
+ else
{
- if(!strcmp (element_name, "fav"))
- {
- Archive *entry = da_archive_malloc();
+ acc->flags |= AF_NOBUDGET;
+ }
- for (i = 0; attribute_names[i] != NULL; i++)
- {
- //DB( g_print(" att=%s val=%s\n", attribute_names[i], attribute_values[i]) );
-
- if(!strcmp (attribute_names[i], "amount" )) { entry->amount = g_ascii_strtod(attribute_values[i], NULL); }
- else if(!strcmp (attribute_names[i], "account" )) { entry->kacc = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "dst_account")) { entry->kxferacc = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "paymode" )) { entry->paymode = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "flags" )) { entry->flags = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "payee" )) { entry->kpay = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "category" )) { entry->kcat = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "wording" )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->wording = g_strdup(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "nextdate" )) { entry->nextdate = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "every" )) { entry->every = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "unit" )) { entry->unit = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "limit" )) { entry->limit = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "weekend" )) { entry->weekend = atoi(attribute_values[i]); }
+ list = g_list_next(list);
+ }
+ g_list_free(lacc);
- }
+}
- //all attribute loaded: append
- GLOBALS->arc_list = g_list_append(GLOBALS->arc_list, entry);
+static void homebank_upgrade_to_v08(void)
+{
+GList *lst_acc, *lnk_acc;
+GList *list;
- }
- }
- break;
+ DB( g_print("\n[hb-xml] homebank_upgrade_to_v08\n") );
- /*
- case 'r':
+ 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;
+
+ list = g_queue_peek_head_link(acc->txn_queue);
+ while (list != NULL)
{
+ Transaction *entry = list->data;
+ da_transaction_consistency(entry);
+ list = g_list_next(list);
}
- break;
- */
+ lnk_acc = g_list_next(lnk_acc);
+ }
+ g_list_free(lst_acc);
- case 'o':
- {
- if(!strcmp (element_name, "ope"))
- {
- Transaction *entry = da_transaction_malloc();
- gchar *scat = NULL;
- gchar *samt = NULL;
- gchar *smem = NULL;
- gboolean split = FALSE;
- for (i = 0; attribute_names[i] != NULL; i++)
- {
- //DB( g_print(" att=%s val=%s\n", attribute_names[i], attribute_values[i]) );
-
- if(!strcmp (attribute_names[i], "date" )) { entry->date = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "amount" )) { entry->amount = g_ascii_strtod(attribute_values[i], NULL); }
- else if(!strcmp (attribute_names[i], "account" )) { entry->kacc = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "dst_account")) { entry->kxferacc = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "paymode" )) { entry->paymode = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "flags" )) { entry->flags = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "payee" )) { entry->kpay = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "category" )) { entry->kcat = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "wording" )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->wording = g_strdup(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "info" )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->info = g_strdup(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "tags" ))
- {
- if(attribute_values[i] != NULL && strlen(attribute_values[i]) > 0 && strcmp(attribute_values[i],"(null)") != 0 )
- {
- transaction_tags_parse(entry, attribute_values[i]);
- }
- }
- else if(!strcmp (attribute_names[i], "kxfer" )) { entry->kxfer = atoi(attribute_values[i]); }
- else if(!strcmp (attribute_names[i], "scat" )) { scat = (gchar *)attribute_values[i]; split = TRUE; }
- else if(!strcmp (attribute_names[i], "samt" )) { samt = (gchar *)attribute_values[i]; split = TRUE; }
- else if(!strcmp (attribute_names[i], "smem" )) { smem = (gchar *)attribute_values[i]; split = TRUE; }
- }
+}
- //bugfix 303886
- //if(entry->kcat < 0)
- // entry->kcat = 0;
- if(split == TRUE)
- {
- transaction_splits_parse(entry, scat, samt, smem);
- }
+static void homebank_upgrade_to_v10(void)
+{
+GList *lst_acc, *lnk_acc;
+GList *list;
- //all attribute loaded: append
- // we use prepend here, the list will be reversed later for perf reason
- da_transaction_prepend(entry);
- }
- }
- break;
+ DB( g_print("\n[hb-xml] homebank_upgrade_to_v10\n") );
+
+ 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;
+
+ list = g_queue_peek_head_link(acc->txn_queue);
+ while (list != NULL)
+ {
+ Transaction *entry = list->data;
+ entry->status = TXN_STATUS_NONE;
+ if(entry->flags & OF_OLDVALID)
+ entry->status = TXN_STATUS_RECONCILED;
+ else
+ if(entry->flags & OF_OLDREMIND)
+ entry->status = TXN_STATUS_REMIND;
+ //remove those flags
+ entry->flags &= ~(OF_OLDVALID|OF_OLDREMIND);
+ list = g_list_next(list);
+ }
+ lnk_acc = g_list_next(lnk_acc);
}
+ g_list_free(lst_acc);
}
-/*
-static void
-end_element_handler (GMarkupParseContext *context,
- const gchar *element_name,
- gpointer user_data,
- GError **error)
+
+static void homebank_upgrade_to_v11(void)
{
- ParseContext *ctx = user_data;
+GList *list;
- //DB( g_print("-- end element: %s\n", element_name) );
+ DB( g_print("\n[hb-xml] homebank_upgrade_to_v11\n") );
+
+ list = g_list_first(GLOBALS->arc_list);
+ while (list != NULL)
+ {
+ Archive *entry = list->data;
+
+ entry->status = TXN_STATUS_NONE;
+ if(entry->flags & OF_OLDVALID)
+ entry->status = TXN_STATUS_RECONCILED;
+ else
+ if(entry->flags & OF_OLDREMIND)
+ entry->status = TXN_STATUS_REMIND;
+
+ //remove those flags
+ entry->flags &= ~(OF_OLDVALID|OF_OLDREMIND);
+ list = g_list_next(list);
+ }
}
-*/
-static GMarkupParser hb_parser = {
- start_element_handler,
- NULL, //end_element_handler,
- NULL, //text_handler,
- NULL,
- NULL //cleanup
-};
-/*
-** XML load homebank file: hbfile
-*/
-gint homebank_load_xml(gchar *filename)
+// v0.6 to v0.7 : assign a default currency
+static void homebank_upgrade_to_v12(void)
{
-gint retval;
-gchar *buffer;
-gsize length;
-GError *error = NULL;
-ParseContext ctx = { 0 };
-GMarkupParseContext *context;
-gboolean rc;
+ DB( g_print("\n[hb-xml] homebank_upgrade_to_v12\n") );
- DB( g_print("\n[hb-xml] homebank_load_xml\n") );
+ // set a base currency to the hbfile if not
+ DB( g_print("GLOBALS->kcur %d\n", GLOBALS->kcur) );
- retval = XML_OK;
- if (!g_file_get_contents (filename, &buffer, &length, &error))
- {
- //g_message ("%s", error->message);
- retval = XML_IO_ERROR;
- g_error_free (error);
- }
- else
- {
- gchar *v_buffer;
- gdouble version;
+ ui_dialog_upgrade_choose_currency();
+}
- /* v3.4 add :: prevent load of future file version */
- v_buffer = g_strstr_len(buffer, 50, "<homebank v=");
- if( v_buffer == NULL )
- return XML_FILE_ERROR;
- DB( g_print("- id line: --(%.50s)\n\n", v_buffer) );
+static void homebank_upgrade_to_v12_7(void)
+{
+GList *lst_acc, *lnk_acc;
- version = g_ascii_strtod(v_buffer+13, NULL); /* a little hacky, but works ! */
- if( version == 0.0 )
- version = 0.1;
+ DB( g_print("\n[hb-xml] homebank_upgrade_to_v12\n") );
- ctx.version = version;
+ //#1674045 exclude closed account from everywhere to
+ //keep continuity for user that don't want to change this
+ 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;
- if( version > FILE_VERSION )
+ if( acc->flags & AF_CLOSED )
{
- DB( g_print("- failed: version %f is not supported (max is %f)\n", version, FILE_VERSION) );
- return XML_VERSION_ERROR;
+ if( !(acc->flags & AF_NOSUMMARY) )
+ acc->flags |= AF_NOSUMMARY;
+ if( !(acc->flags & AF_NOBUDGET) )
+ acc->flags |= AF_NOBUDGET;
+ if( !(acc->flags & AF_NOREPORT) )
+ acc->flags |= AF_NOREPORT;
}
- else
- {
- DB( g_print("- ok : version=%.1f\n", version) );
+ lnk_acc = g_list_next(lnk_acc);
+ }
+ g_list_free(lst_acc);
+}
- /* 1st: validate the file is well in utf-8 */
- DB( g_print("- ensure UTF-8\n") );
- buffer = homebank_utf8_ensure(buffer);
- /* then process the buffer */
- #if MYDEBUG == 1
- GTimer *t = g_timer_new();
- g_print("- start parse\n");
- #endif
-
- context = g_markup_parse_context_new (&hb_parser, 0, &ctx, NULL);
+// lower v0.6 : we must assume categories/payee exists
+// and strong link to xfer
+// #632496
+static void homebank_upgrade_lower_v06(void)
+{
+GList *lst_acc, *lnk_acc;
+Category *cat;
+Payee *pay;
+GList *lrul, *list;
- error = NULL;
- rc = g_markup_parse_context_parse (context, buffer, length, &error);
+ DB( g_print("\n[hb-xml] homebank_upgrade_lower_v06\n") );
- if( error )
- g_print("failed: %s\n", error->message);
+ 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;
+
+ list = g_queue_peek_head_link(acc->txn_queue);
+ while (list != NULL)
+ {
+ Transaction *entry = list->data;
- if( rc == FALSE )
+ //also strong link internal xfer
+ if(entry->paymode == PAYMODE_INTXFER && entry->kxfer == 0)
{
- error = NULL;
- g_markup_parse_context_end_parse(context, &error);
-
- if( error )
- g_print("failed: %s\n", error->message);
+ Transaction *child = transaction_old_get_child_transfer(entry);
+ if(child != NULL)
+ {
+ transaction_xfer_change_to_child(entry, child);
+ }
}
- g_markup_parse_context_free (context);
- g_free (buffer);
-
- //reverse the glist (see g_list append idiom to perf for reason
- // we use prepend and then reverse
- GLOBALS->ope_list = g_list_reverse(GLOBALS->ope_list);
+ da_transaction_consistency(entry);
- DB( g_print("- end parse : %f sec\n", g_timer_elapsed(t, NULL)) );
- DB( g_timer_destroy (t) );
+ list = g_list_next(list);
+ }
+ lnk_acc = g_list_next(lnk_acc);
+ }
+ g_list_free(lst_acc);
- /* file upgrade / bugfix */
- if( version <= 0.1 )
- homebank_upgrade_to_v02();
- if( version <= 0.2 )
- homebank_upgrade_to_v03();
- if( version <= 0.3 )
- homebank_upgrade_to_v04();
- if( version <= 0.4 )
- homebank_upgrade_to_v05();
- if( version <= 0.5 )
- {
- homebank_upgrade_to_v06();
- homebank_upgrade_lower_v06();
- }
- if( version <= 0.6 )
- {
- homebank_upgrade_to_v07();
- hbfile_sanity_check();
- }
- if( version <= 0.7 )
- homebank_upgrade_to_v08();
- if( version <= 0.8 )
- hbfile_sanity_check();
- // next ?
-
+ lrul = list = g_hash_table_get_values(GLOBALS->h_rul);
+ while (list != NULL)
+ {
+ Assign *entry = list->data;
+
+ cat = da_cat_get(entry->kcat);
+ if(cat == NULL)
+ {
+ DB( g_print(" !! fixing cat for rul: %d is unknow\n", entry->kcat) );
+ entry->kcat = 0;
}
- }
- return retval;
+ pay = da_pay_get(entry->kpay);
+ if(pay == NULL)
+ {
+ DB( g_print(" !! fixing pay for rul: %d is unknow\n", entry->kpay) );
+ entry->kpay = 0;
+ }
+
+
+ list = g_list_next(list);
+ }
+ g_list_free(lrul);
}
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
-// v0.1 to v0.2 : we must change account reference by making a +1 to its index references
-static void homebank_upgrade_to_v02(void)
+
+static void homebank_load_xml_acc(ParseContext *ctx, const gchar **attribute_names, const gchar **attribute_values)
{
-GList *list;
+Account *entry = da_acc_malloc();
+gint i;
- DB( g_print("\n[hb-xml] homebank_upgrade_to_v02\n") );
+ for (i = 0; attribute_names[i] != NULL; i++)
+ {
+ //DB( g_print(" att='%s' val='%s'\n", attribute_names[i], attribute_values[i]) );
+
+ if(!strcmp (attribute_names[i], "key" )) { entry->key = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "flags" )) { entry->flags = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "pos" )) { entry->pos = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "type" )) { entry->type = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "curr" )) { entry->kcur = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "name" )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->name = g_strdup(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "number" )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->number = g_strdup(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "bankname")) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->bankname = g_strdup(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "initial" )) { entry->initial = g_ascii_strtod(attribute_values[i], NULL); }
+
+ else if(!strcmp (attribute_names[i], "minimum" )) { entry->minimum = g_ascii_strtod(attribute_values[i], NULL); }
+ else if(!strcmp (attribute_names[i], "cheque1" )) { entry->cheque1 = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "cheque2" )) { entry->cheque2 = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "notes" )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->notes = g_strdup(attribute_values[i]); }
+ }
- list = g_list_first(GLOBALS->ope_list);
- while (list != NULL)
+ //all attribute loaded: append
+ da_acc_insert(entry);
+}
+
+
+static void homebank_load_xml_asg(ParseContext *ctx, const gchar **attribute_names, const gchar **attribute_values)
+{
+Assign *entry = da_asg_malloc();
+gint exact = 0;
+gint i;
+
+ for (i = 0; attribute_names[i] != NULL; i++)
{
- Transaction *entry = list->data;
- entry->kacc++;
- entry->kxferacc++;
- list = g_list_next(list);
+ //DB( g_print(" att='%s' val='%s'\n", attribute_names[i], attribute_values[i]) );
+
+ if(!strcmp (attribute_names[i], "key" )) { entry->key = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "flags" )) { entry->flags = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "field" )) { entry->field = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "name" )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->text = g_strdup(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "payee" )) { entry->kpay = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "category")) { entry->kcat = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "paymode" )) { entry->paymode = atoi(attribute_values[i]); }
+ // prior v08
+ else if(!strcmp (attribute_names[i], "exact" )) { exact = atoi(attribute_values[i]); }
}
- list = g_list_first(GLOBALS->arc_list);
- while (list != NULL)
+ /* in v08 exact moved to flag */
+ if( ctx->file_version <= 0.7)
{
- Archive *entry = list->data;
- entry->kacc++;
- entry->kxferacc++;
- list = g_list_next(list);
+ entry->flags = (ASGF_DOCAT|ASGF_DOPAY);
+ if( exact > 0 )
+ entry->flags |= ASGF_EXACT;
}
+
+ //all attribute loaded: append
+ da_asg_append(entry);
+
}
-// v0.2 to v0.3 : we must assume categories exists : bugs 303886, 303738
-static void homebank_upgrade_to_v03(void)
+
+static void homebank_load_xml_pay(ParseContext *ctx, const gchar **attribute_names, const gchar **attribute_values)
{
-GList *list;
+Payee *entry = da_pay_malloc();
+gint i;
- DB( g_print("\n[hb-xml] homebank_upgrade_to_v03\n") );
-
- list = g_list_first(GLOBALS->ope_list);
- while (list != NULL)
+ for (i = 0; attribute_names[i] != NULL; i++)
{
- Transaction *entry = list->data;
+ //DB( g_print(" att='%s' val='%s'\n", attribute_names[i], attribute_values[i]) );
- da_transaction_consistency(entry);
- list = g_list_next(list);
+ if(!strcmp (attribute_names[i], "key" )) { entry->key = atoi(attribute_values[i]); }
+ //else if(!strcmp (attribute_names[i], "flags")) { entry->flags = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "name" )) { entry->name = g_strdup(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "category")) { entry->kcat = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "paymode" )) { entry->paymode = atoi(attribute_values[i]); }
}
- list = g_list_first(GLOBALS->arc_list);
- while (list != NULL)
- {
- Archive *entry = list->data;
+ //all attribute loaded: append
+ da_pay_insert(entry);
+}
- da_archive_consistency(entry);
- list = g_list_next(list);
+
+static void homebank_load_xml_prop(ParseContext *ctx, const gchar **attribute_names, const gchar **attribute_values)
+{
+gint i;
+
+ for (i = 0; attribute_names[i] != NULL; i++)
+ {
+ if(!strcmp (attribute_names[i], "title" )) { g_free(GLOBALS->owner); GLOBALS->owner = g_strdup(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "curr" )) { GLOBALS->kcur = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "car_category")) { GLOBALS->vehicle_category = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "auto_smode" )) { GLOBALS->auto_smode = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "auto_weekday")) { GLOBALS->auto_weekday = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "auto_nbdays" )) { GLOBALS->auto_nbdays = atoi(attribute_values[i]); }
}
}
-static void homebank_upgrade_to_v04(void)
+
+static void homebank_load_xml_cat(ParseContext *ctx, const gchar **attribute_names, const gchar **attribute_values)
{
- DB( g_print("\n[hb-xml] homebank_upgrade_to_v04\n") );
+Category *entry = da_cat_malloc();
+gboolean budget;
+gint i, j;
- GLOBALS->arc_list = da_archive_sort(GLOBALS->arc_list);
+ for (i = 0; attribute_names[i] != NULL; i++)
+ {
+ //DB( g_print(" att='%s' val='%s'\n", attribute_names[i], attribute_values[i]) );
+
+ if(!strcmp (attribute_names[i], "key" )) { entry->key = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "parent")) { entry->parent = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "flags" )) { entry->flags = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "name" )) { entry->name = g_strdup(attribute_values[i]); }
+
+ budget = FALSE;
+ for(j=0;j<=12;j++)
+ {
+ gchar *tmpname;
+
+ tmpname = g_strdup_printf ("b%d", j);
+ if(!(strcmp (attribute_names[i], tmpname))) { entry->budget[j] = g_ascii_strtod(attribute_values[i], NULL); }
+ g_free(tmpname);
+
+ if(entry->budget[j]) budget = TRUE;
+ }
+ if(budget == TRUE)
+ entry->flags |= GF_BUDGET;
+
+ }
+
+ //all attribute loaded: append
+ da_cat_insert( entry);
}
-// v0.4 to v0.5 :
-// we must assume kxferacc exists in archives for internal xfer : bug 528923
-// if not, remove automation from the archive
-static void homebank_upgrade_to_v05(void)
+static void homebank_load_xml_cur(ParseContext *ctx, const gchar **attribute_names, const gchar **attribute_values)
{
-GList *list;
+Currency *entry = da_cur_malloc ();
+gint i;
- DB( g_print("\n[hb-xml] homebank_upgrade_to_v05\n") );
+ for (i = 0; attribute_names[i] != NULL; i++)
+ {
+ //DB( g_print(" att='%s' val='%s'\n", attribute_names[i], attribute_values[i]) );
+
+ if(!strcmp (attribute_names[i], "key" )) { entry->key = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "flags" )) { entry->flags = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "name" )) { entry->name = g_strdup(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "iso" )) { entry->iso_code = g_strdup(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "symb" )) { entry->symbol = g_strdup(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "syprf" )) { entry->sym_prefix = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "dchar" )) { entry->decimal_char = g_strdup(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "gchar" )) { entry->grouping_char = g_strdup(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "frac" )) { entry->frac_digits = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "rate" )) { entry->rate = g_ascii_strtod(attribute_values[i], NULL); }
+ else if(!strcmp (attribute_names[i], "mdate ")) { entry->mdate = atoi(attribute_values[i]); }
- list = g_list_first(GLOBALS->arc_list);
- while (list != NULL)
+ }
+
+ //all attribute loaded: append
+ da_cur_insert (entry);
+}
+
+
+static void homebank_load_xml_tag(ParseContext *ctx, const gchar **attribute_names, const gchar **attribute_values)
+{
+Tag *entry = da_tag_malloc();
+gint i;
+
+ for (i = 0; attribute_names[i] != NULL; i++)
{
- Archive *entry = list->data;
+ //DB( g_print(" att='%s' val='%s'\n", attribute_names[i], attribute_values[i]) );
- da_archive_consistency(entry);
- list = g_list_next(list);
+ if(!strcmp (attribute_names[i], "key" )) { entry->key = atoi(attribute_values[i]); }
+ //else if(!strcmp (attribute_names[i], "flags")) { entry->flags = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "name" )) { entry->name = g_strdup(attribute_values[i]); }
}
+
+ //all attribute loaded: append
+ da_tag_insert(entry);
}
-// v0.5 to v0.6 : we must change kxferacc to 0 on non Xfer transactions
-//#677351
-static void homebank_upgrade_to_v06(void)
+static void homebank_load_xml_fav(ParseContext *ctx, const gchar **attribute_names, const gchar **attribute_values)
{
-GList *list;
+Archive *entry = da_archive_malloc();
+gchar *scat = NULL;
+gchar *samt = NULL;
+gchar *smem = NULL;
+gboolean split = FALSE;
+gint i;
+
+ for (i = 0; attribute_names[i] != NULL; i++)
+ {
+ //DB( g_print(" att='%s' val='%s'\n", attribute_names[i], attribute_values[i]) );
- DB( g_print("\n[hb-xml] homebank_upgrade_to_v06\n") );
- list = g_list_first(GLOBALS->ope_list);
- while (list != NULL)
+ if(!strcmp (attribute_names[i], "amount" )) { entry->amount = g_ascii_strtod(attribute_values[i], NULL); }
+ else if(!strcmp (attribute_names[i], "account" )) { entry->kacc = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "dst_account")) { entry->kxferacc = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "paymode" )) { entry->paymode = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "st" )) { entry->status = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "flags" )) { entry->flags = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "payee" )) { entry->kpay = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "category" )) { entry->kcat = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "wording" )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->memo = g_strdup(attribute_values[i]); }
+
+
+
+
+
+
+
+ else if(!strcmp (attribute_names[i], "nextdate" )) { entry->nextdate = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "every" )) { entry->every = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "unit" )) { entry->unit = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "limit" )) { entry->limit = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "weekend" )) { entry->weekend = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "gap" )) { entry->daygap = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "scat" )) { scat = (gchar *)attribute_values[i]; split = TRUE; }
+ else if(!strcmp (attribute_names[i], "samt" )) { samt = (gchar *)attribute_values[i]; split = TRUE; }
+ else if(!strcmp (attribute_names[i], "smem" )) { smem = (gchar *)attribute_values[i]; split = TRUE; }
+
+ }
+
+ if(split == TRUE)
{
- Transaction *entry = list->data;
- da_transaction_consistency(entry);
- list = g_list_next(list);
+ if (da_splits_parse(entry->splits, scat, samt, smem) > 0)
+ {
+ entry->flags |= OF_SPLIT; //Flag that Splits are active
+ }
}
- list = g_list_first(GLOBALS->arc_list);
- while (list != NULL)
+ //all attribute loaded: append
+ GLOBALS->arc_list = g_list_append(GLOBALS->arc_list, entry);
+}
+
+
+static void homebank_load_xml_ope(ParseContext *ctx, const gchar **attribute_names, const gchar **attribute_values)
+{
+Transaction *entry = da_transaction_malloc();
+gchar *scat = NULL;
+gchar *samt = NULL;
+gchar *smem = NULL;
+gboolean split = FALSE;
+gint i;
+
+ for (i = 0; attribute_names[i] != NULL; i++)
{
- Archive *entry = list->data;
- da_archive_consistency(entry);
- list = g_list_next(list);
+ //DB( g_print(" att='%s' val='%s'\n", attribute_names[i], attribute_values[i]) );
+
+ if(!strcmp (attribute_names[i], "date" )) { entry->date = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "amount" )) { entry->amount = g_ascii_strtod(attribute_values[i], NULL); }
+ else if(!strcmp (attribute_names[i], "account" )) { entry->kacc = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "dst_account")) { entry->kxferacc = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "paymode" )) { entry->paymode = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "st" )) { entry->status = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "flags" )) { entry->flags = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "payee" )) { entry->kpay = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "category" )) { entry->kcat = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "wording" )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->memo = g_strdup(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "info" )) { if(strcmp(attribute_values[i],"(null)") && attribute_values[i] != NULL) entry->info = g_strdup(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "tags" ))
+ {
+ if(attribute_values[i] != NULL && strlen(attribute_values[i]) > 0 && strcmp(attribute_values[i],"(null)") != 0 )
+ {
+ transaction_tags_parse(entry, attribute_values[i]);
+ }
+ }
+ else if(!strcmp (attribute_names[i], "kxfer" )) { entry->kxfer = atoi(attribute_values[i]); }
+ else if(!strcmp (attribute_names[i], "scat" )) { scat = (gchar *)attribute_values[i]; split = TRUE; }
+ else if(!strcmp (attribute_names[i], "samt" )) { samt = (gchar *)attribute_values[i]; split = TRUE; }
+ else if(!strcmp (attribute_names[i], "smem" )) { smem = (gchar *)attribute_values[i]; split = TRUE; }
}
+
+ //bugfix 303886
+ //if(entry->kcat < 0)
+ // entry->kcat = 0;
+
+ if(split == TRUE)
+ {
+ if (da_splits_parse(entry->splits, scat, samt, smem) > 0)
+ {
+ entry->flags |= OF_SPLIT; //Flag that Splits are active
+ }
+ }
+
+ //all attribute loaded: append
+ // for perf reason we use prepend here, the list will be reversed later
+ da_transaction_prepend(entry);
}
-// v0.7 AF_BUDGET removed instead of AF_NOBUDGET
-static void homebank_upgrade_to_v07(void)
+
+
+static void
+start_element_handler (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ gpointer user_data,
+ GError **error)
{
-GList *lacc, *list;
+ParseContext *ctx = user_data;
+//GtkUIManager *self = ctx->self;
- DB( g_print("\n[hb-xml] homebank_upgrade_to_v07\n") );
+ //DB( g_print("** start element: %s\n", element_name) );
- lacc = list = g_hash_table_get_values(GLOBALS->h_acc);
- while (list != NULL)
+ switch(element_name[0])
{
- Account *acc = list->data;
+ case 'a':
+ {
+ if(!strcmp (element_name, "account")) //account
+ {
+ homebank_load_xml_acc(ctx, attribute_names, attribute_values);
+ }
+ else if(!strcmp (element_name, "asg")) //assign
+ {
+ homebank_load_xml_asg(ctx, attribute_names, attribute_values);
+ }
+ }
+ break;
- if( acc->flags & AF_OLDBUDGET ) // budget include
+ case 'p':
{
- acc->flags &= ~(AF_OLDBUDGET);
+ if(!strcmp (element_name, "pay"))
+ {
+ homebank_load_xml_pay(ctx, attribute_names, attribute_values);
+ }
+ else if(!strcmp (element_name, "properties"))
+ {
+ homebank_load_xml_prop(ctx, attribute_names, attribute_values);
+ }
}
- else
+ break;
+
+ case 'c':
{
- acc->flags |= AF_NOBUDGET;
+ if(!strcmp (element_name, "cat"))
+ {
+ homebank_load_xml_cat(ctx, attribute_names, attribute_values);
+ }
+ else if(!strcmp (element_name, "cur"))
+ {
+ homebank_load_xml_cur(ctx, attribute_names, attribute_values);
+ }
}
+ break;
- list = g_list_next(list);
- }
- g_list_free(lacc);
+ case 't':
+ {
+ if(!strcmp (element_name, "tags"))
+ {
+ homebank_load_xml_tag(ctx, attribute_names, attribute_values);
+ }
+ }
+ break;
+ case 'f':
+ {
+ if(!strcmp (element_name, "fav"))
+ {
+ homebank_load_xml_fav(ctx, attribute_names, attribute_values);
+ }
+ }
+ break;
+
+ case 'o':
+ {
+ if(!strcmp (element_name, "ope"))
+ {
+ homebank_load_xml_ope(ctx, attribute_names, attribute_values);
+ }
+ }
+ break;
+ }
}
-static void homebank_upgrade_to_v08(void)
-{
-GList *list;
- DB( g_print("\n[hb-xml] homebank_upgrade_to_v08\n") );
+/*
+static void
+end_element_handler (GMarkupParseContext *context,
+ const gchar *element_name,
+ gpointer user_data,
+ GError **error)
+{
+ ParseContext *ctx = user_data;
- list = g_list_first(GLOBALS->ope_list);
- while (list != NULL)
- {
- Transaction *entry = list->data;
- da_transaction_consistency(entry);
- list = g_list_next(list);
- }
+ //DB( g_print("-- end element: %s\n", element_name) );
}
+*/
+static GMarkupParser hb_parser = {
+ start_element_handler,
+ NULL, //end_element_handler,
+ NULL, //text_handler,
+ NULL,
+ NULL //cleanup
+};
-// v0.6 to v0.7 : assign a default currency
-/*
-static void homebank_upgrade_to_v08(void)
+
+static gboolean hb_xml_get_version(ParseContext *ctx, gchar *buffer)
{
+gchar *v_buffer;
- // set a base currency to the hbfile if not
- g_print("GLOBALS->kcur %d\n", GLOBALS->kcur);
+ ctx->file_version = 0.0;
+ ctx->data_version = 0;
- if(GLOBALS->kcur == 0)
- {
- //struct iso4217format *choice = ui_cur_select_dialog_new(GLOBALS->mainwindow);
- struct iso4217format *curfmt = iso4217format_get(PREFS->curr_default);
+ /* v3.4 add :: prevent load of future file version */
+ v_buffer = g_strstr_len(buffer, 50, "<homebank v=");
+ if( v_buffer == NULL )
+ return FALSE;
- if(curfmt == NULL)
- curfmt = iso4217format_get_en_us();
-
-
- Currency *item = currency_add_from_user(curfmt);
+ DB( g_print("- id line: --(%.50s)\n\n", v_buffer) );
- GLOBALS->kcur = item->key;
+ ctx->file_version = g_ascii_strtod(v_buffer+13, NULL); /* a little hacky, but works ! */
+ if( ctx->file_version == 0.0 )
+ ctx->file_version = 0.1;
+ else if( ctx->file_version == 5.0 ) //was a mistake
+ ctx->file_version = 1.0;
+
+ v_buffer = g_strstr_len(buffer+13, 50, "d=");
+ if( v_buffer )
+ {
+ DB( g_print(" d=%s)\n\n", v_buffer) );
+
+ ctx->data_version = atoi(v_buffer+3);
+ }
+ return TRUE;
+}
- g_print("GLOBALS->kcur %d\n", GLOBALS->kcur);
- // set every accounts to base currecny
- GList *list = g_hash_table_get_values(GLOBALS->h_acc);
- while (list != NULL)
- {
- Account *acc;
- acc = list->data;
+/*
+** XML load homebank file: hbfile
+*/
+gint homebank_load_xml(gchar *filename)
+{
+gint retval;
+gchar *buffer;
+gsize length;
+GError *error = NULL;
+ParseContext ctx;
+GMarkupParseContext *context;
+gboolean rc;
- acc->kcur = item->key;
+ DB( g_print("\n[hb-xml] homebank_load_xml\n") );
- list = g_list_next(list);
- }
- g_list_free(list);
+ GValue filename_val = G_VALUE_INIT;
+ ext_hook("load_file", EXT_STRING(&filename_val, filename), NULL);
-
+ retval = XML_OK;
+ if (!g_file_get_contents (filename, &buffer, &length, &error))
+ {
+ //g_message ("%s", error->message);
+ retval = XML_IO_ERROR;
+ g_error_free (error);
}
-}
-*/
+ else
+ {
+ if( hb_xml_get_version(&ctx, buffer) == FALSE )
+ {
+ return XML_FILE_ERROR;
+ }
+ if( ctx.file_version > FILE_VERSION )
+ {
+ DB( g_print("- failed: version %f is not supported (max is %f)\n", ctx.file_version, FILE_VERSION) );
+ return XML_VERSION_ERROR;
+ }
+ else
+ {
+ DB( g_print("- file ok : v=%.1f data_v=%06d\n", ctx.file_version, ctx.data_version) );
-// lower v0.6 : we must assume categories/payee exists
-// and strong link to xfer
-// #632496
-static void homebank_upgrade_lower_v06(void)
-{
-Category *cat;
-Payee *pay;
-GList *lrul, *list;
+ /* 1st: validate the file is well in utf-8 */
+ DB( g_print("- ensure UTF-8\n") );
+ buffer = homebank_utf8_ensure(buffer);
- DB( g_print("\n[hb-xml] homebank_upgrade_lower_v06\n") );
+ /* then process the buffer */
+ #if MYDEBUG == 1
+ GTimer *t = g_timer_new();
+ g_print("- start parse\n");
+ #endif
- list = g_list_first(GLOBALS->ope_list);
- while (list != NULL)
- {
- Transaction *entry = list->data;
+ context = g_markup_parse_context_new (&hb_parser, 0, &ctx, NULL);
+
+ error = NULL;
+ rc = g_markup_parse_context_parse (context, buffer, length, &error);
- da_transaction_consistency(entry);
+ if( error )
+ g_print("failed: %s\n", error->message);
- //also strong link internal xfer
- if(entry->paymode == PAYMODE_INTXFER)
- {
- Transaction *child = transaction_old_get_child_transfer(entry);
- if(child != NULL)
+ if( rc == FALSE )
{
- transaction_xfer_change_to_child(entry, child);
+ error = NULL;
+ g_markup_parse_context_end_parse(context, &error);
+
+ if( error )
+ g_print("failed: %s\n", error->message);
}
- }
- list = g_list_next(list);
- }
+ g_markup_parse_context_free (context);
+ g_free (buffer);
+ DB( g_print("- end parse : %f sec\n", g_timer_elapsed(t, NULL)) );
+ DB( g_timer_destroy (t) );
- lrul = list = g_hash_table_get_values(GLOBALS->h_rul);
- while (list != NULL)
- {
- Assign *entry = list->data;
+ /* file upgrade / bugfix */
+ // group a test for very old version
+ if( ctx.file_version <= 1.0 )
+ {
+ if( ctx.file_version <= 0.1 )
+ homebank_upgrade_to_v02();
+ if( ctx.file_version <= 0.2 )
+ homebank_upgrade_to_v03();
+ if( ctx.file_version <= 0.3 )
+ homebank_upgrade_to_v04();
+ if( ctx.file_version <= 0.4 )
+ homebank_upgrade_to_v05();
+ if( ctx.file_version <= 0.5 )
+ {
+ homebank_upgrade_to_v06();
+ homebank_upgrade_lower_v06();
+ }
+ if( ctx.file_version <= 0.6 )
+ {
+ homebank_upgrade_to_v07();
+ hbfile_sanity_check();
+ }
+ if( ctx.file_version <= 0.7 ) // <= 4.5
+ {
+ homebank_upgrade_to_v08();
+ }
+ if( ctx.file_version <= 0.8 ) // <= 4.6
+ {
+ hbfile_sanity_check();
+ }
+ if( ctx.file_version <= 0.9 ) // <= 4.6.3
+ {
+ hbfile_sanity_check();
+ homebank_upgrade_to_v10();
+ }
+ if( ctx.file_version <= 1.0 ) // <= 5.0.0
+ {
+ hbfile_sanity_check();
+ homebank_upgrade_to_v11();
+ }
+ }
- cat = da_cat_get(entry->kcat);
- if(cat == NULL)
- {
- DB( g_print(" !! fixing cat for rul: %d is unknow\n", entry->kcat) );
- entry->kcat = 0;
- }
+ //starting 5.0.4 data upgrade is done without changing file_version
+ //file version is changed only when the structure change
+ //don't start number below with 0 to avoid octal interpretation
+ if( ctx.data_version <= 50005 ) // <= 5.0.5
+ {
+ hbfile_sanity_check();
+ }
+ if( ctx.file_version <= 1.1 ) // <= 5.1.0
+ {
+ hbfile_sanity_check();
+ homebank_upgrade_to_v12();
+ }
+ if( ctx.data_version <= 50106 ) // < 5.1.6
+ {
+ homebank_upgrade_to_v12_7();
+ }
- pay = da_pay_get(entry->kpay);
- if(pay == NULL)
- {
- DB( g_print(" !! fixing pay for rul: %d is unknow\n", entry->kpay) );
- entry->kpay = 0;
+ // next ?
+
}
-
-
- list = g_list_next(list);
}
- g_list_free(lrul);
-
+ return retval;
}
}
}
+static void
+append_escaped_text (GString *str,
+ const gchar *text,
+ gssize length)
+{
+ const gchar *p;
+ const gchar *end;
+ gunichar c;
+
+ p = text;
+ end = text + length;
+
+ while (p < end)
+ {
+ const gchar *next;
+ next = g_utf8_next_char (p);
+
+ switch (*p)
+ {
+ case '&':
+ g_string_append (str, "&");
+ break;
+
+ case '<':
+ g_string_append (str, "<");
+ break;
+
+ case '>':
+ g_string_append (str, ">");
+ break;
+
+ case '\'':
+ g_string_append (str, "'");
+ break;
+
+ case '"':
+ g_string_append (str, """);
+ break;
+
+ default:
+ c = g_utf8_get_char (p);
+ if ((0x1 <= c && c <= 0x8) ||
+ (0xa <= c && c <= 0xd) || //chnaged here from b<->c to a<->d
+ (0xe <= c && c <= 0x1f) ||
+ (0x7f <= c && c <= 0x84) ||
+ (0x86 <= c && c <= 0x9f))
+ g_string_append_printf (str, "&#x%x;", c);
+ else
+ g_string_append_len (str, p, next - p);
+ break;
+ }
+
+ p = next;
+ }
+}
+
+// we override g_markup_escape_text from glib to encode \n (LF) & \r (CR)
+static void hb_xml_append_txt_crlf(GString *gstring, gchar *attrname, gchar *value)
+{
+ if(value != NULL && *value != 0)
+ {
+ gssize length;
+ GString *escaped;
+
+ //gchar *escaped = g_markup_escape_text(value, -1);
+ length = strlen (value);
+ escaped = g_string_sized_new (length);
+ append_escaped_text (escaped, value, length);
+ g_string_append_printf(gstring, "%s=\"%s\" ", attrname, escaped->str);
+ g_string_free (escaped, TRUE);
+ }
+}
+
static void hb_xml_append_int0(GString *gstring, gchar *attrname, guint32 value)
{
g_string_append_printf(gstring, "%s=\"%d\" ", attrname, value);
}
+/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
+
+
/*
** XML properties save
*/
-static void homebank_save_xml_prop(GIOChannel *io)
+static gint homebank_save_xml_prop(GIOChannel *io)
{
gchar *title;
GString *node;
+gint retval = XML_OK;
+GError *error = NULL;
title = GLOBALS->owner == NULL ? "" : GLOBALS->owner;
g_string_assign(node, "<properties ");
hb_xml_append_txt(node, "title", title);
+ hb_xml_append_int(node, "curr", GLOBALS->kcur);
hb_xml_append_int(node, "car_category", GLOBALS->vehicle_category);
hb_xml_append_int0(node, "auto_smode", GLOBALS->auto_smode);
hb_xml_append_int(node, "auto_weekday", GLOBALS->auto_weekday);
g_string_append(node, "/>\n");
- g_io_channel_write_chars(io, node->str, -1, NULL, NULL);
+ error = NULL;
+ g_io_channel_write_chars(io, node->str, -1, NULL, &error);
+ if(error)
+ {
+ retval = XML_IO_ERROR;
+ g_error_free(error);
+ }
g_string_free(node, TRUE);
+ return retval;
}
/*
** XML currency save
*/
-/*
-static void homebank_save_xml_cur(GIOChannel *io)
+static gint homebank_save_xml_cur(GIOChannel *io)
{
GList *list;
gchar *tmpstr;
char buf1[G_ASCII_DTOSTR_BUF_SIZE];
+gint retval = XML_OK;
list = g_hash_table_get_values(GLOBALS->h_cur);
while (list != NULL)
{
Currency *item = list->data;
- if(item->key != 0)
- {
- tmpstr = g_markup_printf_escaped(
- "<cur key=\"%d\" iso=\"%s\" name=\"%s\" symb=\"%s\" syprf=\"%d\" dchar=\"%s\" gchar=\"%s\" frac=\"%d\" rate=\"%s\" mdate=\"%d\" />\n",
- item->key,
- item->iso_code,
- item->name,
- item->symbol,
- item->sym_prefix,
- item->decimal_char,
- item->grouping_char,
- item->frac_digits,
- g_ascii_dtostr (buf1, sizeof (buf1), item->rate),
- item->mdate
- );
-
- g_io_channel_write_chars(io, tmpstr, -1, NULL, NULL);
- g_free(tmpstr);
+ tmpstr = g_markup_printf_escaped(
+ "<cur key=\"%d\" flags=\"%d\" iso=\"%s\" name=\"%s\" symb=\"%s\" syprf=\"%d\" dchar=\"%s\" gchar=\"%s\" frac=\"%d\" rate=\"%s\" mdate=\"%d\"/>\n",
+ item->key,
+ item->flags,
+ item->iso_code,
+ item->name,
+ item->symbol,
+ item->sym_prefix,
+ item->decimal_char,
+ item->grouping_char,
+ item->frac_digits,
+ g_ascii_dtostr (buf1, sizeof (buf1), item->rate),
+ item->mdate
+ );
+
+ g_io_channel_write_chars(io, tmpstr, -1, NULL, NULL);
+ g_free(tmpstr);
- }
list = g_list_next(list);
}
g_list_free(list);
+ return retval;
}
-*/
/*
** XML account save
*/
-static void homebank_save_xml_acc(GIOChannel *io)
+static gint homebank_save_xml_acc(GIOChannel *io)
{
GList *lacc, *list;
GString *node;
+gint retval = XML_OK;
+GError *error = NULL;
node = g_string_sized_new(255);
{
Account *item = list->data;
- item->flags &= ~(AF_ADDED|AF_CHANGED); //remove flag
+ item->flags &= ~(AF_ADDED|AF_CHANGED); //delete flag
g_string_assign(node, "<account ");
hb_xml_append_int(node, "flags", item->flags);
hb_xml_append_int(node, "pos", item->pos);
hb_xml_append_int(node, "type", item->type);
- //hb_xml_append_int(node, "curr", item->kcur);
+ hb_xml_append_int(node, "curr", item->kcur);
hb_xml_append_txt(node, "name", item->name);
hb_xml_append_txt(node, "number", item->number);
hb_xml_append_txt(node, "bankname", item->bankname);
hb_xml_append_amt(node, "initial", item->initial);
+
hb_xml_append_amt(node, "minimum", item->minimum);
hb_xml_append_int(node, "cheque1", item->cheque1);
hb_xml_append_int(node, "cheque2", item->cheque2);
+ hb_xml_append_txt_crlf(node, "notes", item->notes);
g_string_append(node, "/>\n");
- g_io_channel_write_chars(io, node->str, -1, NULL, NULL);
+ error = NULL;
+ g_io_channel_write_chars(io, node->str, -1, NULL, &error);
+
+ if(error)
+ {
+ retval = XML_IO_ERROR;
+ g_error_free(error);
+ }
+
list = g_list_next(list);
}
g_list_free(lacc);
g_string_free(node, TRUE);
+ return retval;
}
/*
** XML payee save
*/
-static void homebank_save_xml_pay(GIOChannel *io)
+static gint homebank_save_xml_pay(GIOChannel *io)
{
GList *lpay, *list;
-gchar *tmpstr;
+GString *node;
+gint retval = XML_OK;
+GError *error = NULL;
+
+ node = g_string_sized_new(255);
lpay = list = payee_glist_sorted(0);
while (list != NULL)
if(item->key != 0)
{
- tmpstr = g_markup_printf_escaped("<pay key=\"%d\" name=\"%s\"/>\n",
- item->key,
- item->name
- );
+ g_string_assign(node, "<pay ");
- g_io_channel_write_chars(io, tmpstr, -1, NULL, NULL);
- g_free(tmpstr);
+ hb_xml_append_int(node, "key", item->key);
+ hb_xml_append_txt(node, "name", item->name);
+ hb_xml_append_int(node, "category", item->kcat);
+ hb_xml_append_int(node, "paymode" , item->paymode);
+
+ g_string_append(node, "/>\n");
+
+ error = NULL;
+ g_io_channel_write_chars(io, node->str, -1, NULL, &error);
+
+ if(error)
+ {
+ retval = XML_IO_ERROR;
+ g_error_free(error);
+ }
}
list = g_list_next(list);
}
g_list_free(lpay);
+ g_string_free(node, TRUE);
+ return retval;
}
/*
** XML category save
*/
-static void homebank_save_xml_cat(GIOChannel *io)
+static gint homebank_save_xml_cat(GIOChannel *io)
{
GList *lcat, *list;
GString *node;
char buf[G_ASCII_DTOSTR_BUF_SIZE];
guint i;
+gint retval = XML_OK;
+GError *error = NULL;
node = g_string_sized_new(255);
}
g_string_append(node, "/>\n");
- g_io_channel_write_chars(io, node->str, -1, NULL, NULL);
+
+ error = NULL;
+ g_io_channel_write_chars(io, node->str, -1, NULL, &error);
+
+ if(error)
+ {
+ retval = XML_IO_ERROR;
+ g_error_free(error);
+ }
}
list = g_list_next(list);
}
g_list_free(lcat);
g_string_free(node, TRUE);
+ return retval;
}
/*
** XML tag save
*/
-static void homebank_save_xml_tag(GIOChannel *io)
+static gint homebank_save_xml_tag(GIOChannel *io)
{
GList *ltag, *list;
gchar *tmpstr;
+gint retval = XML_OK;
+GError *error = NULL;
ltag = list = tag_glist_sorted(0);
while (list != NULL)
if(item->key != 0)
{
- tmpstr = g_markup_printf_escaped("<tag key=\"%d\" name=\"%s\" />\n",
+ tmpstr = g_markup_printf_escaped("<tag key=\"%d\" name=\"%s\"/>\n",
item->key,
item->name
);
- g_io_channel_write_chars(io, tmpstr, -1, NULL, NULL);
+ error = NULL;
+ g_io_channel_write_chars(io, tmpstr, -1, NULL, &error);
g_free(tmpstr);
-
+
+ if(error)
+ {
+ retval = XML_IO_ERROR;
+ g_error_free(error);
+ }
}
list = g_list_next(list);
}
g_list_free(ltag);
+ return retval;
}
/*
** XML assign save
*/
-static void homebank_save_xml_asg(GIOChannel *io)
+static gint homebank_save_xml_asg(GIOChannel *io)
{
GList *lasg, *list;
GString *node;
+gint retval = XML_OK;
+GError *error = NULL;
node = g_string_sized_new(255);
hb_xml_append_int(node, "key" , item->key);
hb_xml_append_int(node, "flags" , item->flags);
hb_xml_append_int(node, "field" , item->field);
- hb_xml_append_txt(node, "name" , item->name);
+ hb_xml_append_txt(node, "name" , item->text);
hb_xml_append_int(node, "payee" , item->kpay);
hb_xml_append_int(node, "category", item->kcat);
- //hb_xml_append_int(node, "paymode" , item->paymode);
+ hb_xml_append_int(node, "paymode" , item->paymode);
g_string_append(node, "/>\n");
- g_io_channel_write_chars(io, node->str, -1, NULL, NULL);
+ error = NULL;
+ g_io_channel_write_chars(io, node->str, -1, NULL, &error);
+
+ if(error)
+ {
+ retval = XML_IO_ERROR;
+ g_error_free(error);
+ }
list = g_list_next(list);
}
g_list_free(lasg);
g_string_free(node, TRUE);
+ return retval;
}
/*
** XML archive save
*/
-static void homebank_save_xml_arc(GIOChannel *io)
+static gint homebank_save_xml_arc(GIOChannel *io)
{
GList *list;
GString *node;
+gint retval = XML_OK;
+GError *error = NULL;
node = g_string_sized_new(255);
hb_xml_append_int(node, "account", item->kacc);
hb_xml_append_int(node, "dst_account", item->kxferacc);
hb_xml_append_int(node, "paymode", item->paymode);
+ hb_xml_append_int(node, "st", item->status);
hb_xml_append_int(node, "flags", item->flags);
hb_xml_append_int(node, "payee", item->kpay);
hb_xml_append_int(node, "category", item->kcat);
- hb_xml_append_txt(node, "wording", item->wording);
+ hb_xml_append_txt(node, "wording", item->memo);
hb_xml_append_int(node, "nextdate", item->nextdate);
hb_xml_append_int(node, "every", item->every);
hb_xml_append_int(node, "unit", item->unit);
hb_xml_append_int(node, "limit", item->limit);
hb_xml_append_int(node, "weekend", item->weekend);
+ hb_xml_append_int(node, "gap", item->daygap);
+
+ if(da_splits_count(item->splits) > 0)
+ {
+ gchar *cats, *amounts, *memos;
+
+ da_splits_tostring(item->splits, &cats, &amounts, &memos);
+ g_string_append_printf(node, "scat=\"%s\" ", cats);
+ g_string_append_printf(node, "samt=\"%s\" ", amounts);
+
+ //fix #1173910
+ gchar *escaped = g_markup_escape_text(memos, -1);
+ g_string_append_printf(node, "smem=\"%s\" ", escaped);
+ g_free(escaped);
+
+ g_free(cats);
+ g_free(amounts);
+ g_free(memos);
+ }
g_string_append(node, "/>\n");
- g_io_channel_write_chars(io, node->str, -1, NULL, NULL);
+ error = NULL;
+ g_io_channel_write_chars(io, node->str, -1, NULL, &error);
+ if(error)
+ {
+ retval = XML_IO_ERROR;
+ g_error_free(error);
+ }
+
list = g_list_next(list);
}
g_string_free(node, TRUE);
+ return retval;
}
/*
** XML transaction save
*/
-static void homebank_save_xml_ope(GIOChannel *io)
+static gint homebank_save_xml_ope(GIOChannel *io)
{
+GList *lst_acc, *lnk_acc;
GList *list;
GString *node;
gchar *tagstr;
+gint retval = XML_OK;
+GError *error = NULL;
node = g_string_sized_new(255);
- 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 *item = list->data;
+ Account *acc = lnk_acc->data;
- item->flags &= ~(OF_AUTO|OF_ADDED|OF_CHANGED); //remove flag
- tagstr = transaction_tags_tostring(item);
+ list = g_queue_peek_head_link(acc->txn_queue);
+ while (list != NULL)
+ {
+ Transaction *item = list->data;
- g_string_assign(node, "<ope ");
-
- hb_xml_append_int(node, "date", item->date);
- hb_xml_append_amt(node, "amount", item->amount);
- hb_xml_append_int(node, "account", item->kacc);
- hb_xml_append_int(node, "dst_account", item->kxferacc);
- hb_xml_append_int(node, "paymode", item->paymode);
- hb_xml_append_int(node, "flags", item->flags);
- hb_xml_append_int(node, "payee", item->kpay);
- hb_xml_append_int(node, "category", item->kcat);
- hb_xml_append_txt(node, "wording", item->wording);
- hb_xml_append_txt(node, "info", item->info);
- hb_xml_append_txt(node, "tags", tagstr);
- hb_xml_append_int(node, "kxfer", item->kxfer);
+ item->flags &= ~(OF_AUTO|OF_ADDED|OF_CHANGED); //delete flag
+ tagstr = transaction_tags_tostring(item);
- if(da_transaction_splits_count(item) > 0)
- {
- gchar *cats, *amounts, *memos;
+ g_string_assign(node, "<ope ");
- transaction_splits_tostring(item, &cats, &amounts, &memos);
- g_string_append_printf(node, "scat=\"%s\" ", cats);
- g_string_append_printf(node, "samt=\"%s\" ", amounts);
-
- //fix #1173910
- gchar *escaped = g_markup_escape_text(memos, -1);
- g_string_append_printf(node, "smem=\"%s\" ", escaped);
- g_free(escaped);
+ hb_xml_append_int(node, "date", item->date);
+ hb_xml_append_amt(node, "amount", item->amount);
+ hb_xml_append_int(node, "account", item->kacc);
+ hb_xml_append_int(node, "dst_account", item->kxferacc);
+ hb_xml_append_int(node, "paymode", item->paymode);
+ hb_xml_append_int(node, "st", item->status);
+ hb_xml_append_int(node, "flags", item->flags);
+ hb_xml_append_int(node, "payee", item->kpay);
+ hb_xml_append_int(node, "category", item->kcat);
+ hb_xml_append_txt(node, "wording", item->memo);
+ hb_xml_append_txt(node, "info", item->info);
+ hb_xml_append_txt(node, "tags", tagstr);
+ hb_xml_append_int(node, "kxfer", item->kxfer);
+
+ if(da_splits_count(item->splits) > 0)
+ {
+ gchar *cats, *amounts, *memos;
+
+ da_splits_tostring(item->splits, &cats, &amounts, &memos);
+ g_string_append_printf(node, "scat=\"%s\" ", cats);
+ g_string_append_printf(node, "samt=\"%s\" ", amounts);
+
+ //fix #1173910
+ gchar *escaped = g_markup_escape_text(memos, -1);
+ g_string_append_printf(node, "smem=\"%s\" ", escaped);
+ g_free(escaped);
+
+ g_free(cats);
+ g_free(amounts);
+ g_free(memos);
+ }
- g_free(cats);
- g_free(amounts);
- g_free(memos);
- }
+ g_string_append(node, "/>\n");
- g_string_append(node, "/>\n");
+ g_free(tagstr);
+
+ error = NULL;
+ g_io_channel_write_chars(io, node->str, -1, NULL, &error);
+
+ if(error)
+ {
+ retval = XML_IO_ERROR;
+ g_error_free(error);
+ }
- g_free(tagstr);
- g_io_channel_write_chars(io, node->str, -1, NULL, NULL);
- list = g_list_next(list);
+ list = g_list_next(list);
+ }
+
+ lnk_acc = g_list_next(lnk_acc);
}
+ g_list_free(lst_acc);
+
g_string_free(node, TRUE);
+ return retval;
}
/*
char buf1[G_ASCII_DTOSTR_BUF_SIZE];
gchar *outstr;
gint retval = XML_OK;
+GError *error = NULL;
+
+ GValue filename_val = G_VALUE_INIT;
+ ext_hook("save_file", EXT_STRING(&filename_val, filename), NULL);
- io = g_io_channel_new_file(filename, "w", NULL);
+ io = g_io_channel_new_file(filename, "w", &error);
if(io == NULL)
{
g_message("file error on: %s", filename);
retval = XML_IO_ERROR;
+
+ if(error)
+ g_print("failed: %s\n", error->message);
+
+ g_error_free(error);
}
else
{
g_io_channel_write_chars(io, "<?xml version=\"1.0\"?>\n", -1, NULL, NULL);
- outstr = g_strdup_printf("<homebank v=\"%s\">\n", g_ascii_dtostr (buf1, sizeof (buf1), FILE_VERSION));
+ outstr = g_strdup_printf("<homebank v=\"%s\" d=\"%06d\">\n", g_ascii_dtostr (buf1, sizeof (buf1), FILE_VERSION), HB_VERSION_NUM);
g_io_channel_write_chars(io, outstr, -1, NULL, NULL);
g_free(outstr);
- homebank_save_xml_prop(io);
- //homebank_save_xml_cur(io);
- homebank_save_xml_acc(io);
- homebank_save_xml_pay(io);
- homebank_save_xml_cat(io);
- homebank_save_xml_tag(io);
- homebank_save_xml_asg(io);
- homebank_save_xml_arc(io);
- homebank_save_xml_ope(io);
+ retval = homebank_save_xml_prop(io);
+ retval = homebank_save_xml_cur(io);
+ retval = homebank_save_xml_acc(io);
+ retval = homebank_save_xml_pay(io);
+ retval = homebank_save_xml_cat(io);
+ retval = homebank_save_xml_tag(io);
+ retval = homebank_save_xml_asg(io);
+ retval = homebank_save_xml_arc(io);
+ retval = homebank_save_xml_ope(io);
g_io_channel_write_chars(io, "</homebank>\n", -1, NULL, NULL);