33 #include <qofinstance-p.h>
37 #include "gncAddressP.h"
38 #include "gncBillTermP.h"
40 #ifdef GNUCASH_MAJOR_VERSION
45 #include "gncCustomerP.h"
47 #include "gncTaxTableP.h"
49 static gint gs_address_event_handler_id = 0;
51 gpointer user_data, gpointer event_data);
65 gboolean taxtable_override;
83 #define _GNC_MOD_NAME GNC_ID_CUSTOMER
88 G_INLINE_FUNC
void mark_customer (
GncCustomer *customer);
91 qof_instance_set_dirty(&customer->inst);
103 PROP_PAYMENT_LAST_ACCT,
107 G_DEFINE_TYPE(
GncCustomer, gnc_customer, QOF_TYPE_INSTANCE);
115 gnc_customer_dispose(GObject *custp)
117 G_OBJECT_CLASS(gnc_customer_parent_class)->dispose(custp);
121 gnc_customer_finalize(GObject* custp)
123 G_OBJECT_CLASS(gnc_customer_parent_class)->finalize(custp);
127 gnc_customer_get_property (GObject *
object,
134 g_return_if_fail(GNC_IS_CUSTOMER(
object));
136 cust = GNC_CUSTOMER(
object);
140 g_value_set_string(value, cust->name);
142 case PROP_PDF_DIRNAME:
143 key = OWNER_EXPORT_PDF_DIRNAME;
144 qof_instance_get_kvp (QOF_INSTANCE (cust), key, value);
146 case PROP_LAST_POSTED:
147 key = LAST_POSTED_TO_ACCT;
148 qof_instance_get_kvp (QOF_INSTANCE (cust), key, value);
150 case PROP_PAYMENT_LAST_ACCT:
151 key = GNC_PAYMENT
"/" GNC_LAST_ACCOUNT;
152 qof_instance_get_kvp (QOF_INSTANCE (cust), key, value);
155 G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
161 gnc_customer_set_property (GObject *
object,
169 g_return_if_fail(GNC_IS_CUSTOMER(
object));
171 cust = GNC_CUSTOMER(
object);
172 g_assert (qof_instance_get_editlevel(cust));
177 gncCustomerSetName(cust, g_value_get_string(value));
179 case PROP_PDF_DIRNAME:
180 key = OWNER_EXPORT_PDF_DIRNAME;
181 qof_instance_set_kvp (QOF_INSTANCE (cust), key, value);
183 case PROP_LAST_POSTED:
184 key = LAST_POSTED_TO_ACCT;
185 qof_instance_set_kvp (QOF_INSTANCE (cust), key, value);
187 case PROP_PAYMENT_LAST_ACCT:
188 key = GNC_PAYMENT
"/" GNC_LAST_ACCOUNT;
189 qof_instance_set_kvp (QOF_INSTANCE (cust), key, value);
192 G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
203 g_return_val_if_fail(inst != NULL, FALSE);
204 g_return_val_if_fail(GNC_IS_CUSTOMER(inst), FALSE);
206 cust = GNC_CUSTOMER(inst);
208 return g_strdup_printf(
"Customer %s", cust->name);
217 g_return_val_if_fail(inst != NULL, FALSE);
218 g_return_val_if_fail(GNC_IS_CUSTOMER(inst), FALSE);
220 cust = GNC_CUSTOMER(inst);
222 if (GNC_IS_BILLTERM(ref))
224 return (cust->terms == GNC_BILLTERM(ref));
226 else if (GNC_IS_TAXTABLE(ref))
228 return (cust->taxtable == GNC_TAXTABLE(ref));
243 if (!GNC_IS_BILLTERM(ref) && !GNC_IS_TAXTABLE(ref))
254 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
257 gobject_class->dispose = gnc_customer_dispose;
258 gobject_class->finalize = gnc_customer_finalize;
259 gobject_class->set_property = gnc_customer_set_property;
260 gobject_class->get_property = gnc_customer_get_property;
262 qof_class->get_display_name = impl_get_display_name;
263 qof_class->refers_to_object = impl_refers_to_object;
264 qof_class->get_typed_referring_object_list = impl_get_typed_referring_object_list;
266 g_object_class_install_property
269 g_param_spec_string (
"name",
271 "The customer is an arbitrary string "
272 "assigned by the user which provides the "
277 g_object_class_install_property
280 g_param_spec_string (
"export-pdf-dir",
281 "Export PDF Directory Name",
282 "A subdirectory for exporting PDF reports which is "
283 "appended to the target directory when writing them "
284 "out. It is retrieved from preferences and stored on "
285 "each 'Owner' object which prints items after "
290 g_object_class_install_property(
293 g_param_spec_boxed(
"invoice-last-posted-account",
294 "Invoice Last Posted Account",
295 "The last account to which an invoice belonging to "
296 "this owner was posted.",
300 g_object_class_install_property(
302 PROP_PAYMENT_LAST_ACCT,
303 g_param_spec_boxed(
"payment-last-account",
304 "Payment Last Account",
305 "The last account to which an payment belonging to "
306 "this owner was posted.",
316 if (!book)
return NULL;
318 cust = g_object_new (GNC_TYPE_CUSTOMER, NULL);
321 cust->id = CACHE_INSERT (
"");
322 cust->name = CACHE_INSERT (
"");
323 cust->notes = CACHE_INSERT (
"");
324 cust->addr = gncAddressCreate (book, &cust->inst);
329 cust->discount = gnc_numeric_zero();
330 cust->credit = gnc_numeric_zero();
331 cust->shipaddr = gncAddressCreate (book, &cust->inst);
333 if (gs_address_event_handler_id == 0)
346 qof_instance_set_destroying(cust, TRUE);
347 qof_instance_set_dirty (&cust->inst);
348 gncCustomerCommitEdit (cust);
357 CACHE_REMOVE (cust->id);
358 CACHE_REMOVE (cust->name);
359 CACHE_REMOVE (cust->notes);
360 gncAddressBeginEdit (cust->addr);
361 gncAddressDestroy (cust->addr);
362 gncAddressBeginEdit (cust->shipaddr);
363 gncAddressDestroy (cust->shipaddr);
364 g_list_free (cust->jobs);
367 gncBillTermDecRef (cust->terms);
370 gncTaxTableDecRef (cust->taxtable);
374 g_object_unref (cust);
380 #define SET_STR(obj, member, str) { \
383 if (!g_strcmp0 (member, str)) return; \
384 gncCustomerBeginEdit (obj); \
385 tmp = CACHE_INSERT (str); \
386 CACHE_REMOVE (member); \
390 void gncCustomerSetID (
GncCustomer *cust,
const char *
id)
394 SET_STR(cust, cust->id,
id);
395 mark_customer (cust);
396 gncCustomerCommitEdit (cust);
399 void gncCustomerSetName (
GncCustomer *cust,
const char *name)
403 SET_STR(cust, cust->name, name);
404 mark_customer (cust);
405 gncCustomerCommitEdit (cust);
408 void gncCustomerSetNotes (
GncCustomer *cust,
const char *notes)
412 SET_STR(cust, cust->notes, notes);
413 mark_customer (cust);
414 gncCustomerCommitEdit (cust);
420 if (cust->terms == terms)
return;
422 gncCustomerBeginEdit (cust);
424 gncBillTermDecRef (cust->terms);
427 gncBillTermIncRef (cust->terms);
428 mark_customer (cust);
429 gncCustomerCommitEdit (cust);
435 if (taxincl == cust->taxincluded)
return;
436 gncCustomerBeginEdit (cust);
437 cust->taxincluded = taxincl;
438 mark_customer (cust);
439 gncCustomerCommitEdit (cust);
442 void gncCustomerSetActive (
GncCustomer *cust, gboolean active)
445 if (active == cust->active)
return;
446 gncCustomerBeginEdit (cust);
447 cust->active = active;
448 mark_customer (cust);
449 gncCustomerCommitEdit (cust);
456 gncCustomerBeginEdit (cust);
457 cust->discount = discount;
458 mark_customer (cust);
459 gncCustomerCommitEdit (cust);
466 gncCustomerBeginEdit (cust);
467 cust->credit = credit;
468 mark_customer (cust);
469 gncCustomerCommitEdit (cust);
474 if (!cust || !currency)
return;
476 gncCustomerBeginEdit (cust);
477 cust->currency = currency;
478 mark_customer (cust);
479 gncCustomerCommitEdit (cust);
482 void gncCustomerSetTaxTableOverride (
GncCustomer *customer, gboolean
override)
484 if (!customer)
return;
485 if (customer->taxtable_override ==
override)
return;
486 gncCustomerBeginEdit (customer);
487 customer->taxtable_override =
override;
488 mark_customer (customer);
489 gncCustomerCommitEdit (customer);
494 if (!customer)
return;
495 if (customer->taxtable == table)
return;
497 gncCustomerBeginEdit (customer);
498 if (customer->taxtable)
499 gncTaxTableDecRef (customer->taxtable);
501 gncTaxTableIncRef (table);
502 customer->taxtable = table;
503 mark_customer (customer);
504 gncCustomerCommitEdit (customer);
513 if (g_list_index(cust->jobs, job) == -1)
514 cust->jobs = g_list_insert_sorted (cust->jobs, job,
515 (GCompareFunc)gncJobCompare);
527 node = g_list_find (cust->jobs, job);
534 cust->jobs = g_list_remove_link (cust->jobs, node);
535 g_list_free_1 (node);
547 PERR(
"Customer QofBackend Failure: %d", errcode);
548 gnc_engine_signal_commit_error( errcode );
554 gncAddressClearDirty (cust->addr);
555 gncAddressClearDirty (cust->shipaddr);
561 gncCustomerFree (cust);
568 gncCustomerOnDone, cust_free);
574 const char * gncCustomerGetID (
const GncCustomer *cust)
576 if (!cust)
return NULL;
580 const char * gncCustomerGetName (
const GncCustomer *cust)
582 if (!cust)
return NULL;
588 if (!cust)
return NULL;
597 if (!cust || !addr_ent)
602 if (addr == cust->addr)
606 if (cust->addr != NULL)
608 gncAddressBeginEdit(cust->addr);
609 gncAddressDestroy(cust->addr);
611 gncCustomerBeginEdit(cust);
613 gncCustomerCommitEdit(cust);
621 if (!cust || !ship_addr_ent)
626 if (ship_addr == cust->shipaddr)
630 if (cust->shipaddr != NULL)
632 gncAddressBeginEdit(cust->shipaddr);
633 gncAddressDestroy(cust->shipaddr);
635 gncCustomerBeginEdit(cust);
636 cust->shipaddr = ship_addr;
637 gncCustomerCommitEdit(cust);
642 if (!cust)
return NULL;
643 return cust->shipaddr;
646 const char * gncCustomerGetNotes (
const GncCustomer *cust)
648 if (!cust)
return NULL;
654 if (!cust)
return NULL;
661 return cust->taxincluded;
666 if (!cust)
return NULL;
667 return cust->currency;
670 gboolean gncCustomerGetActive (
const GncCustomer *cust)
672 if (!cust)
return FALSE;
678 if (!cust)
return gnc_numeric_zero();
679 return cust->discount;
684 if (!cust)
return gnc_numeric_zero();
688 gboolean gncCustomerGetTaxTableOverride (
const GncCustomer *customer)
690 if (!customer)
return FALSE;
691 return customer->taxtable_override;
696 if (!customer)
return NULL;
697 return customer->taxtable;
700 GList * gncCustomerGetJoblist (
const GncCustomer *cust, gboolean show_all)
702 if (!cust)
return NULL;
706 return (g_list_copy (cust->jobs));
710 GList *list = NULL, *iterator;
711 for (iterator = cust->jobs; iterator; iterator = iterator->next)
713 GncJob *j = iterator->data;
714 if (gncJobGetActive (j))
715 list = g_list_append (list, j);
723 if (!cust)
return FALSE;
725 gncAddressIsDirty (cust->addr) ||
726 gncAddressIsDirty (cust->shipaddr));
733 if (!a && !b)
return 0;
734 if (!a && b)
return 1;
735 if (a && !b)
return -1;
737 return(strcmp(a->name, b->name));
743 if (a == NULL && b == NULL)
return TRUE;
744 if (a == NULL || b == NULL)
return FALSE;
746 g_return_val_if_fail(GNC_IS_CUSTOMER(a), FALSE);
747 g_return_val_if_fail(GNC_IS_CUSTOMER(b), FALSE);
749 if (g_strcmp0(a->id, b->id) != 0)
751 PWARN(
"IDs differ: %s vs %s", a->id, b->id);
755 if (g_strcmp0(a->name, b->name) != 0)
757 PWARN(
"Names differ: %s vs %s", a->name, b->name);
761 if (g_strcmp0(a->notes, b->notes) != 0)
763 PWARN(
"Notes differ: %s vs %s", a->notes, b->notes);
769 PWARN(
"Bill terms differ");
775 PWARN(
"currencies differ");
779 if (!gncTaxTableEqual(a->taxtable, b->taxtable))
781 PWARN(
"tax tables differ");
785 if (a->taxtable_override != b->taxtable_override)
787 PWARN(
"Tax table override flags differ");
791 if (a->taxincluded != b->taxincluded)
793 PWARN(
"Tax included flags differ");
797 if (a->active != b->active)
799 PWARN(
"Active flags differ");
805 PWARN(
"addresses differ");
810 PWARN(
"addresses differ");
816 PWARN(
"Credit amounts differ");
822 PWARN(
"Discount amounts differ");
844 gpointer user_data, gpointer event_data)
848 if ((event_type & QOF_EVENT_MODIFY) == 0)
852 if (!GNC_IS_ADDRESS(entity))
856 if (!GNC_IS_CUSTOMER(event_data))
860 cust = GNC_CUSTOMER(event_data);
861 gncCustomerBeginEdit(cust);
863 gncCustomerCommitEdit(cust);
867 static const char * _gncCustomerPrintable (gpointer item)
870 if (!item)
return "failed";
875 destroy_customer_on_book_close(
QofInstance *ent, gpointer data)
879 gncCustomerBeginEdit(c);
880 gncCustomerDestroy(c);
888 gnc_customer_book_end(
QofBook* book)
899 DI(.e_type = ) _GNC_MOD_NAME,
900 DI(.type_label = ) "Customer",
901 DI(.create = ) (gpointer)gncCustomerCreate,
902 DI(.book_begin = ) NULL,
903 DI(.book_end = ) gnc_customer_book_end,
907 DI(.printable = ) (const
char * (*)(gpointer))gncCustomerGetName,
911 gboolean gncCustomerRegister (
void)
919 CUSTOMER_DISCOUNT, QOF_TYPE_NUMERIC, (
QofAccessFunc)gncCustomerGetDiscount,
923 CUSTOMER_CREDIT, QOF_TYPE_NUMERIC, (
QofAccessFunc)gncCustomerGetCredit,
929 CUSTOMER_TT_OVER, QOF_TYPE_BOOLEAN, (
QofAccessFunc)gncCustomerGetTaxTableOverride,
953 _gncCustomerPrintable(NULL);
957 gchar *gncCustomerNextID (
QofBook *book)
int qof_instance_version_cmp(const QofInstance *left, const QofInstance *right)
gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b)
const GncGUID * qof_instance_get_guid(gconstpointer)
#define qof_instance_is_dirty
QofBook * qof_instance_get_book(gconstpointer)
gboolean qof_collection_is_dirty(const QofCollection *col)
QofBackendError
The errors that can be reported to the GUI & other front-end users.
gchar * qof_book_increment_and_format_counter(QofBook *book, const char *counter_name)
GList * qof_instance_get_referring_object_list_from_collection(const QofCollection *coll, const QofInstance *ref)
void qof_class_register(QofIdTypeConst obj_name, QofSortFunc default_sort_fcn, const QofParam *params)
gboolean gnc_commodity_equal(const gnc_commodity *a, const gnc_commodity *b)
QofCollection * qof_instance_get_collection(gconstpointer inst)
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
#define QOF_OBJECT_VERSION
gboolean qof_commit_edit(QofInstance *inst)
#define PERR(format, args...)
void qof_collection_foreach(const QofCollection *, QofInstanceForeachCB, gpointer user_data)
gboolean gncBillTermEqual(const GncBillTerm *a, const GncBillTerm *b)
gint qof_event_register_handler(QofEventHandler handler, gpointer handler_data)
Register a handler for events.
#define PWARN(format, args...)
void qof_instance_init_data(QofInstance *, QofIdType, QofBook *)
gboolean qof_begin_edit(QofInstance *inst)
gboolean qof_choice_create(char *type)
Set an object as using QOF_TYPE_CHOICE.
int(* QofSortFunc)(gconstpointer, gconstpointer)
gboolean qof_commit_edit_part2(QofInstance *inst, void(*on_error)(QofInstance *, QofBackendError), void(*on_done)(QofInstance *), void(*on_free)(QofInstance *))
void qof_collection_mark_clean(QofCollection *)
gboolean gncAddressEqual(const GncAddress *a, const GncAddress *b)
Deeply compare two addresses.
Business Invoice Interface.
gboolean gncCustomerEqual(const GncCustomer *a, const GncCustomer *b)
gboolean qof_choice_add_class(const char *choice, char *add, char *param_name)
Add the choices for this parameter to the object.
void(* QofSetterFunc)(gpointer, gpointer)
QofCollection * qof_book_get_collection(const QofBook *, QofIdType)
gboolean qof_object_register(const QofObject *object)
void qof_event_gen(QofInstance *entity, QofEventId event_type, gpointer event_data)
Invoke all registered event handlers using the given arguments.
Commodity handling public routines.
const gchar * QofLogModule