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