GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dialog-customer-import.c
1 /*
2  * customer_import.c --
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, contact:
16  *
17  * Free Software Foundation Voice: +1-617-542-5942
18  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
19  * Boston, MA 02110-1301, USA [email protected]
20  */
21 
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31 
32 #include <glib/gi18n.h>
33 #include <regex.h>
34 #include <glib.h>
35 #include <glib/gstdio.h>
36 
37 #include "gnc-ui.h"
38 #include "gnc-ui-util.h"
39 #include "gnc-gui-query.h"
40 #include "gncAddress.h"
41 #include "gncCustomerP.h"
42 #include "gncVendorP.h"
43 // query
44 #include "Query.h"
45 #include "qof.h"
46 #include "gncIDSearch.h"
47 
48 #include "dialog-customer-import.h"
49 
50 // private prototypes
51 //static GncCustomer *gnc_customer_import_searchCustomer (const gchar *id, QofBook *book);
52 
53 
54 
55 // perl regular expressions are available
56 
57 // this helper macro takes a regexp match and fills the model
58 #define FILL_IN_HELPER(match_name,column) \
59  temp = g_match_info_fetch_named (match_info, match_name); \
60  if (temp) \
61  { \
62  g_strstrip( temp ); \
63  gtk_list_store_set (store, &iter, column, temp, -1); \
64  g_free (temp); \
65  }
66 customer_import_result
67 gnc_customer_import_read_file (const gchar *filename, const gchar *parser_regexp, GtkListStore *store, guint max_rows, customer_import_stats *stats)
68 {
69  // some statistics
70  customer_import_stats stats_fallback;
71  FILE *f;
72 
73  // regexp
74  char *line;
75  gchar *line_utf8, *temp;
76  GMatchInfo *match_info;
77  GError *err;
78  GRegex *regexpat;
79 
80  // model
81  GtkTreeIter iter;
82 
83  f = g_fopen( filename, "rt" );
84  if (!f)
85  {
86  //gnc_error_dialog( 0, _("File %s cannot be opened."), filename );
87  return CI_RESULT_OPEN_FAILED;
88  }
89 
90  // set up statistics
91  if (!stats)
92  stats = &stats_fallback;
93 
94  // compile the regular expression and check for errors
95  err = NULL;
96  regexpat = g_regex_new (parser_regexp, G_REGEX_EXTENDED | G_REGEX_OPTIMIZE | G_REGEX_DUPNAMES, 0, &err);
97  if (err != NULL)
98  {
99  GtkWidget *dialog;
100  gchar *errmsg;
101 
102  errmsg = g_strdup_printf (_("Error in regular expression '%s':\n%s"),
103  parser_regexp, err->message);
104  g_error_free (err);
105  err = NULL;
106 
107  dialog = gtk_message_dialog_new (NULL,
108  GTK_DIALOG_MODAL,
109  GTK_MESSAGE_ERROR,
110  GTK_BUTTONS_OK,
111  "%s", errmsg);
112  gtk_dialog_run (GTK_DIALOG (dialog));
113  gtk_widget_destroy(dialog);
114  g_free (errmsg);
115  errmsg = 0;
116 
117  fclose (f);
118  return CI_RESULT_ERROR_IN_REGEXP;
119  }
120 
121  // start the import
122  stats->n_imported = 0;
123  stats->n_ignored = 0;
124  stats->ignored_lines = g_string_new (NULL);
125 #define buffer_size 1000
126  line = g_malloc0 (buffer_size);
127  while (!feof (f) && ((max_rows == 0) || (stats->n_imported + stats->n_ignored < max_rows)))
128  {
129  int l;
130  // read one line
131  if (!fgets (line, buffer_size, f))
132  break; // eof
133  // now strip the '\n' from the end of the line
134  l = strlen (line);
135  if ((l > 0) && (line[l - 1] == '\n'))
136  line[l - 1] = 0;
137 
138  // convert line from locale into utf8
139  line_utf8 = g_locale_to_utf8 (line, -1, NULL, NULL, NULL);
140 
141  // parse the line
142  match_info = NULL; // it seems, that in contrast to documentation, match_info is not alsways set -> g_match_info_free will segfault
143  if (g_regex_match (regexpat, line_utf8, 0, &match_info))
144  {
145  // match found
146  stats->n_imported++;
147 
148  // fill in the values
149  gtk_list_store_append (store, &iter);
150  FILL_IN_HELPER ("id", CI_ID);
151  FILL_IN_HELPER ("company", CI_COMPANY);
152  FILL_IN_HELPER ("name", CI_NAME);
153  FILL_IN_HELPER ("addr1", CI_ADDR1);
154  FILL_IN_HELPER ("addr2", CI_ADDR2);
155  FILL_IN_HELPER ("addr3", CI_ADDR3);
156  FILL_IN_HELPER ("addr4", CI_ADDR4);
157  FILL_IN_HELPER ("phone", CI_PHONE);
158  FILL_IN_HELPER ("fax", CI_FAX);
159  FILL_IN_HELPER ("email", CI_EMAIL);
160  FILL_IN_HELPER ("notes", CI_NOTES);
161  FILL_IN_HELPER ("shipname", CI_SHIPNAME);
162  FILL_IN_HELPER ("shipaddr1", CI_SHIPADDR1);
163  FILL_IN_HELPER ("shipaddr2", CI_SHIPADDR2);
164  FILL_IN_HELPER ("shipaddr3", CI_SHIPADDR3);
165  FILL_IN_HELPER ("shipaddr4", CI_SHIPADDR4);
166  FILL_IN_HELPER ("shipphone", CI_SHIPPHONE);
167  FILL_IN_HELPER ("shipfax", CI_SHIPFAX);
168  FILL_IN_HELPER ("shipemail", CI_SHIPEMAIL);
169  }
170  else
171  {
172  // ignore line
173  stats->n_ignored++;
174  g_string_append (stats->ignored_lines, line_utf8);
175  g_string_append_c (stats->ignored_lines, '\n');
176  }
177 
178  g_match_info_free (match_info);
179  match_info = 0;
180  g_free (line_utf8);
181  line_utf8 = 0;
182  }
183  g_free (line);
184  line = 0;
185 
186  g_regex_unref (regexpat);
187  regexpat = 0;
188  fclose (f);
189 
190  //gnc_info_dialog (0, _("Import results:\n%i customers imported\n%i lines ignored"), n_imported, n_ignored);
191 
192  if (stats == &stats_fallback)
193  // stats are not requested -> free the string
194  g_string_free (stats->ignored_lines, TRUE);
195 
196  return CI_RESULT_OK;
197 }
198 
199 
200 
201 void
202 gnc_customer_import_fix_customers (GtkListStore *store, guint *fixed, guint *deleted, gchar * type)
203 {
204  GtkTreeIter iter;
205  gboolean valid;
206  gchar *company, *name, *addr1, *addr2, *addr3, *addr4, *phone, *fax, *email,
207  *notes, *shipname, *shipaddr1, *shipaddr2, *shipaddr3, *shipaddr4,
208  *shipphone, *shipfax, *shipemail;
209  guint dummy;
210 
211  // allow the call to this function with only GtkListeStore* specified
212  if (!fixed)
213  fixed = &dummy;
214  if (!deleted)
215  deleted = &dummy;
216 
217  *fixed = 0;
218  *deleted = 0;
219 
220  valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL(store), &iter);
221  while (valid)
222  {
223  // Walk through the list, reading each row
224  gtk_tree_model_get (GTK_TREE_MODEL(store), &iter,
225  CI_COMPANY, &company,
226  CI_NAME, &name,
227  CI_ADDR1, &addr1,
228  CI_ADDR2, &addr2,
229  CI_ADDR3, &addr3,
230  CI_ADDR4, &addr4,
231  CI_PHONE, &phone,
232  CI_FAX, &fax,
233  CI_EMAIL, &email,
234  CI_NOTES, &notes,
235  CI_SHIPNAME, &shipname,
236  CI_SHIPADDR1, &shipaddr1,
237  CI_SHIPADDR2, &shipaddr2,
238  CI_SHIPADDR3, &shipaddr3,
239  CI_SHIPADDR4, &shipaddr4,
240  CI_SHIPPHONE, &shipphone,
241  CI_SHIPFAX, &shipfax,
242  CI_SHIPEMAIL, &shipemail,
243  -1);
244 
245  if (strlen(company) == 0)
246  {
247  if (strlen(name) == 0)
248  {
249  // no fix possible -> delete row
250  gtk_list_store_remove (store, &iter);
251  (*deleted)++;
252  continue;
253  }
254  else
255  {
256  // fix possible -> copy name to company
257  gtk_list_store_set (store, &iter, CI_COMPANY, name, -1);
258  (*fixed)++;
259  }
260  }
261 
262  g_free (company);
263  g_free (name);
264  g_free (addr1);
265  g_free (addr2);
266  g_free (addr3);
267  g_free (addr4);
268  g_free (phone);
269  g_free (fax);
270  g_free (email);
271  g_free (notes);
272  g_free (shipname);
273  g_free (shipaddr1);
274  g_free (shipaddr2);
275  g_free (shipaddr3);
276  g_free (shipaddr4);
277  g_free (shipphone);
278  g_free (shipfax);
279  g_free (shipemail);
280 
281  valid = gtk_tree_model_iter_next (GTK_TREE_MODEL(store), &iter);
282  }
283 }
284 
285 void
286 gnc_customer_import_create_customers (GtkListStore *store, QofBook *book, guint *n_customers_created, guint *n_customers_updated, gchar * type)
287 {
288  gboolean valid;
289  GtkTreeIter iter;
290  gchar *id, *company, *name, *addr1, *addr2, *addr3, *addr4, *phone, *fax, *email;
291  gchar *notes, *shipname, *shipaddr1, *shipaddr2, *shipaddr3, *shipaddr4, *shipphone, *shipfax, *shipemail;
292  GncAddress *addr, *shipaddr;
293  guint dummy;
294  GncCustomer *customer;
295  GncVendor *vendor;
296  customer = NULL;
297  vendor = NULL;
298  addr = NULL;
299  shipaddr = NULL;
300  // these arguments are needed
301  g_return_if_fail (store && book);
302  printf("\nTYPE = %s\n", type);
303 
304  // allow to call this function without statistics
305  if (!n_customers_created)
306  n_customers_created = &dummy;
307  if (!n_customers_updated)
308  n_customers_updated = &dummy;
309  *n_customers_created = 0;
310  *n_customers_updated = 0;
311 
312  valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL(store), &iter);
313  while (valid)
314  {
315  // Walk through the list, reading each row
316  gtk_tree_model_get (GTK_TREE_MODEL(store), &iter,
317  CI_ID, &id,
318  CI_COMPANY, &company,
319  CI_NAME, &name,
320  CI_ADDR1, &addr1,
321  CI_ADDR2, &addr2,
322  CI_ADDR3, &addr3,
323  CI_ADDR4, &addr4,
324  CI_PHONE, &phone,
325  CI_FAX, &fax,
326  CI_EMAIL, &email,
327  CI_NOTES, &notes,
328  CI_SHIPNAME, &shipname,
329  CI_SHIPADDR1, &shipaddr1,
330  CI_SHIPADDR2, &shipaddr2,
331  CI_SHIPADDR3, &shipaddr3,
332  CI_SHIPADDR4, &shipaddr4,
333  CI_SHIPPHONE, &shipphone,
334  CI_SHIPFAX, &shipfax,
335  CI_SHIPEMAIL, &shipemail,
336  -1);
337 
338  // Set the customer id if one has not been chosen
339  if (strlen (id) == 0)
340  {
341  g_free (id);
342  if (g_ascii_strcasecmp (type, "CUSTOMER") == 0) id = gncCustomerNextID (book);
343  else if (g_ascii_strcasecmp (type, "VENDOR") == 0)id = gncVendorNextID (book);
344  //printf("ASSIGNED ID = %s\n",id);
345  }
346 
347  // Now save it off after checking if a vend/cust number doesn't already exist
348  {
349  if (g_ascii_strcasecmp (type, "CUSTOMER") == 0)
350  {
351  customer = gnc_search_customer_on_id (book, id);
352  if (!customer)
353  {
354  customer = gncCustomerCreate( book );
355  gncCustomerSetCurrency( customer, gnc_default_currency() );
356  (*n_customers_created)++;
357  }
358  else (*n_customers_updated)++;
359  }
360  else if (g_ascii_strcasecmp (type, "VENDOR") == 0)
361  {
362  vendor = gnc_search_vendor_on_id (book, id);
363  if ( !vendor)
364  {
365  vendor = gncVendorCreate( book );
366  gncVendorSetCurrency( vendor, gnc_default_currency() );
367  (*n_customers_created)++;
368  }
369  else (*n_customers_updated)++;
370  }
371 
372  if (g_ascii_strcasecmp (type, "CUSTOMER") == 0)
373  {
374  gncCustomerBeginEdit (customer);
375  gncCustomerSetID (customer, id);
376  gncCustomerSetName (customer, company);
377  gncCustomerSetNotes (customer, notes);
378  addr = gncCustomerGetAddr (customer);
379  shipaddr = gncCustomerGetShipAddr (customer);
380  }
381  else if (g_ascii_strcasecmp (type, "VENDOR") == 0)
382  {
383  gncVendorBeginEdit (vendor);
384  gncVendorSetID (vendor, id);
385  gncVendorSetName (vendor, company);
386  gncVendorSetNotes (vendor, notes);
387  addr = gncVendorGetAddr (vendor);
388  }
389  gncAddressSetName (addr, name);
390  gncAddressSetAddr1 (addr, addr1);
391  gncAddressSetAddr2 (addr, addr2);
392  gncAddressSetAddr3 (addr, addr3);
393  gncAddressSetAddr4 (addr, addr4);
394  gncAddressSetPhone (addr, phone);
395  gncAddressSetFax (addr, fax);
396  gncAddressSetEmail (addr, email);
397  if (g_ascii_strcasecmp (type, "CUSTOMER") == 0)
398  {
399  gncAddressSetName (shipaddr, shipname);
400  gncAddressSetAddr1 (shipaddr, shipaddr1);
401  gncAddressSetAddr2 (shipaddr, shipaddr2);
402  gncAddressSetAddr3 (shipaddr, shipaddr3);
403  gncAddressSetAddr4 (shipaddr, shipaddr4);
404  gncAddressSetPhone (shipaddr, shipphone);
405  gncAddressSetFax (shipaddr, shipfax);
406  gncAddressSetEmail (shipaddr, shipemail);
407  gncCustomerSetActive (customer, TRUE);
408  gncCustomerCommitEdit (customer);
409  }
410  else if (g_ascii_strcasecmp (type, "VENDOR") == 0)
411  {
412  gncVendorSetActive (vendor, TRUE);
413  gncVendorCommitEdit (vendor);
414  }
415  //printf("TYPE %s created with ID = %s.\n", type, id); // DEBUG
416  }
417 
418  g_free (company);
419  g_free (name);
420  g_free (addr1);
421  g_free (addr2);
422  g_free (addr3);
423  g_free (addr4);
424  g_free (phone);
425  g_free (fax);
426  g_free (email);
427  g_free (notes);
428  g_free (shipname);
429  g_free (shipaddr1);
430  g_free (shipaddr2);
431  g_free (shipaddr3);
432  g_free (shipaddr4);
433  g_free (shipphone);
434  g_free (shipfax);
435  g_free (shipemail);
436  valid = gtk_tree_model_iter_next (GTK_TREE_MODEL(store), &iter);
437  }
438 }
439 
core import functions for customer import plugin
utility functions for the GnuCash UI
gnc_commodity * gnc_default_currency(void)
Definition: gnc-ui-util.c:939
an Address object