GnuCash  5.6-150-g038405b370+
business-urls.c
1 /*
2  * business-urls.c -- Initialize HTML for business code
3  *
4  * Written By: Derek Atkins <warlord@MIT.EDU>
5  * Copyright (C) 2002 Derek Atkins
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of
10  * the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, contact:
19  *
20  * Free Software Foundation Voice: +1-617-542-5942
21  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
22  * Boston, MA 02110-1301, USA gnu@gnu.org
23  */
24 
25 #include <config.h>
26 
27 #include <gtk/gtk.h>
28 #include <glib/gi18n.h>
29 
30 #include "gnc-html.h"
31 #include "gnc-ui-util.h"
32 #include "qof.h"
33 #include "stdint.h"
34 
35 #include "gncCustomer.h"
36 #include "gncJob.h"
37 #include "gncVendor.h"
38 #include "gncEmployee.h"
39 #include "gncInvoice.h"
40 
41 #include "business-urls.h"
42 #include "dialog-customer.h"
43 #include "dialog-employee.h"
44 #include "dialog-vendor.h"
45 #include "dialog-invoice.h"
46 #include "dialog-job.h"
47 
48 #define HANDLE_TYPE(URL_TYPE_STR,OBJ_TYPE) { \
49  QofBook *book; \
50  GncGUID guid; \
51  QofCollection *coll; \
52  \
53  g_return_val_if_fail (location != NULL, FALSE); \
54  g_return_val_if_fail (result != NULL, FALSE); \
55  result->load_to_stream = FALSE; \
56  \
57  if (strncmp (URL_TYPE_STR, location, strlen(URL_TYPE_STR))) \
58  { \
59  result->error_message = \
60  g_strdup_printf (_("Badly formed URL %s"), location); \
61  return FALSE; \
62  } \
63  if (!string_to_guid (location + strlen(URL_TYPE_STR), &guid)) \
64  { \
65  result->error_message = g_strdup_printf (_("Bad URL: %s"), location); \
66  return FALSE; \
67  } \
68  \
69  book = gnc_get_current_book(); \
70  coll = qof_book_get_collection (book, OBJ_TYPE); \
71  entity = qof_collection_lookup_entity (coll, &guid); \
72  if (NULL == entity) \
73  { \
74  result->error_message = g_strdup_printf (_("No such entity: %s"), \
75  location); \
76  return FALSE; \
77  } \
78 }
79 
80 static gboolean
81 customerCB (const char *location, const char *label,
82  gboolean new_window, GNCURLResult * result)
83 {
84  QofInstance *entity;
85  GncCustomer *customer;
86 
87  /* href="...:customer=<guid>" */
88  HANDLE_TYPE ("customer=", GNC_ID_CUSTOMER);
89  customer = (GncCustomer *) entity;
90  gnc_ui_customer_edit (result->parent, customer);
91 
92  return TRUE;
93 }
94 
95 static gboolean
96 vendorCB (const char *location, const char *label,
97  gboolean new_window, GNCURLResult * result)
98 {
99  QofInstance *entity;
100  GncVendor *vendor;
101 
102  /* href="...:vendor=<guid>" */
103  HANDLE_TYPE ("vendor=", GNC_ID_VENDOR);
104  vendor = (GncVendor *) entity;
105  gnc_ui_vendor_edit (result->parent, vendor);
106 
107  return TRUE;
108 }
109 
110 static gboolean
111 employeeCB (const char *location, const char *label,
112  gboolean new_window, GNCURLResult * result)
113 {
114  QofInstance *entity;
115  GncEmployee *employee;
116 
117  /* href="...:employee=<guid>" */
118  HANDLE_TYPE ("employee=", GNC_ID_EMPLOYEE);
119 
120  employee = (GncEmployee *) entity;
121  gnc_ui_employee_edit (result->parent, employee);
122 
123  return TRUE;
124 }
125 
126 static gboolean
127 invoiceCB (const char *location, const char *label,
128  gboolean new_window, GNCURLResult * result)
129 {
130  QofInstance *entity;
131  GncInvoice *invoice;
132 
133  /* href="...:invoice=<guid>" */
134  HANDLE_TYPE ("invoice=", GNC_ID_INVOICE);
135  invoice = (GncInvoice *) entity;
136  gnc_ui_invoice_edit (result->parent, invoice);
137 
138  return TRUE;
139 }
140 
141 static gboolean
142 jobCB (const char *location, const char *label,
143  gboolean new_window, GNCURLResult * result)
144 {
145  QofInstance *entity;
146  GncJob *job;
147 
148  /* href="...:job=<guid>" */
149  HANDLE_TYPE ("job=", GNC_ID_JOB);
150  job = (GncJob *) entity;
151  gnc_ui_job_edit (result->parent, job);
152 
153  return TRUE;
154 }
155 
156 /* ================================================================= */
157 
158 #define DISABLE_REPORT_IF_NULL(inst) \
159  if (NULL == inst) \
160  { \
161  result->error_message = \
162  g_strdup_printf (_("No such owner entity: %s"), location); \
163  show_report = FALSE; \
164  }
165 
166 #define DISABLE_REPORT_IF_TRUE(inst) \
167  if (inst) \
168  { \
169  result->error_message = \
170  g_strdup_printf (_("Badly formed URL %s"), location); \
171  show_report = FALSE; \
172  }
173 
174 /* parses a string "user=john&pass=smith&age=41" into a string-keyed
175  GHashTable. String must not contain non-ASCII chars. Duplicate keys
176  will be ignored. */
177 static GHashTable *parse_parameters (const gchar *parms)
178 {
179  GHashTable *rethash;
180  char *query = strdup (parms);
181  const char *key_tok = "&\n";
182  const char val_tok = '=';
183 
184  rethash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
185 
186  for (char *p = strtok (query, key_tok); p; p = strtok (NULL, key_tok))
187  {
188  gchar * val = strchr (p, val_tok);
189  *(val++) = '\0';
190  if (val && !g_hash_table_contains (rethash, p))
191  g_hash_table_insert (rethash, g_strdup (p), g_strdup (val));
192  }
193 
194  g_free (query);
195  return rethash;
196 }
197 
198 static gboolean
199 ownerreportCB (const char *location, const char *label,
200  gboolean new_window, GNCURLResult * result)
201 {
202  gchar *ownerptr, *acctptr, *etype, *datestr = NULL;
203  GncGUID guid;
204  GncOwner owner;
205  Account *acc;
206  GHashTable *query_ht;
207  time64 enddate = INT64_MAX;
208  gboolean show_report = TRUE;
209 
210  g_return_val_if_fail (location != NULL, FALSE);
211  g_return_val_if_fail (result != NULL, FALSE);
212 
213  result->load_to_stream = FALSE;
214 
215  /* href="...:owner=<owner-type>:<guid>[&acct=<guid>]" */
216  query_ht = parse_parameters (location);
217 
218  /* parse the acct guid*/
219  acctptr = g_hash_table_lookup (query_ht, "acct");
220  DISABLE_REPORT_IF_TRUE (!acctptr || !string_to_guid (acctptr, &guid));
221  acc = xaccAccountLookup (&guid, gnc_get_current_book ());
222 
223  /* parse the acct guid*/
224  datestr = g_hash_table_lookup (query_ht, "enddate");
225  if (datestr)
226  enddate = g_ascii_strtoull (datestr, NULL, 10);
227 
228  /* parse the owner guid */
229  ownerptr = g_hash_table_lookup (query_ht, "owner");
230  DISABLE_REPORT_IF_TRUE (!ownerptr || !strchr("cvej", ownerptr[0]) ||
231  ownerptr[1] != ':' ||
232  !string_to_guid (ownerptr+2, &guid));
233  memset (&owner, 0, sizeof (owner));
234  switch (*ownerptr)
235  {
236  case 'c':
237  {
238  GncCustomer *customer =
239  gncCustomerLookup (gnc_get_current_book (), &guid);
240  DISABLE_REPORT_IF_NULL (customer);
241  gncOwnerInitCustomer (&owner, customer);
242  etype = "Customer";
243  break;
244  }
245  case 'v':
246  {
247  GncVendor *vendor =
248  gncVendorLookup (gnc_get_current_book (), &guid);
249  DISABLE_REPORT_IF_NULL (vendor);
250  gncOwnerInitVendor (&owner, vendor);
251  etype = "Vendor";
252  break;
253  }
254  case 'e':
255  {
256  GncEmployee *employee =
257  gncEmployeeLookup (gnc_get_current_book (), &guid);
258  DISABLE_REPORT_IF_NULL(employee);
259  gncOwnerInitEmployee (&owner, employee);
260  etype = "Employee";
261  break;
262  }
263  case 'j':
264  {
265  GncJob *job =
266  gncJobLookup (gnc_get_current_book (), &guid);
267  DISABLE_REPORT_IF_NULL(job);
268  gncOwnerInitJob (&owner, job);
269  etype = "Job";
270  break;
271  }
272  default:
273  etype = "Undefined";
274  break;
275  }
276 
277  if (owner.owner.undefined == NULL)
278  {
279  result->error_message =
280  g_strdup_printf (_("Entity type does not match %s: %s"),
281  etype, location);
282  show_report = FALSE;
283  }
284 
285  /* Ok, let's run this report */
286  if (show_report)
287  {
288  if (enddate != INT64_MAX)
289  gnc_business_call_owner_report_with_enddate (result->parent, &owner,
290  acc, enddate);
291  else
292  gnc_business_call_owner_report (result->parent, &owner, acc);
293  }
294 
295  g_hash_table_destroy (query_ht);
296  return show_report;
297 }
298 
299 void
300 gnc_business_urls_initialize (void)
301 {
302  int i;
303  static struct
304  {
305  URLType urltype;
306  char * protocol;
307  GncHTMLUrlCB handler;
308  } types[] =
309  {
310  { GNC_ID_CUSTOMER, GNC_ID_CUSTOMER, customerCB },
311  { GNC_ID_VENDOR, GNC_ID_VENDOR, vendorCB },
312  { GNC_ID_EMPLOYEE, GNC_ID_EMPLOYEE, employeeCB },
313  { GNC_ID_JOB, GNC_ID_JOB, jobCB },
314  { GNC_ID_INVOICE, GNC_ID_INVOICE, invoiceCB },
315  { URL_TYPE_OWNERREPORT, "gnc-ownerreport", ownerreportCB },
316  { NULL, NULL }
317  };
318 
319  for (i = 0; types[i].urltype; i++)
320  gnc_html_register_urltype (types[i].urltype, types[i].protocol);
321 
322  for (i = 0; types[i].urltype; i++)
323  if (types[i].handler)
324  gnc_html_register_url_handler (types[i].urltype, types[i].handler);
325 
326 }
327 
328 /* =========================== END OF FILE ========================= */
Core Customer Interface.
utility functions for the GnuCash UI
STRUCTS.
gboolean string_to_guid(const gchar *string, GncGUID *guid)
Given a string, replace the given guid with the parsed one unless the given value is null...
credit, discount and shipaddr are unique to GncCustomer id, name, notes, terms, addr, currency, taxtable, taxtable_override taxincluded, active and jobs are identical to ::GncVendor.
Business Invoice Interface.
Job Interface.
Employee Interface.
Vendor Interface.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
Definition: gnc-date.h:87
The type used to store guids in C.
Definition: guid.h:75
Account * xaccAccountLookup(const GncGUID *guid, QofBook *book)
The xaccAccountLookup() subroutine will return the account associated with the given id...
Definition: Account.cpp:2052