gnucash maint: Bug 756469 - CSV Invoice Import - Items with double quote escape not imported.
Mike Evans
mikee at code.gnucash.org
Thu Jan 14 08:48:11 EST 2016
Updated via https://github.com/Gnucash/gnucash/commit/9b21c9e6 (commit)
from https://github.com/Gnucash/gnucash/commit/44814868 (commit)
commit 9b21c9e682e8ade37778f7b67a09bfd0da87355f
Author: Mike Evans <mikee at saxicola.co.uk>
Date: Thu Jan 14 13:38:11 2016 +0000
Bug 756469 - CSV Invoice Import - Items with double quote escape not imported.
Update regex to accept escaped quotes in (some) quoted fields. Thanks Derek.
Convert escaped quotes "" to unescaped " in notes and description fields.
diff --git a/src/plugins/bi_import/dialog-bi-import-gui.c b/src/plugins/bi_import/dialog-bi-import-gui.c
index fa14669..679627f 100644
--- a/src/plugins/bi_import/dialog-bi-import-gui.c
+++ b/src/plugins/bi_import/dialog-bi-import-gui.c
@@ -284,7 +284,7 @@ void gnc_bi_import_gui_filenameChanged_cb (GtkWidget *widget, gpointer data)
// generate preview
gtk_list_store_clear (gui->store);
- gnc_bi_import_read_file (filename, gui->regexp->str, gui->store, 10, NULL);
+ gnc_bi_import_read_file (filename, gui->regexp->str, gui->store, 100, NULL);
g_free( filename );
}
@@ -315,7 +315,7 @@ void gnc_bi_import_gui_option3_cb (GtkWidget *widget, gpointer data)
BillImportGui *gui = data;
if (!gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget) ))
return;
- g_string_assign (gui->regexp, "^((?<id>[^\";]*)|\"(?<id>[^\"]*)\");((?<date_opened>[^\";]*)|\"(?<date_opened>[^\"]*)\");((?<owner_id>[^\";]*)|\"(?<owner_id>[^\"]*)\");((?<billing_id>[^\";]*)|\"(?<billing_id>[^\"]*)\");((?<notes>[^\";]*)|\"(?<notes>[^\"]*)\");((?<date>[^\";]*)|\"(?<date>[^\"]*)\");((?<desc>[^\";]*)|\"(?<desc>[^\"]*)\");((?<action>[^\";]*)|\"(?<action>[^\"]*)\");((?<account>[^\";]*)|\"(?<account>[^\"]*)\");((?<quantity>[^\";]*)|\"(?<quantity>[^\"]*)\");((?<price>[^\";]*)|\"(?<price>[^\"]*)\");((?<disc_type>[^\";]*)|\"(?<disc_type>[^\"]*)\");((?<disc_how>[^\";]*)|\"(?<disc_how>[^\"]*)\");((?<discount>[^\";]*)|\"(?<discount>[^\"]*)\");((?<taxable>[^\";]*)|\"(?<taxable>[^\"]*)\");((?<taxincluded>[^\";]*)|\"(?<taxincluded>[^\"]*)\");((?<tax_table>[^\";]*)|\"(?<tax_table>[^\"]*)\");((?<date_posted>[^\";]*)|\"(?<date_posted>[^\"]*)\");((?<due_date>[^\";]*)|\"(?<due_date>[^\"]*)\");((?<account_posted>[^\";]*)|\"(?<account_posted>[^\"]*)\");((?<memo_posted>[^\";]*)|\"(?<memo_posted>[^\"]*)\");((?<accu_splits>[^\";]*)|\"(?<accu_splits>[^\"]*)\")$");
+ g_string_assign (gui->regexp, "^((?<id>[^\";]*)|\"(?<id>[^\"]*)\");((?<date_opened>[^\";]*)|\"(?<date_opened>[^\"]*)\");((?<owner_id>[^\";]*)|\"(?<owner_id>[^\"]*)\");((?<billing_id>[^\";]*)|\"(?<billing_id>[^\"]*)\");((?<notes>[^\";]*)|\"(?<notes>([^\"]|\"\")*)\");((?<date>[^\";]*)|\"(?<date>[^\"]*)\");((?<desc>[^\";]*)|\"(?<desc>([^\"]|\"\")*)\");((?<action>[^\";]*)|\"(?<action>[^\"]*)\");((?<account>[^\";]*)|\"(?<account>[^\"]*)\");((?<quantity>[^\";]*)|\"(?<quantity>[^\"]*)\");((?<price>[^\";]*)|\"(?<price>[^\"]*)\");((?<disc_type>[^\";]*)|\"(?<disc_type>[^\"]*)\");((?<disc_how>[^\";]*)|\"(?<disc_how>[^\"]*)\");((?<discount>[^\";]*)|\"(?<discount>[^\"]*)\");((?<taxable>[^\";]*)|\"(?<taxable>[^\"]*)\");((?<taxincluded>[^\";]*)|\"(?<taxincluded>[^\"]*)\");((?<tax_table>[^\";]*)|\"(?<tax_table>[^\"]*)\");((?<date_posted>[^\";]*)|\"(?<date_posted>[^\"]*)\");((?<due_date>[^\";]*)|\"(?<due_date>[^\"]*)\");((?<account_posted>[^\";]*)|\"(?<account_posted>[^\"]*)\");((?<memo_posted>[^\";]*)|\"(?<memo_posted>[^\"]*)\");((?<accu_splits>[^\";]*)|\"(?<accu_splits>[^\"]*)\")$");
gnc_bi_import_gui_filenameChanged_cb (gui->entryFilename, gui);
}
@@ -325,7 +325,7 @@ void gnc_bi_import_gui_option4_cb (GtkWidget *widget, gpointer data)
BillImportGui *gui = data;
if (!gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(widget) ))
return;
- g_string_assign (gui->regexp, "^((?<id>[^\",]*)|\"(?<id>[^\"]*)\"),((?<date_opened>[^\",]*)|\"(?<date_opened>[^\"]*)\"),((?<owner_id>[^\",]*)|\"(?<owner_id>[^\"]*)\"),((?<billing_id>[^\",]*)|\"(?<billing_id>[^\"]*)\"),((?<notes>[^\",]*)|\"(?<notes>[^\"]*)\"),((?<date>[^\",]*)|\"(?<date>[^\"]*)\"),((?<desc>[^\",]*)|\"(?<desc>[^\"]*)\"),((?<action>[^\",]*)|\"(?<action>[^\"]*)\"),((?<account>[^\",]*)|\"(?<account>[^\"]*)\"),((?<quantity>[^\",]*)|\"(?<quantity>[^\"]*)\"),((?<price>[^\",]*)|\"(?<price>[^\"]*)\"),((?<disc_type>[^\",]*)|\"(?<disc_type>[^\"]*)\"),((?<disc_how>[^\",]*)|\"(?<disc_how>[^\"]*)\"),((?<discount>[^\",]*)|\"(?<discount>[^\"]*)\"),((?<taxable>[^\",]*)|\"(?<taxable>[^\"]*)\"),((?<taxincluded>[^\",]*)|\"(?<taxincluded>[^\"]*)\"),((?<tax_table>[^\",]*)|\"(?<tax_table>[^\"]*)\"),((?<date_posted>[^\",]*)|\"(?<date_posted>[^\"]*)\"),((?<due_date>[^\",]*)|\"(?<due_date>[^\"]*)\"),((?<account_posted>[^\",]*)|\"(?<account_posted>[^\"]*)\"),((?<memo_posted>[^\",]*)|\"(?<memo_posted>[^\"]*)\"),((?<accu_splits>[^\",]*)|\"(?<accu_splits>[^\"]*)\")$");
+ g_string_assign (gui->regexp, "^((?<id>[^\",]*)|\"(?<id>[^\"]*)\"),((?<date_opened>[^\",]*)|\"(?<date_opened>[^\"]*)\"),((?<owner_id>[^\",]*)|\"(?<owner_id>[^\"]*)\"),((?<billing_id>[^\",]*)|\"(?<billing_id>[^\"]*)\"),((?<notes>[^\",]*)|\"(?<notes>([^\"]|\"\")*)\"),((?<date>[^\",]*)|\"(?<date>[^\"]*)\"),((?<desc>[^\",]*)|\"(?<desc>([^\"]|\"\")*)\"),((?<action>[^\",]*)|\"(?<action>[^\"]*)\"),((?<account>[^\",]*)|\"(?<account>[^\"]*)\"),((?<quantity>[^\",]*)|\"(?<quantity>[^\"]*)\"),((?<price>[^\",]*)|\"(?<price>[^\"]*)\"),((?<disc_type>[^\",]*)|\"(?<disc_type>[^\"]*)\"),((?<disc_how>[^\",]*)|\"(?<disc_how>[^\"]*)\"),((?<discount>[^\",]*)|\"(?<discount>[^\"]*)\"),((?<taxable>[^\",]*)|\"(?<taxable>[^\"]*)\"),((?<taxincluded>[^\",]*)|\"(?<taxincluded>[^\"]*)\"),((?<tax_table>[^\",]*)|\"(?<tax_table>[^\"]*)\"),((?<date_posted>[^\",]*)|\"(?<date_posted>[^\"]*)\"),((?<due_date>[^\",]*)|\"(?<due_date>[^\"]*)\"),((?<account_posted>[^\",]*)|\"(?<account_posted>[^\"]*)\"),((?<memo_posted>[^\",]*)|\"(?<memo_posted>[^\"]*)\"),((?<accu_splits>[^\",]*)|\"(?<accu_splits>[^\"]*)\")$");
gnc_bi_import_gui_filenameChanged_cb (gui->entryFilename, gui);
}
diff --git a/src/plugins/bi_import/dialog-bi-import.c b/src/plugins/bi_import/dialog-bi-import.c
index a67d255..f9eb832 100644
--- a/src/plugins/bi_import/dialog-bi-import.c
+++ b/src/plugins/bi_import/dialog-bi-import.c
@@ -79,7 +79,7 @@
}
static QofLogModule log_module = G_LOG_DOMAIN; //G_LOG_BUSINESS;
-
+static char * un_escape(char *str);
bi_import_result
gnc_bi_import_read_file (const gchar * filename, const gchar * parser_regexp,
GtkListStore * store, guint max_rows,
@@ -240,9 +240,9 @@ gnc_bi_import_fix_bis (GtkListStore * store, guint * fixed, guint * deleted,
guint dummy;
gint row = 1;
const gchar* date_format_string = qof_date_format_get_string (qof_date_format_get()); // Get the user set date format string
-
-
- //date_format_string = qof_date_format_get_string (qof_date_format_get());
+
+
+ //date_format_string = qof_date_format_get_string (qof_date_format_get());
DEBUG("date_format_string: %s",date_format_string);
// allow the call to this function with only GtkListeStore* specified
@@ -298,7 +298,7 @@ gnc_bi_import_fix_bis (GtkListStore * store, guint * fixed, guint * deleted,
row, id);
}
else
- { // TODO: If id is empty get the next one in the series. Bug 731105
+ { // TODO: If id is empty get the next one in the series. Bug 731105
if (strlen (id) == 0)
{
// no invoice id specified
@@ -386,9 +386,9 @@ gnc_bi_import_fix_bis (GtkListStore * store, guint * fixed, guint * deleted,
gtk_list_store_set (store, &iter, DUE_DATE,
date_posted, -1);
row_fixed = TRUE;
-
+
}
-
+
// due_date is valid
*/
if (strlen (quantity) == 0)
@@ -397,7 +397,7 @@ gnc_bi_import_fix_bis (GtkListStore * store, guint * fixed, guint * deleted,
gtk_list_store_set (store, &iter, QUANTITY, "1", -1);
row_fixed = TRUE;
}
-
+
// quantity is valid
@@ -533,7 +533,7 @@ gnc_bi_import_create_bis (GtkListStore * store, QofBook * book,
gchar *new_id = NULL;
gint64 denom = 0;
gnc_commodity *currency;
-
+
// these arguments are needed
g_return_if_fail (store && book);
// logic of this function only works for bills or invoices
@@ -626,6 +626,7 @@ gnc_bi_import_create_bis (GtkListStore * store, QofBook * book,
gncInvoiceSetDateOpened (invoice, now_timespec);
}
gncInvoiceSetBillingID (invoice, billing_id ? billing_id : "");
+ notes = un_escape(notes);
gncInvoiceSetNotes (invoice, notes ? notes : "");
gncInvoiceSetActive (invoice, TRUE);
//if (g_ascii_strcasecmp(type,"INVOICE"))gncInvoiceSetBillTo( invoice, billto );
@@ -710,6 +711,9 @@ gnc_bi_import_create_bis (GtkListStore * store, QofBook * book,
}
timespecFromTime64 (&today, gnc_time (NULL)); // set today to the current date
gncEntrySetDateEntered (entry, today);
+ // Remove escaped quotes
+ desc = un_escape(desc);
+ notes = un_escape(notes);
gncEntrySetDescription (entry, desc);
gncEntrySetAction (entry, action);
value = gnc_numeric_zero();
@@ -717,7 +721,7 @@ gnc_bi_import_create_bis (GtkListStore * store, QofBook * book,
gncEntrySetQuantity (entry, value);
acc = gnc_account_lookup_for_register (gnc_get_current_root_account (),
account);
-
+
if (g_ascii_strcasecmp (type, "BILL") == 0)
{
gncEntrySetBillAccount (entry, acc);
@@ -751,8 +755,8 @@ gnc_bi_import_create_bis (GtkListStore * store, QofBook * book,
valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
// handle auto posting of invoices
-
-
+
+
if (valid)
gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, ID, &new_id, -1);
if (g_strcmp0 (id, new_id) != 0)
@@ -782,8 +786,8 @@ gnc_bi_import_create_bis (GtkListStore * store, QofBook * book,
}
}
-
-
+
+
}
// cleanup
g_free (new_id);
@@ -809,5 +813,36 @@ gnc_bi_import_create_bis (GtkListStore * store, QofBook * book,
g_free (account_posted);
g_free (memo_posted);
g_free (accumulatesplits);
-
+
+}
+
+/* Change any escaped quotes ("") to (")
+ * @param char* String to be modified
+ * @return char* Modified string.
+*/
+static char * un_escape(char *str)
+{
+ gchar quote = '"';
+ gchar *newStr = NULL;
+ int n = 0;
+ newStr = g_malloc(strlen(str)+1); // This must be freed in the calling code.
+ while(*str != '\0')
+ {
+ if(*str == quote)
+ {
+ str++;
+ if(*str == quote)
+ {
+ newStr[n] = quote;
+ }
+ }
+ else
+ {
+ newStr[n] = *str;
+ }
+ str++;
+ n++;
+ }
+ newStr[n] = '\0'; //ending the character array
+ return newStr;
}
Summary of changes:
src/plugins/bi_import/dialog-bi-import-gui.c | 6 +--
src/plugins/bi_import/dialog-bi-import.c | 65 +++++++++++++++++++++-------
2 files changed, 53 insertions(+), 18 deletions(-)
More information about the gnucash-changes
mailing list