GnuCash  4.8a-132-gcdaeb421d+
gncVendor.c
1 /********************************************************************\
2  * gncVendor.c -- the Core Vendor Interface *
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 gnu@gnu.org *
20  * *
21 \********************************************************************/
22 
23 /*
24  * Copyright (C) 2001, 2002 Derek Atkins
25  * Copyright (C) 2003 <linas@linas.org>
26  * Author: Derek Atkins <warlord@MIT.EDU>
27  */
28 
29 #include <config.h>
30 
31 #include <glib.h>
32 #include <string.h>
33 #include <qofinstance-p.h>
34 
35 #include "gnc-commodity.h"
36 #include "gncAddressP.h"
37 #include "gncBillTermP.h"
38 #include "gncInvoice.h"
39 #include "gncJobP.h"
40 #include "gncTaxTableP.h"
41 #include "gncVendor.h"
42 #include "gncVendorP.h"
43 
44 static gint vend_qof_event_handler_id = 0;
45 static void vend_handle_qof_events (QofInstance *entity, QofEventId event_type,
46  gpointer user_data, gpointer event_data);
47 static void qofVendorSetAddr (GncVendor *vendor, QofInstance *addr_ent);
48 static const char* qofVendorGetTaxIncluded(const GncVendor *vendor);
49 static void qofVendorSetTaxIncluded(GncVendor *vendor, const char* type_string);
50 
51 struct _gncVendor
52 {
53  QofInstance inst;
54 
55  const char * id;
56  const char * name;
57  const char * notes;
58  GncBillTerm * terms;
59  GncAddress * addr;
60  gnc_commodity * currency;
61  GncTaxTable* taxtable;
62  gboolean taxtable_override;
63  GncTaxIncluded taxincluded;
64  gboolean active;
65  GList * jobs;
66  gnc_numeric * balance; /* cached vendor balance, will not be stored */
67 };
68 
70 {
71  QofInstanceClass parent_class;
72 };
73 
74 static QofLogModule log_module = GNC_MOD_BUSINESS;
75 
76 #define _GNC_MOD_NAME GNC_ID_VENDOR
77 
78 /* ============================================================ */
79 /* Misc inline funcs */
80 
81 static inline void mark_vendor (GncVendor *vendor);
82 void mark_vendor (GncVendor *vendor)
83 {
84  qof_instance_set_dirty(&vendor->inst);
85  qof_event_gen (&vendor->inst, QOF_EVENT_MODIFY, NULL);
86 }
87 
88 /* ============================================================== */
89 
90 enum
91 {
92  PROP_0,
93  PROP_NAME, /* Table */
94  PROP_ID, /* Table */
95  PROP_NOTES, /* Table */
96  PROP_CURRENCY, /* Table */
97  PROP_ACTIVE, /* Table */
98  PROP_TAXTABLE_OVERRIDE, /* Table */
99  PROP_BILLTERMS, /* Table */
100  PROP_TAXTABLE, /* Table */
101  PROP_ADDRESS, /* Table, 8 fields */
102  PROP_TAX_INCLUDED, /* Table */
103  PROP_TAX_INCLUDED_STR, /* Alternate setter for PROP_TAX_INCLUDED */
104  PROP_PDF_DIRNAME, /* KVP */
105  PROP_LAST_POSTED, /* KVP */
106  PROP_PAYMENT_LAST_ACCT, /* KVP */
107 };
108 
109 /* GObject Initialization */
110 G_DEFINE_TYPE(GncVendor, gnc_vendor, QOF_TYPE_INSTANCE);
111 
112 static void
113 gnc_vendor_init(GncVendor* vendor)
114 {
115 }
116 
117 static void
118 gnc_vendor_dispose(GObject *vendorp)
119 {
120  G_OBJECT_CLASS(gnc_vendor_parent_class)->dispose(vendorp);
121 }
122 
123 static void
124 gnc_vendor_finalize(GObject* vendorp)
125 {
126  G_OBJECT_CLASS(gnc_vendor_parent_class)->finalize(vendorp);
127 }
128 
129 /* Note that g_value_set_object() refs the object, as does
130  * g_object_get(). But g_object_get() only unrefs once when it disgorges
131  * the object, leaving an unbalanced ref, which leaks. So instead of
132  * using g_value_set_object(), use g_value_take_object() which doesn't
133  * ref the object when used in get_property().
134  */
135 static void
136 gnc_vendor_get_property (GObject *object,
137  guint prop_id,
138  GValue *value,
139  GParamSpec *pspec)
140 {
141  GncVendor *vendor;
142  gchar *key;
143 
144  g_return_if_fail(GNC_IS_VENDOR(object));
145 
146  vendor = GNC_VENDOR(object);
147  switch (prop_id)
148  {
149  case PROP_NAME:
150  g_value_set_string(value, vendor->name);
151  break;
152  case PROP_ID:
153  g_value_set_string(value, vendor->id);
154  break;
155  case PROP_NOTES:
156  g_value_set_string(value, vendor->notes);
157  break;
158  case PROP_CURRENCY:
159  g_value_take_object(value, vendor->currency);
160  break;
161  case PROP_ACTIVE:
162  g_value_set_boolean(value, vendor->active);
163  break;
164  case PROP_TAXTABLE_OVERRIDE:
165  g_value_set_boolean(value, vendor->taxtable_override);
166  break;
167  case PROP_BILLTERMS:
168  g_value_take_object(value, vendor->terms);
169  break;
170  case PROP_TAXTABLE:
171  g_value_take_object(value, vendor->taxtable);
172  break;
173  case PROP_ADDRESS:
174  g_value_take_object(value, vendor->addr);
175  break;
176  case PROP_TAX_INCLUDED:
177  g_value_set_int(value, vendor->taxincluded);
178  break;
179  case PROP_TAX_INCLUDED_STR:
180  g_value_set_string(value, qofVendorGetTaxIncluded(vendor));
181  break;
182  case PROP_PDF_DIRNAME:
183  qof_instance_get_kvp (QOF_INSTANCE (vendor), value, 1, OWNER_EXPORT_PDF_DIRNAME);
184  break;
185  case PROP_LAST_POSTED:
186  qof_instance_get_kvp (QOF_INSTANCE (vendor), value, 1, LAST_POSTED_TO_ACCT);
187  break;
188  case PROP_PAYMENT_LAST_ACCT:
189  qof_instance_get_kvp (QOF_INSTANCE (vendor), value, 2, GNC_PAYMENT, GNC_LAST_ACCOUNT);
190  break;
191  default:
192  G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
193  break;
194  }
195 }
196 
197 static void
198 gnc_vendor_set_property (GObject *object,
199  guint prop_id,
200  const GValue *value,
201  GParamSpec *pspec)
202 {
203  GncVendor *vendor;
204  gchar *key;
205 
206  g_return_if_fail(GNC_IS_VENDOR(object));
207 
208  vendor = GNC_VENDOR(object);
209  g_assert (qof_instance_get_editlevel(vendor));
210 
211  switch (prop_id)
212  {
213  case PROP_NAME:
214  gncVendorSetName(vendor, g_value_get_string(value));
215  break;
216  case PROP_ID:
217  gncVendorSetID(vendor, g_value_get_string(value));
218  break;
219  case PROP_NOTES:
220  gncVendorSetNotes(vendor, g_value_get_string(value));
221  break;
222  case PROP_CURRENCY:
223  gncVendorSetCurrency(vendor, g_value_get_object(value));
224  break;
225  case PROP_ACTIVE:
226  gncVendorSetActive(vendor, g_value_get_boolean(value));
227  break;
228  case PROP_TAXTABLE_OVERRIDE:
229  gncVendorSetTaxTableOverride(vendor, g_value_get_boolean(value));
230  break;
231  case PROP_BILLTERMS:
232  gncVendorSetTerms(vendor, g_value_get_object(value));
233  break;
234  case PROP_TAXTABLE:
235  gncVendorSetTaxTable(vendor, g_value_get_object(value));
236  break;
237  case PROP_ADDRESS:
238  qofVendorSetAddr(vendor, g_value_get_object(value));
239  break;
240  case PROP_TAX_INCLUDED:
241  gncVendorSetTaxIncluded(vendor, (GncTaxIncluded)g_value_get_int(value));
242  break;
243  case PROP_TAX_INCLUDED_STR:
244  qofVendorSetTaxIncluded(vendor, g_value_get_string(value));
245  break;
246  case PROP_PDF_DIRNAME:
247  qof_instance_set_kvp (QOF_INSTANCE (vendor), value, 1, OWNER_EXPORT_PDF_DIRNAME);
248  break;
249  case PROP_LAST_POSTED:
250  qof_instance_set_kvp (QOF_INSTANCE (vendor), value, 1, LAST_POSTED_TO_ACCT);
251  break;
252  case PROP_PAYMENT_LAST_ACCT:
253  qof_instance_set_kvp (QOF_INSTANCE (vendor), value, 2, GNC_PAYMENT, GNC_LAST_ACCOUNT);
254  break;
255  default:
256  G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
257  break;
258  }
259 }
260 
262 static gboolean
263 impl_refers_to_object(const QofInstance* inst, const QofInstance* ref)
264 {
265  GncVendor* v;
266 
267  g_return_val_if_fail(inst != NULL, FALSE);
268  g_return_val_if_fail(GNC_IS_VENDOR(inst), FALSE);
269 
270  v = GNC_VENDOR(inst);
271 
272  if (GNC_IS_BILLTERM(ref))
273  {
274  return (v->terms == GNC_BILLTERM(ref));
275  }
276  else if (GNC_IS_TAXTABLE(ref))
277  {
278  return (v->taxtable == GNC_TAXTABLE(ref));
279  }
280 
281  return FALSE;
282 }
283 
290 static GList*
291 impl_get_typed_referring_object_list(const QofInstance* inst, const QofInstance* ref)
292 {
293  if (!GNC_IS_BILLTERM(ref) && !GNC_IS_TAXTABLE(ref))
294  {
295  return NULL;
296  }
297 
299 }
300 
301 static void
302 gnc_vendor_class_init (GncVendorClass *klass)
303 {
304  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
305  QofInstanceClass* qof_class = QOF_INSTANCE_CLASS(klass);
306 
307  gobject_class->dispose = gnc_vendor_dispose;
308  gobject_class->finalize = gnc_vendor_finalize;
309  gobject_class->set_property = gnc_vendor_set_property;
310  gobject_class->get_property = gnc_vendor_get_property;
311 
312  qof_class->get_display_name = NULL;
313  qof_class->refers_to_object = impl_refers_to_object;
314  qof_class->get_typed_referring_object_list = impl_get_typed_referring_object_list;
315 
316  g_object_class_install_property
317  (gobject_class,
318  PROP_NAME,
319  g_param_spec_string ("name",
320  "Vendor Name",
321  "The vendor name is an arbitrary string "
322  "assigned by the user to provide the vendor name.",
323  NULL,
324  G_PARAM_READWRITE));
325 
326  g_object_class_install_property
327  (gobject_class,
328  PROP_ID,
329  g_param_spec_string ("id",
330  "Vendor ID",
331  "The vendor id is an arbitrary string "
332  "assigned by the user to identify the vendor.",
333  NULL,
334  G_PARAM_READWRITE));
335 
336  g_object_class_install_property
337  (gobject_class,
338  PROP_NOTES,
339  g_param_spec_string ("notes",
340  "Vendor notes",
341  "The vendor notes is an arbitrary string "
342  "assigned by the user to add extra information about the vendor.",
343  NULL,
344  G_PARAM_READWRITE));
345 
346  g_object_class_install_property
347  (gobject_class,
348  PROP_CURRENCY,
349  g_param_spec_object ("currency",
350  "Currency",
351  "The currency property denotes the currency used by this vendor.",
352  GNC_TYPE_COMMODITY,
353  G_PARAM_READWRITE));
354 
355  g_object_class_install_property
356  (gobject_class,
357  PROP_ACTIVE,
358  g_param_spec_boolean ("active",
359  "Active",
360  "TRUE if the vendor is active. FALSE if inactive.",
361  FALSE,
362  G_PARAM_READWRITE));
363 
364  g_object_class_install_property
365  (gobject_class,
366  PROP_TAXTABLE_OVERRIDE,
367  g_param_spec_boolean ("tax-table-override",
368  "Tax table override",
369  "TRUE if the vendor has a specific tax table which overrides the default "
370  "tax table. FALSE if the default table should be used.",
371  FALSE,
372  G_PARAM_READWRITE));
373 
374  g_object_class_install_property
375  (gobject_class,
376  PROP_BILLTERMS,
377  g_param_spec_object ("terms",
378  "Terms",
379  "The billing terms used by this vendor.",
380  GNC_TYPE_BILLTERM,
381  G_PARAM_READWRITE));
382 
383  g_object_class_install_property
384  (gobject_class,
385  PROP_TAXTABLE,
386  g_param_spec_object ("tax-table",
387  "Tax table",
388  "The tax table which applies to this vendor.",
389  GNC_TYPE_TAXTABLE,
390  G_PARAM_READWRITE));
391 
392  g_object_class_install_property
393  (gobject_class,
394  PROP_ADDRESS,
395  g_param_spec_object ("address",
396  "Address",
397  "The address property contains the address information for this vendor.",
398  GNC_TYPE_ADDRESS,
399  G_PARAM_READWRITE));
400 
401  g_object_class_install_property
402  (gobject_class,
403  PROP_TAX_INCLUDED,
404  g_param_spec_int ("tax-included",
405  "Tax included",
406  "The tax-included property contains the information about tax calculation this vendor.",
407  GNC_TAXINCLUDED_YES, /* min */
408  GNC_TAXINCLUDED_USEGLOBAL, /* max */
409  GNC_TAXINCLUDED_USEGLOBAL, /* default */
410  G_PARAM_READWRITE));
411 
412  g_object_class_install_property
413  (gobject_class,
414  PROP_TAX_INCLUDED_STR,
415  g_param_spec_string("tax-included-string",
416  "Tax included string",
417  "The tax-included-string property contains a character version of tax-included.",
418  FALSE,
419  G_PARAM_READWRITE));
420  g_object_class_install_property
421  (gobject_class,
422  PROP_PDF_DIRNAME,
423  g_param_spec_string ("export-pdf-dir",
424  "Export PDF Directory Name",
425  "A subdirectory for exporting PDF reports which is "
426  "appended to the target directory when writing them "
427  "out. It is retrieved from preferences and stored on "
428  "each 'Owner' object which prints items after "
429  "printing.",
430  NULL,
431  G_PARAM_READWRITE));
432 
433  g_object_class_install_property(
434  gobject_class,
435  PROP_LAST_POSTED,
436  g_param_spec_boxed("invoice-last-posted-account",
437  "Invoice Last Posted Account",
438  "The last account to which an invoice belonging to "
439  "this owner was posted.",
440  GNC_TYPE_GUID,
441  G_PARAM_READWRITE));
442 
443  g_object_class_install_property(
444  gobject_class,
445  PROP_PAYMENT_LAST_ACCT,
446  g_param_spec_boxed("payment-last-account",
447  "Payment Last Account",
448  "The last account to which an payment belonging to "
449  "this owner was posted.",
450  GNC_TYPE_GUID,
451  G_PARAM_READWRITE));
452 }
453 
454 /* Create/Destroy Functions */
455 GncVendor *gncVendorCreate (QofBook *book)
456 {
457  GncVendor *vendor;
458 
459  if (!book) return NULL;
460 
461  vendor = g_object_new (GNC_TYPE_VENDOR, NULL);
462  qof_instance_init_data (&vendor->inst, _GNC_MOD_NAME, book);
463 
464  vendor->id = CACHE_INSERT ("");
465  vendor->name = CACHE_INSERT ("");
466  vendor->notes = CACHE_INSERT ("");
467  vendor->addr = gncAddressCreate (book, &vendor->inst);
468  vendor->taxincluded = GNC_TAXINCLUDED_USEGLOBAL;
469  vendor->active = TRUE;
470  vendor->jobs = NULL;
471  vendor->balance = NULL;
472 
473  if (vend_qof_event_handler_id == 0)
474  vend_qof_event_handler_id = qof_event_register_handler (vend_handle_qof_events, NULL);
475 
476  qof_event_gen (&vendor->inst, QOF_EVENT_CREATE, NULL);
477 
478  return vendor;
479 }
480 
481 void gncVendorDestroy (GncVendor *vendor)
482 {
483  if (!vendor) return;
484  qof_instance_set_destroying(vendor, TRUE);
485  gncVendorCommitEdit (vendor);
486 }
487 
488 static void gncVendorFree (GncVendor *vendor)
489 {
490  if (!vendor) return;
491 
492  qof_event_gen (&vendor->inst, QOF_EVENT_DESTROY, NULL);
493 
494  CACHE_REMOVE (vendor->id);
495  CACHE_REMOVE (vendor->name);
496  CACHE_REMOVE (vendor->notes);
497  gncAddressBeginEdit (vendor->addr);
498  gncAddressDestroy (vendor->addr);
499  g_list_free (vendor->jobs);
500  g_free (vendor->balance);
501 
502  if (vendor->terms)
503  gncBillTermDecRef (vendor->terms);
504  if (vendor->taxtable)
505  gncTaxTableDecRef (vendor->taxtable);
506 
507  /* qof_instance_release (&vendor->inst); */
508  g_object_unref (vendor);
509 }
510 
511 /* ============================================================== */
512 /* Set Functions */
513 
514 #define SET_STR(obj, member, str) { \
515  if (!g_strcmp0 (member, str)) return; \
516  gncVendorBeginEdit (obj); \
517  CACHE_REPLACE (member, str); \
518  }
519 
520 void gncVendorSetID (GncVendor *vendor, const char *id)
521 {
522  if (!vendor) return;
523  if (!id) return;
524  SET_STR(vendor, vendor->id, id);
525  mark_vendor (vendor);
526  gncVendorCommitEdit (vendor);
527 }
528 
529 void gncVendorSetName (GncVendor *vendor, const char *name)
530 {
531  if (!vendor) return;
532  if (!name) return;
533  SET_STR(vendor, vendor->name, name);
534  mark_vendor (vendor);
535  gncVendorCommitEdit (vendor);
536 }
537 
538 void gncVendorSetNotes (GncVendor *vendor, const char *notes)
539 {
540  if (!vendor) return;
541  if (!notes) return;
542  SET_STR(vendor, vendor->notes, notes);
543  mark_vendor (vendor);
544  gncVendorCommitEdit (vendor);
545 }
546 
547 void gncVendorSetTerms (GncVendor *vendor, GncBillTerm *terms)
548 {
549  if (!vendor) return;
550  if (vendor->terms == terms) return;
551 
552  gncVendorBeginEdit (vendor);
553  if (vendor->terms)
554  gncBillTermDecRef (vendor->terms);
555  vendor->terms = terms;
556  if (vendor->terms)
557  gncBillTermIncRef (vendor->terms);
558  mark_vendor (vendor);
559  gncVendorCommitEdit (vendor);
560 }
561 
562 void gncVendorSetTaxIncluded (GncVendor *vendor, GncTaxIncluded taxincl)
563 {
564  if (!vendor) return;
565  if (taxincl == vendor->taxincluded) return;
566  gncVendorBeginEdit (vendor);
567  vendor->taxincluded = taxincl;
568  mark_vendor (vendor);
569  gncVendorCommitEdit (vendor);
570 }
571 
572 void gncVendorSetCurrency (GncVendor *vendor, gnc_commodity *currency)
573 {
574  if (!vendor || !currency) return;
575  if (vendor->currency &&
576  gnc_commodity_equal (vendor->currency, currency))
577  return;
578  gncVendorBeginEdit (vendor);
579  vendor->currency = currency;
580  mark_vendor (vendor);
581  gncVendorCommitEdit (vendor);
582 }
583 
584 void gncVendorSetActive (GncVendor *vendor, gboolean active)
585 {
586  if (!vendor) return;
587  if (active == vendor->active) return;
588  gncVendorBeginEdit (vendor);
589  vendor->active = active;
590  mark_vendor (vendor);
591  gncVendorCommitEdit (vendor);
592 }
593 
594 void gncVendorSetTaxTableOverride (GncVendor *vendor, gboolean override)
595 {
596  if (!vendor) return;
597  if (vendor->taxtable_override == override) return;
598  gncVendorBeginEdit (vendor);
599  vendor->taxtable_override = override;
600  mark_vendor (vendor);
601  gncVendorCommitEdit (vendor);
602 }
603 
604 void gncVendorSetTaxTable (GncVendor *vendor, GncTaxTable *table)
605 {
606  if (!vendor) return;
607  if (vendor->taxtable == table) return;
608  gncVendorBeginEdit (vendor);
609  if (vendor->taxtable)
610  gncTaxTableDecRef (vendor->taxtable);
611  if (table)
612  gncTaxTableIncRef (table);
613  vendor->taxtable = table;
614  mark_vendor (vendor);
615  gncVendorCommitEdit (vendor);
616 }
617 
618 static void
619 qofVendorSetAddr (GncVendor *vendor, QofInstance *addr_ent)
620 {
621  GncAddress *addr;
622 
623  if (!vendor || !addr_ent)
624  {
625  return;
626  }
627  addr = (GncAddress*)addr_ent;
628  if (addr == vendor->addr)
629  {
630  return;
631  }
632  if (vendor->addr != NULL)
633  {
634  gncAddressBeginEdit(vendor->addr);
635  gncAddressDestroy(vendor->addr);
636  }
637  gncVendorBeginEdit(vendor);
638  vendor->addr = addr;
639  gncVendorCommitEdit(vendor);
640 }
641 
642 static void
643 qofVendorSetTaxIncluded(GncVendor *vendor, const char* type_string)
644 {
645  GncTaxIncluded inc;
646 
647  if (!gncTaxIncludedStringToType(type_string, &inc))
648  {
649  return;
650  }
651  gncVendorBeginEdit(vendor);
652  vendor->taxincluded = inc;
653  gncVendorCommitEdit(vendor);
654 }
655 
656 /* ============================================================== */
657 /* Get Functions */
658 
659 const char * gncVendorGetID (const GncVendor *vendor)
660 {
661  if (!vendor) return NULL;
662  return vendor->id;
663 }
664 
665 const char * gncVendorGetName (const GncVendor *vendor)
666 {
667  if (!vendor) return NULL;
668  return vendor->name;
669 }
670 
671 GncAddress * gncVendorGetAddr (const GncVendor *vendor)
672 {
673  if (!vendor) return NULL;
674  return vendor->addr;
675 }
676 
677 const char * gncVendorGetNotes (const GncVendor *vendor)
678 {
679  if (!vendor) return NULL;
680  return vendor->notes;
681 }
682 
683 GncBillTerm * gncVendorGetTerms (const GncVendor *vendor)
684 {
685  if (!vendor) return 0;
686  return vendor->terms;
687 }
688 
689 GncTaxIncluded gncVendorGetTaxIncluded (const GncVendor *vendor)
690 {
691  if (!vendor) return GNC_TAXINCLUDED_USEGLOBAL;
692  return vendor->taxincluded;
693 }
694 
695 gnc_commodity * gncVendorGetCurrency (const GncVendor *vendor)
696 {
697  if (!vendor) return NULL;
698  return vendor->currency;
699 }
700 
701 gboolean gncVendorGetActive (const GncVendor *vendor)
702 {
703  if (!vendor) return FALSE;
704  return vendor->active;
705 }
706 
707 gboolean gncVendorGetTaxTableOverride (const GncVendor *vendor)
708 {
709  if (!vendor) return FALSE;
710  return vendor->taxtable_override;
711 }
712 
713 GncTaxTable* gncVendorGetTaxTable (const GncVendor *vendor)
714 {
715  if (!vendor) return NULL;
716  return vendor->taxtable;
717 }
718 
719 static const char*
720 qofVendorGetTaxIncluded(const GncVendor *vendor)
721 {
722  return gncTaxIncludedTypeToString(vendor->taxincluded);
723 }
724 
725 /* Note that JobList changes do not affect the "dirtiness" of the vendor */
726 void gncVendorAddJob (GncVendor *vendor, GncJob *job)
727 {
728  if (!vendor) return;
729  if (!job) return;
730 
731  if (g_list_index(vendor->jobs, job) == -1)
732  vendor->jobs = g_list_insert_sorted (vendor->jobs, job,
733  (GCompareFunc)gncJobCompare);
734 
735  qof_event_gen (&vendor->inst, QOF_EVENT_MODIFY, NULL);
736 }
737 
738 void gncVendorRemoveJob (GncVendor *vendor, GncJob *job)
739 {
740  GList *node;
741 
742  if (!vendor) return;
743  if (!job) return;
744 
745  node = g_list_find (vendor->jobs, job);
746  if (!node)
747  {
748  /* PERR ("split not in account"); */
749  }
750  else
751  {
752  vendor->jobs = g_list_remove_link (vendor->jobs, node);
753  g_list_free_1 (node);
754  }
755 
756  qof_event_gen (&vendor->inst, QOF_EVENT_MODIFY, NULL);
757 }
758 
759 void gncVendorBeginEdit (GncVendor *vendor)
760 {
761  qof_begin_edit(&vendor->inst);
762 }
763 
764 static void gncVendorOnError (QofInstance *vendor, QofBackendError errcode)
765 {
766  PERR("Vendor QofBackend Failure: %d", errcode);
767  gnc_engine_signal_commit_error( errcode );
768 }
769 
770 static void gncVendorOnDone (QofInstance *inst)
771 {
772  GncVendor *vendor = (GncVendor *) inst;
773  gncAddressClearDirty (vendor->addr);
774 }
775 
776 static void vendor_free (QofInstance *inst)
777 {
778  GncVendor *vendor = (GncVendor *) inst;
779  gncVendorFree (vendor);
780 }
781 
782 void gncVendorCommitEdit (GncVendor *vendor)
783 {
784  if (!qof_commit_edit (QOF_INSTANCE(vendor))) return;
785  qof_commit_edit_part2 (&vendor->inst, gncVendorOnError,
786  gncVendorOnDone, vendor_free);
787 }
788 
789 /* ============================================================== */
790 /* Other functions */
791 
792 int gncVendorCompare (const GncVendor *a, const GncVendor *b)
793 {
794  if (!a && !b) return 0;
795  if (!a && b) return 1;
796  if (a && !b) return -1;
797 
798  return(strcmp(a->name, b->name));
799 }
800 
801 gboolean gncVendorEqual(const GncVendor *a, const GncVendor *b)
802 {
803  if (a == NULL && b == NULL) return TRUE;
804  if (a == NULL || b == NULL) return FALSE;
805 
806  g_return_val_if_fail(GNC_IS_VENDOR(a), FALSE);
807  g_return_val_if_fail(GNC_IS_VENDOR(b), FALSE);
808 
809  if (g_strcmp0(a->id, b->id) != 0)
810  {
811  PWARN("IDs differ: %s vs %s", a->id, b->id);
812  return FALSE;
813  }
814 
815  if (g_strcmp0(a->name, b->name) != 0)
816  {
817  PWARN("Names differ: %s vs %s", a->name, b->name);
818  return FALSE;
819  }
820 
821  if (g_strcmp0(a->notes, b->notes) != 0)
822  {
823  PWARN("Notes differ");
824  return FALSE;
825  }
826 
827  if (!gncBillTermEqual(a->terms, b->terms))
828  {
829  PWARN("BillTerms differ");
830  return FALSE;
831  }
832 
833  if (!gncAddressEqual(a->addr, b->addr))
834  {
835  PWARN("Addresses differ");
836  return FALSE;
837  }
838 
839  if (!gnc_commodity_equal(a->currency, b->currency))
840  {
841  PWARN("Currencies differ");
842  return FALSE;
843  }
844 
845  if (!gncTaxTableEqual(a->taxtable, b->taxtable))
846  {
847  PWARN("Tax tables differ");
848  return FALSE;
849  }
850 
851  if (a->taxtable_override != b->taxtable_override)
852  {
853  PWARN("Tax table override flags differ");
854  return FALSE;
855  }
856 
857  if (a->taxincluded != b->taxincluded)
858  {
859  PWARN("Tax included flags differ");
860  return FALSE;
861  }
862 
863  if (a->active != b->active)
864  {
865  PWARN("Active flags differ");
866  return FALSE;
867  }
868 
869 // GList * jobs;
870  return TRUE;
871 }
872 
873 gboolean
874 gncVendorIsDirty (const GncVendor *vendor)
875 {
876  if (!vendor) return FALSE;
877  return (qof_instance_get_dirty_flag(vendor)
878  || gncAddressIsDirty (vendor->addr));
879 }
880 
893 static void
894 vend_handle_qof_events (QofInstance *entity, QofEventId event_type,
895  gpointer user_data, gpointer event_data)
896 {
897  /* Handle address change events */
898  if ((GNC_IS_ADDRESS (entity) &&
899  (event_type & QOF_EVENT_MODIFY) != 0))
900  {
901  if (GNC_IS_VENDOR (event_data))
902  {
903  GncVendor* vend = GNC_VENDOR (event_data);
904  gncVendorBeginEdit (vend);
905  mark_vendor (vend);
906  gncVendorCommitEdit (vend);
907  }
908  return;
909  }
910 
911  /* Handle lot change events */
912  if (GNC_IS_LOT (entity))
913  {
914  GNCLot *lot = GNC_LOT (entity);
915  GncOwner lot_owner;
916  const GncOwner *end_owner = NULL;
917  GncInvoice *invoice = gncInvoiceGetInvoiceFromLot (lot);
918 
919  /* Determine the owner associated with the lot */
920  if (invoice)
921  /* Invoice lots */
922  end_owner = gncOwnerGetEndOwner (gncInvoiceGetOwner (invoice));
923  else if (gncOwnerGetOwnerFromLot (lot, &lot_owner))
924  /* Pre-payment lots */
925  end_owner = gncOwnerGetEndOwner (&lot_owner);
926 
927  if (gncOwnerGetType (end_owner) == GNC_OWNER_VENDOR)
928  {
929  /* Clear the cached balance */
930  GncVendor* vend = gncOwnerGetVendor (end_owner);
931  g_free (vend->balance);
932  vend->balance = NULL;
933  }
934  return;
935  }
936 }
937 
938 /* ============================================================== */
939 /* Package-Private functions */
940 
941 static const char * _gncVendorPrintable (gpointer item)
942 {
943  GncVendor *v = item;
944  if (!item) return NULL;
945  return v->name;
946 }
947 
948 static void
949 destroy_vendor_on_book_close(QofInstance *ent, gpointer data)
950 {
951  GncVendor* v = GNC_VENDOR(ent);
952 
953  gncVendorBeginEdit(v);
954  gncVendorDestroy(v);
955 }
956 
961 static void
962 gnc_vendor_book_end(QofBook* book)
963 {
964  QofCollection *col;
965 
966  col = qof_book_get_collection(book, GNC_ID_VENDOR);
967  qof_collection_foreach(col, destroy_vendor_on_book_close, NULL);
968 }
969 
970 static QofObject gncVendorDesc =
971 {
972  DI(.interface_version = ) QOF_OBJECT_VERSION,
973  DI(.e_type = ) _GNC_MOD_NAME,
974  DI(.type_label = ) "Vendor",
975  DI(.create = ) (gpointer)gncVendorCreate,
976  DI(.book_begin = ) NULL,
977  DI(.book_end = ) gnc_vendor_book_end,
978  DI(.is_dirty = ) qof_collection_is_dirty,
979  DI(.mark_clean = ) qof_collection_mark_clean,
980  DI(.foreach = ) qof_collection_foreach,
981  DI(.printable = ) _gncVendorPrintable,
982  DI(.version_cmp = ) (int (*)(gpointer, gpointer)) qof_instance_version_cmp,
983 };
984 
985 gboolean gncVendorRegister (void)
986 {
987  static QofParam params[] =
988  {
989  { VENDOR_ID, QOF_TYPE_STRING, (QofAccessFunc)gncVendorGetID, (QofSetterFunc)gncVendorSetID },
990  { VENDOR_NAME, QOF_TYPE_STRING, (QofAccessFunc)gncVendorGetName, (QofSetterFunc)gncVendorSetName },
991  { VENDOR_ADDR, GNC_ID_ADDRESS, (QofAccessFunc)gncVendorGetAddr, (QofSetterFunc)qofVendorSetAddr },
992  { VENDOR_NOTES, QOF_TYPE_STRING, (QofAccessFunc)gncVendorGetNotes, (QofSetterFunc)gncVendorSetNotes },
993  { VENDOR_TERMS, GNC_ID_BILLTERM, (QofAccessFunc)gncVendorGetTerms, (QofSetterFunc)gncVendorSetTerms },
994  {
995  VENDOR_TAX_OVERRIDE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncVendorGetTaxTableOverride,
996  (QofSetterFunc)gncVendorSetTaxTableOverride
997  },
998  {
999  VENDOR_TAX_TABLE, GNC_ID_TAXTABLE, (QofAccessFunc)gncVendorGetTaxTable,
1000  (QofSetterFunc)gncVendorSetTaxTable
1001  },
1002  {
1003  VENDOR_TAX_INC, QOF_TYPE_STRING, (QofAccessFunc)qofVendorGetTaxIncluded,
1004  (QofSetterFunc)qofVendorSetTaxIncluded
1005  },
1006  { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
1007  { QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
1008  { QOF_PARAM_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncVendorGetActive, NULL },
1009  { NULL },
1010  };
1011 
1012  if (!qof_choice_add_class(GNC_ID_INVOICE, GNC_ID_VENDOR, INVOICE_OWNER))
1013  {
1014  return FALSE;
1015  }
1016  if (!qof_choice_add_class(GNC_ID_JOB, GNC_ID_VENDOR, JOB_OWNER))
1017  {
1018  return FALSE;
1019  }
1020 
1021  qof_class_register (_GNC_MOD_NAME, (QofSortFunc)gncVendorCompare, params);
1022 
1023  return qof_object_register (&gncVendorDesc);
1024 }
1025 
1026 gchar *gncVendorNextID (QofBook *book)
1027 {
1028  return qof_book_increment_and_format_counter (book, _GNC_MOD_NAME);
1029 }
1030 
1031 const gnc_numeric*
1032 gncVendorGetCachedBalance (GncVendor *vend)
1033 {
1034  return vend->balance;
1035 }
1036 
1037 void gncVendorSetCachedBalance (GncVendor *vend, const gnc_numeric *new_bal)
1038 {
1039  if (!new_bal)
1040  {
1041  if (vend->balance)
1042  {
1043  g_free (vend->balance);
1044  vend->balance = NULL;
1045  }
1046  return;
1047  }
1048 
1049  if (!vend->balance)
1050  vend->balance = g_new0 (gnc_numeric, 1);
1051 
1052  *vend->balance = *new_bal;
1053 }
int qof_instance_version_cmp(const QofInstance *left, const QofInstance *right)
Compare two instances, based on their last update times.
const GncGUID * qof_instance_get_guid(gconstpointer inst)
Return the GncGUID of this instance.
void qof_instance_set_kvp(QofInstance *, GValue const *value, unsigned count,...)
Sets a KVP slot to a value from a GValue.
QofBook * qof_instance_get_book(gconstpointer inst)
Return the book pointer.
gboolean qof_collection_is_dirty(const QofCollection *col)
Return value of &#39;dirty&#39; flag on collection.
Definition: qofid.cpp:257
GncTaxIncluded
How to interpret the TaxIncluded.
Definition: gncTaxTable.h:74
QofBackendError
The errors that can be reported to the GUI & other front-end users.
Definition: qofbackend.h:57
gchar * qof_book_increment_and_format_counter(QofBook *book, const char *counter_name)
This will increment the named counter for this book and format it.
Definition: qofbook.cpp:703
GList * qof_instance_get_referring_object_list_from_collection(const QofCollection *coll, const QofInstance *ref)
Returns a list of objects from the collection which refer to the specific object. ...
void qof_class_register(QofIdTypeConst obj_name, QofSortFunc default_sort_function, const QofParam *params)
This function registers a new object class with the Qof subsystem.
Definition: qofclass.cpp:86
gboolean gnc_commodity_equal(const gnc_commodity *a, const gnc_commodity *b)
This routine returns TRUE if the two commodities are equal.
tax is included
Definition: gncTaxTable.h:76
QofCollection * qof_instance_get_collection(gconstpointer ptr)
Return the collection this instance belongs to.
int(* QofSortFunc)(gconstpointer, gconstpointer)
This function is the default sort function for a particular object type.
Definition: qofclass.h:222
#define QOF_OBJECT_VERSION
Defines the version of the core object object registration interface.
Definition: qofobject.h:64
gboolean qof_commit_edit(QofInstance *inst)
commit_edit helpers
#define PERR(format, args...)
Log a serious error.
Definition: qoflog.h:244
#define QOF_PARAM_BOOK
"Known" Object Parameters – all objects must support these
Definition: qofquery.h:109
use the global setting
Definition: gncTaxTable.h:78
void qof_collection_foreach(const QofCollection *col, QofInstanceForeachCB cb_func, gpointer user_data)
Call the callback for each entity in the collection.
Definition: qofid.cpp:323
void(* QofSetterFunc)(gpointer, gpointer)
The QofSetterFunc defines an function pointer for parameter setters.
Definition: qofclass.h:184
void qof_instance_get_kvp(QofInstance *, GValue *value, unsigned count,...)
Retrieves the contents of a KVP slot into a provided GValue.
gboolean gncBillTermEqual(const GncBillTerm *a, const GncBillTerm *b)
Check if all internal fields of a and b match.
Definition: gncBillTerm.c:643
gint qof_event_register_handler(QofEventHandler handler, gpointer user_data)
Register a handler for events.
Definition: qofevent.cpp:73
#define PWARN(format, args...)
Log a warning.
Definition: qoflog.h:250
void qof_instance_init_data(QofInstance *inst, QofIdType type, QofBook *book)
Initialise the settings associated with an instance.
gboolean qof_begin_edit(QofInstance *inst)
begin_edit
gint QofEventId
Define the type of events allowed.
Definition: qofevent.h:45
gboolean qof_instance_get_dirty_flag(gconstpointer ptr)
Retrieve the flag that indicates whether or not this object has been modified.
gboolean qof_commit_edit_part2(QofInstance *inst, void(*on_error)(QofInstance *, QofBackendError), void(*on_done)(QofInstance *), void(*on_free)(QofInstance *))
part2 – deal with the backend
gboolean gncOwnerGetOwnerFromLot(GNCLot *lot, GncOwner *owner)
Get the owner from the lot.
Definition: gncOwner.c:637
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
The QofAccessFunc defines an arbitrary function pointer for access functions.
Definition: qofclass.h:177
void qof_collection_mark_clean(QofCollection *)
reset value of dirty flag
Definition: qofid.cpp:263
int gncVendorCompare(const GncVendor *a, const GncVendor *b)
XXX should be renamed to RetJobList to be consistent with other usage, since caller must free the cop...
Definition: gncVendor.c:792
gboolean gncAddressEqual(const GncAddress *a, const GncAddress *b)
Deeply compare two addresses.
Definition: gncAddress.c:577
GncOwnerType gncOwnerGetType(const GncOwner *owner)
Returns the GncOwnerType of this owner.
Definition: gncOwner.c:201
const GncOwner * gncOwnerGetEndOwner(const GncOwner *owner)
Get the "parent" Owner or GncGUID thereof.
Definition: gncOwner.c:573
GncInvoice * gncInvoiceGetInvoiceFromLot(GNCLot *lot)
Given a LOT, find and return the Invoice attached to the lot.
Definition: gncInvoice.c:1301
Business Invoice Interface.
gboolean qof_choice_add_class(const char *select, char *option, char *param_name)
Add the choices for this parameter to the object.
Definition: qofchoice.cpp:78
gboolean gncVendorEqual(const GncVendor *a, const GncVendor *b)
Test support function, used by test-dbi-business-stuff.c.
Definition: gncVendor.c:801
GncVendor * gncOwnerGetVendor(const GncOwner *owner)
If the given owner is of type GNC_OWNER_VENDOR, returns the pointer to the vendor object...
Definition: gncOwner.c:384
Vendor Interface.
QofCollection * qof_book_get_collection(const QofBook *book, QofIdType entity_type)
Return The table of entities of the given type.
Definition: qofbook.cpp:604
gboolean qof_object_register(const QofObject *object)
Register new types of object objects.
Definition: qofobject.cpp:317
void qof_event_gen(QofInstance *entity, QofEventId event_id, gpointer event_data)
Invoke all registered event handlers using the given arguments.
Definition: qofevent.cpp:231
Commodity handling public routines.
modtime is the internal date of the last modtime See src/doc/business.txt for an explanation of the f...