GnuCash  4.8a-132-gcdaeb421d+
gncEmployee.c
1 /********************************************************************\
2  * gncEmployee.c -- the Core Employee 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 Vepstas <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 "Account.h"
36 #include "gnc-commodity.h"
37 #include "gncAddressP.h"
38 #include "gncEmployee.h"
39 #include "gncEmployeeP.h"
40 #include "gnc-lot.h"
41 #include "gncOwner.h"
42 
43 static gint empl_qof_event_handler_id = 0;
44 static void empl_handle_qof_events (QofInstance *entity, QofEventId event_type,
45  gpointer user_data, gpointer event_data);
46 
48 {
49  QofInstance inst;
50  const char * id;
51  const char * username;
52  GncAddress * addr;
53  gnc_commodity * currency;
54  gboolean active;
55  gnc_numeric * balance;
56 
57  const char * language;
58  const char * acl;
59  gnc_numeric workday;
60  gnc_numeric rate;
61 
62  Account * ccard_acc;
63 };
64 
66 {
67  QofInstanceClass parent_class;
68 };
69 
70 static QofLogModule log_module = GNC_MOD_BUSINESS;
71 
72 #define _GNC_MOD_NAME GNC_ID_EMPLOYEE
73 
74 static inline void mark_employee (GncEmployee *employee);
75 void mark_employee (GncEmployee *employee)
76 {
77  qof_instance_set_dirty(&employee->inst);
78  qof_event_gen (&employee->inst, QOF_EVENT_MODIFY, NULL);
79 }
80 
81 /* ============================================================== */
82 
83 enum
84 {
85  PROP_0,
86  PROP_USERNAME, /* Table */
87  PROP_ID, /* Table */
88  PROP_LANGUAGE, /* Table */
89  PROP_ACL, /* Table */
90  PROP_ACTIVE, /* Table */
91  PROP_CURRENCY, /* Table */
92  PROP_CCARD, /* Table */
93  PROP_WORKDAY, /* Table (numeric) */
94  PROP_RATE, /* Table (numeric) */
95  PROP_ADDRESS, /* Table, 8 fields */
96  PROP_PDF_DIRNAME, /* KVP */
97  PROP_LAST_POSTED, /* KVP */
98  PROP_PAYMENT_LAST_ACCT, /* KVP */
99 };
100 
101 /* GObject Initialization */
102 G_DEFINE_TYPE(GncEmployee, gnc_employee, QOF_TYPE_INSTANCE);
103 
104 static void
105 gnc_employee_init(GncEmployee* emp)
106 {
107 }
108 
109 static void
110 gnc_employee_dispose(GObject *empp)
111 {
112  G_OBJECT_CLASS(gnc_employee_parent_class)->dispose(empp);
113 }
114 
115 static void
116 gnc_employee_finalize(GObject* empp)
117 {
118  G_OBJECT_CLASS(gnc_employee_parent_class)->finalize(empp);
119 }
120 
121 /* Note that g_value_set_object() refs the object, as does
122  * g_object_get(). But g_object_get() only unrefs once when it disgorges
123  * the object, leaving an unbalanced ref, which leaks. So instead of
124  * using g_value_set_object(), use g_value_take_object() which doesn't
125  * ref the object when used in get_property().
126  */
127 static void
128 gnc_employee_get_property (GObject *object,
129  guint prop_id,
130  GValue *value,
131  GParamSpec *pspec)
132 {
133  GncEmployee *emp;
134  g_return_if_fail(GNC_IS_EMPLOYEE(object));
135  emp = GNC_EMPLOYEE(object);
136  switch (prop_id)
137  {
138  case PROP_USERNAME:
139  g_value_set_string(value, emp->username);
140  break;
141  case PROP_ID:
142  g_value_set_string(value, emp->id);
143  break;
144  case PROP_ACTIVE:
145  g_value_set_boolean(value, emp->active);
146  break;
147  case PROP_LANGUAGE:
148  g_value_set_string(value, emp->language);
149  break;
150  case PROP_CURRENCY:
151  g_value_take_object(value, emp->currency);
152  break;
153  case PROP_ACL:
154  g_value_set_string(value, emp->acl);
155  break;
156  case PROP_ADDRESS:
157  g_value_take_object(value, emp->addr);
158  break;
159  case PROP_WORKDAY:
160  g_value_set_boxed(value, &emp->workday);
161  break;
162  case PROP_RATE:
163  g_value_set_boxed(value, &emp->rate);
164  break;
165  case PROP_CCARD:
166  g_value_take_object(value, emp->ccard_acc);
167  break;
168  case PROP_PDF_DIRNAME:
169  qof_instance_get_kvp (QOF_INSTANCE (emp), value, 1, OWNER_EXPORT_PDF_DIRNAME);
170  break;
171  case PROP_LAST_POSTED:
172  qof_instance_get_kvp (QOF_INSTANCE (emp), value, 1, LAST_POSTED_TO_ACCT);
173  break;
174  case PROP_PAYMENT_LAST_ACCT:
175  qof_instance_get_kvp (QOF_INSTANCE (emp), value, 2, GNC_PAYMENT, GNC_LAST_ACCOUNT);
176  break;
177  default:
178  G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
179  break;
180  }
181 }
182 
183 static void
184 gnc_employee_set_property (GObject *object,
185  guint prop_id,
186  const GValue *value,
187  GParamSpec *pspec)
188 {
189  GncEmployee *emp;
190  g_return_if_fail(GNC_IS_EMPLOYEE(object));
191  emp = GNC_EMPLOYEE(object);
192  g_assert (qof_instance_get_editlevel(emp));
193  switch (prop_id)
194  {
195  case PROP_USERNAME:
196  gncEmployeeSetUsername(emp, g_value_get_string(value));
197  break;
198  case PROP_ID:
199  gncEmployeeSetID(emp, g_value_get_string(value));
200  break;
201  case PROP_ACTIVE:
202  gncEmployeeSetActive(emp, g_value_get_boolean(value));
203  break;
204  case PROP_LANGUAGE:
205  gncEmployeeSetLanguage(emp, g_value_get_string(value));
206  break;
207  case PROP_CURRENCY:
208  gncEmployeeSetCurrency(emp, g_value_get_object(value));
209  break;
210  case PROP_ACL:
211  gncEmployeeSetAcl(emp, g_value_get_string(value));
212  break;
213  case PROP_ADDRESS:
214  qofEmployeeSetAddr(emp, g_value_get_object(value));
215  break;
216  case PROP_WORKDAY:
217  gncEmployeeSetWorkday(emp, *(gnc_numeric*)g_value_get_boxed(value));
218  break;
219  case PROP_RATE:
220  gncEmployeeSetRate(emp, *(gnc_numeric*)g_value_get_boxed(value));
221  break;
222  case PROP_CCARD:
223  gncEmployeeSetCCard(emp, g_value_get_object(value));
224  break;
225  case PROP_PDF_DIRNAME:
226  qof_instance_set_kvp (QOF_INSTANCE (emp), value, 1, OWNER_EXPORT_PDF_DIRNAME);
227  break;
228  case PROP_LAST_POSTED:
229  qof_instance_set_kvp (QOF_INSTANCE (emp), value, 1, LAST_POSTED_TO_ACCT);
230  break;
231  case PROP_PAYMENT_LAST_ACCT:
232  qof_instance_set_kvp (QOF_INSTANCE (emp), value, 2, GNC_PAYMENT, GNC_LAST_ACCOUNT);
233  break;
234  default:
235  G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
236  break;
237  }
238 }
239 
241 static gboolean
242 impl_refers_to_object(const QofInstance* inst, const QofInstance* ref)
243 {
244  GncEmployee* emp;
245 
246  g_return_val_if_fail(inst != NULL, FALSE);
247  g_return_val_if_fail(GNC_IS_EMPLOYEE(inst), FALSE);
248 
249  emp = GNC_EMPLOYEE(inst);
250 
251  if (GNC_IS_COMMODITY(ref))
252  {
253  return (emp->currency == GNC_COMMODITY(ref));
254  }
255  else if (GNC_IS_ACCOUNT(ref))
256  {
257  return (emp->ccard_acc == GNC_ACCOUNT(ref));
258  }
259 
260  return FALSE;
261 }
262 
269 static GList*
270 impl_get_typed_referring_object_list(const QofInstance* inst, const QofInstance* ref)
271 {
272  if (!GNC_IS_COMMODITY(ref) && !GNC_IS_ACCOUNT(ref))
273  {
274  return NULL;
275  }
276 
278 }
279 
280 static void
281 gnc_employee_class_init (GncEmployeeClass *klass)
282 {
283  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
284  QofInstanceClass* qof_class = QOF_INSTANCE_CLASS(klass);
285 
286  gobject_class->dispose = gnc_employee_dispose;
287  gobject_class->finalize = gnc_employee_finalize;
288  gobject_class->set_property = gnc_employee_set_property;
289  gobject_class->get_property = gnc_employee_get_property;
290 
291  qof_class->get_display_name = NULL;
292  qof_class->refers_to_object = impl_refers_to_object;
293  qof_class->get_typed_referring_object_list = impl_get_typed_referring_object_list;
294 
295  g_object_class_install_property
296  (gobject_class,
297  PROP_USERNAME,
298  g_param_spec_string ("username",
299  "Employee Name",
300  "The employee name is an arbitrary string "
301  "assigned by the user which provides the employee "
302  "name.",
303  NULL,
304  G_PARAM_READWRITE));
305 
306  g_object_class_install_property
307  (gobject_class,
308  PROP_ID,
309  g_param_spec_string ("id",
310  "Employee ID",
311  "The employee ID is an arbitrary string "
312  "assigned by the user which provides the employee "
313  "ID.",
314  NULL,
315  G_PARAM_READWRITE));
316 
317  g_object_class_install_property
318  (gobject_class,
319  PROP_ACTIVE,
320  g_param_spec_boolean ("active",
321  "Active",
322  "TRUE if the employee is active. FALSE if inactive.",
323  FALSE,
324  G_PARAM_READWRITE));
325 
326  g_object_class_install_property
327  (gobject_class,
328  PROP_LANGUAGE,
329  g_param_spec_string ("language",
330  "Employee Language",
331  "The language is an arbitrary string "
332  "assigned by the user which provides the language spoken "
333  " by the employee.",
334  NULL,
335  G_PARAM_READWRITE));
336 
337  g_object_class_install_property
338  (gobject_class,
339  PROP_CURRENCY,
340  g_param_spec_object ("currency",
341  "Currency",
342  "The currency property denotes the currency used by this employee.",
343  GNC_TYPE_COMMODITY,
344  G_PARAM_READWRITE));
345 
346  g_object_class_install_property
347  (gobject_class,
348  PROP_ACL,
349  g_param_spec_string ("acl",
350  "Employee ACL",
351  "The acl is an arbitrary string "
352  "assigned by the user which provides ??? "
353  " for the employee.",
354  NULL,
355  G_PARAM_READWRITE));
356 
357  g_object_class_install_property
358  (gobject_class,
359  PROP_ADDRESS,
360  g_param_spec_object ("address",
361  "Address",
362  "The address property contains the address information for this employee.",
363  GNC_TYPE_ADDRESS,
364  G_PARAM_READWRITE));
365 
366  g_object_class_install_property
367  (gobject_class,
368  PROP_WORKDAY,
369  g_param_spec_boxed("workday",
370  "Workday rate",
371  "The daily rate for this employee.",
372  GNC_TYPE_NUMERIC,
373  G_PARAM_READWRITE));
374 
375  g_object_class_install_property
376  (gobject_class,
377  PROP_RATE,
378  g_param_spec_boxed("rate",
379  "Hourly rate",
380  "The hourly rate for this employee.",
381  GNC_TYPE_NUMERIC,
382  G_PARAM_READWRITE));
383 
384  g_object_class_install_property
385  (gobject_class,
386  PROP_CCARD,
387  g_param_spec_object ("credit-card-account",
388  "Credit card account",
389  "The credit card account for this employee.",
390  GNC_TYPE_ACCOUNT,
391  G_PARAM_READWRITE));
392 
393  g_object_class_install_property
394  (gobject_class,
395  PROP_PDF_DIRNAME,
396  g_param_spec_string ("export-pdf-dir",
397  "Export PDF Directory Name",
398  "A subdirectory for exporting PDF reports which is "
399  "appended to the target directory when writing them "
400  "out. It is retrieved from preferences and stored on "
401  "each 'Owner' object which prints items after "
402  "printing.",
403  NULL,
404  G_PARAM_READWRITE));
405 
406  g_object_class_install_property(
407  gobject_class,
408  PROP_LAST_POSTED,
409  g_param_spec_boxed("invoice-last-posted-account",
410  "Invoice Last Posted Account",
411  "The last account to which an invoice belonging to "
412  "this owner was posted.",
413  GNC_TYPE_GUID,
414  G_PARAM_READWRITE));
415 
416  g_object_class_install_property(
417  gobject_class,
418  PROP_PAYMENT_LAST_ACCT,
419  g_param_spec_boxed("payment-last-account",
420  "Payment Last Account",
421  "The last account to which an payment belonging to "
422  "this owner was posted.",
423  GNC_TYPE_GUID,
424  G_PARAM_READWRITE));
425 }
426 
427 /* Create/Destroy Functions */
428 GncEmployee *gncEmployeeCreate (QofBook *book)
429 {
430  GncEmployee *employee;
431 
432  if (!book) return NULL;
433 
434  employee = g_object_new (GNC_TYPE_EMPLOYEE, NULL);
435  qof_instance_init_data (&employee->inst, _GNC_MOD_NAME, book);
436 
437  employee->id = CACHE_INSERT ("");
438  employee->username = CACHE_INSERT ("");
439  employee->language = CACHE_INSERT ("");
440  employee->acl = CACHE_INSERT ("");
441  employee->addr = gncAddressCreate (book, &employee->inst);
442  employee->workday = gnc_numeric_zero();
443  employee->rate = gnc_numeric_zero();
444  employee->active = TRUE;
445  employee->balance = NULL;
446 
447  if (empl_qof_event_handler_id == 0)
448  empl_qof_event_handler_id = qof_event_register_handler (empl_handle_qof_events, NULL);
449 
450  qof_event_gen (&employee->inst, QOF_EVENT_CREATE, NULL);
451 
452  return employee;
453 }
454 
455 void gncEmployeeDestroy (GncEmployee *employee)
456 {
457  if (!employee) return;
458  qof_instance_set_destroying(employee, TRUE);
459  gncEmployeeCommitEdit(employee);
460 }
461 
462 static void gncEmployeeFree (GncEmployee *employee)
463 {
464  if (!employee) return;
465 
466  qof_event_gen (&employee->inst, QOF_EVENT_DESTROY, NULL);
467 
468  CACHE_REMOVE (employee->id);
469  CACHE_REMOVE (employee->username);
470  CACHE_REMOVE (employee->language);
471  CACHE_REMOVE (employee->acl);
472  gncAddressBeginEdit (employee->addr);
473  gncAddressDestroy (employee->addr);
474  g_free (employee->balance);
475 
476  /* qof_instance_release (&employee->inst); */
477  g_object_unref (employee);
478 }
479 
480 /* ============================================================== */
481 /* Set Functions */
482 
483 #define SET_STR(obj, member, str) { \
484  if (!g_strcmp0 (member, str)) return; \
485  gncEmployeeBeginEdit (obj); \
486  CACHE_REPLACE (member, str); \
487  }
488 
489 void gncEmployeeSetID (GncEmployee *employee, const char *id)
490 {
491  if (!employee) return;
492  if (!id) return;
493  SET_STR(employee, employee->id, id);
494  mark_employee (employee);
495  gncEmployeeCommitEdit (employee);
496 }
497 
498 void gncEmployeeSetUsername (GncEmployee *employee, const char *username)
499 {
500  if (!employee) return;
501  if (!username) return;
502  SET_STR(employee, employee->username, username);
503  mark_employee (employee);
504  gncEmployeeCommitEdit (employee);
505 }
506 
507 /* Employees don't have a name property defined, but
508  * in order to get a consistent interface with other owner types,
509  * this function fakes one by setting the name property of
510  * the employee's address.
511  */
512 void gncEmployeeSetName (GncEmployee *employee, const char *name)
513 {
514  if (!employee) return;
515  if (!name) return;
516  gncAddressSetName (gncEmployeeGetAddr (employee), name);
517 }
518 
519 void gncEmployeeSetLanguage (GncEmployee *employee, const char *language)
520 {
521  if (!employee) return;
522  if (!language) return;
523  SET_STR(employee, employee->language, language);
524  mark_employee (employee);
525  gncEmployeeCommitEdit (employee);
526 }
527 
528 void gncEmployeeSetAcl (GncEmployee *employee, const char *acl)
529 {
530  if (!employee) return;
531  if (!acl) return;
532  SET_STR(employee, employee->acl, acl);
533  mark_employee (employee);
534  gncEmployeeCommitEdit (employee);
535 }
536 
537 void gncEmployeeSetWorkday (GncEmployee *employee, gnc_numeric workday)
538 {
539  if (!employee) return;
540  if (gnc_numeric_equal (workday, employee->workday)) return;
541  gncEmployeeBeginEdit (employee);
542  employee->workday = workday;
543  mark_employee (employee);
544  gncEmployeeCommitEdit (employee);
545 }
546 
547 void gncEmployeeSetRate (GncEmployee *employee, gnc_numeric rate)
548 {
549  if (!employee) return;
550  if (gnc_numeric_equal (rate, employee->rate)) return;
551  gncEmployeeBeginEdit (employee);
552  employee->rate = rate;
553  mark_employee (employee);
554  gncEmployeeCommitEdit (employee);
555 }
556 
557 void gncEmployeeSetCurrency (GncEmployee *employee, gnc_commodity *currency)
558 {
559  if (!employee || !currency) return;
560  if (employee->currency &&
561  gnc_commodity_equal (employee->currency, currency))
562  return;
563  gncEmployeeBeginEdit (employee);
564  employee->currency = currency;
565  mark_employee (employee);
566  gncEmployeeCommitEdit (employee);
567 }
568 
569 void gncEmployeeSetActive (GncEmployee *employee, gboolean active)
570 {
571  if (!employee) return;
572  if (active == employee->active) return;
573  gncEmployeeBeginEdit (employee);
574  employee->active = active;
575  mark_employee (employee);
576  gncEmployeeCommitEdit (employee);
577 }
578 
579 void gncEmployeeSetCCard (GncEmployee *employee, Account* ccard_acc)
580 {
581  if (!employee) return;
582  if (ccard_acc == employee->ccard_acc) return;
583  gncEmployeeBeginEdit (employee);
584  employee->ccard_acc = ccard_acc;
585  mark_employee (employee);
586  gncEmployeeCommitEdit (employee);
587 }
588 
589 void
590 qofEmployeeSetAddr (GncEmployee *employee, QofInstance *addr_ent)
591 {
592  GncAddress *addr;
593 
594  if (!employee || !addr_ent)
595  {
596  return;
597  }
598  addr = (GncAddress*)addr_ent;
599  if (addr == employee->addr)
600  {
601  return;
602  }
603  if (employee->addr != NULL)
604  {
605  gncAddressBeginEdit(employee->addr);
606  gncAddressDestroy(employee->addr);
607  }
608  gncEmployeeBeginEdit(employee);
609  employee->addr = addr;
610  mark_employee (employee);
611  gncEmployeeCommitEdit(employee);
612 }
613 
614 /* ============================================================== */
615 /* Get Functions */
616 const char * gncEmployeeGetID (const GncEmployee *employee)
617 {
618  if (!employee) return NULL;
619  return employee->id;
620 }
621 
622 const char * gncEmployeeGetUsername (const GncEmployee *employee)
623 {
624  if (!employee) return NULL;
625  return employee->username;
626 }
627 
628 /* Employees don't have a name property defined, but
629  * in order to get a consistent interface with other owner types,
630  * this function fakes one by returning the name property of
631  * the employee's address.
632  */
633 const char * gncEmployeeGetName (const GncEmployee *employee)
634 {
635  if (!employee) return NULL;
636  return gncAddressGetName ( gncEmployeeGetAddr (employee));
637 }
638 
639 GncAddress * gncEmployeeGetAddr (const GncEmployee *employee)
640 {
641  if (!employee) return NULL;
642  return employee->addr;
643 }
644 
645 const char * gncEmployeeGetLanguage (const GncEmployee *employee)
646 {
647  if (!employee) return NULL;
648  return employee->language;
649 }
650 
651 const char * gncEmployeeGetAcl (const GncEmployee *employee)
652 {
653  if (!employee) return NULL;
654  return employee->acl;
655 }
656 
657 gnc_numeric gncEmployeeGetWorkday (const GncEmployee *employee)
658 {
659  if (!employee) return gnc_numeric_zero();
660  return employee->workday;
661 }
662 
663 gnc_numeric gncEmployeeGetRate (const GncEmployee *employee)
664 {
665  if (!employee) return gnc_numeric_zero();
666  return employee->rate;
667 }
668 
669 gnc_commodity * gncEmployeeGetCurrency (const GncEmployee *employee)
670 {
671  if (!employee) return NULL;
672  return employee->currency;
673 }
674 
675 gboolean gncEmployeeGetActive (const GncEmployee *employee)
676 {
677  if (!employee) return FALSE;
678  return employee->active;
679 }
680 
681 Account * gncEmployeeGetCCard (const GncEmployee *employee)
682 {
683  if (!employee) return NULL;
684  return employee->ccard_acc;
685 }
686 
687 gboolean gncEmployeeIsDirty (const GncEmployee *employee)
688 {
689  if (!employee) return FALSE;
690  return (qof_instance_get_dirty_flag(employee)
691  || gncAddressIsDirty (employee->addr));
692 }
693 
694 void gncEmployeeBeginEdit (GncEmployee *employee)
695 {
696  qof_begin_edit(&employee->inst);
697 }
698 
699 static void gncEmployeeOnError (QofInstance *employee, QofBackendError errcode)
700 {
701  PERR("Employee QofBackend Failure: %d", errcode);
702  gnc_engine_signal_commit_error( errcode );
703 }
704 
705 static void gncEmployeeOnDone (QofInstance *inst)
706 {
707  GncEmployee *employee = (GncEmployee *) inst;
708  gncAddressClearDirty (employee->addr);
709 }
710 
711 static void emp_free (QofInstance *inst)
712 {
713  GncEmployee *employee = (GncEmployee *) inst;
714  gncEmployeeFree (employee);
715 }
716 
717 
718 void gncEmployeeCommitEdit (GncEmployee *employee)
719 {
720  if (!qof_commit_edit (QOF_INSTANCE(employee))) return;
721  qof_commit_edit_part2 (&employee->inst, gncEmployeeOnError,
722  gncEmployeeOnDone, emp_free);
723 }
724 
725 /* ============================================================== */
726 /* Other functions */
727 
728 int gncEmployeeCompare (const GncEmployee *a, const GncEmployee *b)
729 {
730  if (!a && !b) return 0;
731  if (!a && b) return 1;
732  if (a && !b) return -1;
733 
734  return(strcmp(a->username, b->username));
735 }
736 
737 gboolean gncEmployeeEqual(const GncEmployee* a, const GncEmployee* b)
738 {
739  if (a == NULL && b == NULL) return TRUE;
740  if (a == NULL || b == NULL ) return FALSE;
741 
742  g_return_val_if_fail(GNC_IS_EMPLOYEE(a), FALSE);
743  g_return_val_if_fail(GNC_IS_EMPLOYEE(b), FALSE);
744 
745  if (g_strcmp0(a->id, b->id) != 0)
746  {
747  PWARN("IDs differ: %s vs %s", a->id, b->id);
748  return FALSE;
749  }
750 
751  if (g_strcmp0(a->username, b->username) != 0)
752  {
753  PWARN("Usernames differ: %s vs %s", a->username, b->username);
754  return FALSE;
755  }
756 
757  if (!gncAddressEqual(a->addr, b->addr))
758  {
759  PWARN("Addresses differ");
760  return FALSE;
761  }
762 
763  if (!gnc_commodity_equal(a->currency, b->currency))
764  {
765  PWARN("Currencies differ");
766  return FALSE;
767  }
768 
769  if (a->active != b->active)
770  {
771  PWARN("Active flags differ");
772  return FALSE;
773  }
774 
775  if (g_strcmp0(a->language, b->language) != 0)
776  {
777  PWARN("Languages differ: %s vs %s", a->language, b->language);
778  return FALSE;
779  }
780 
781  if (g_strcmp0(a->acl, b->acl) != 0)
782  {
783  PWARN("ACLs differ: %s vs %s", a->acl, b->acl);
784  return FALSE;
785  }
786 
787  if (!xaccAccountEqual(a->ccard_acc, b->ccard_acc, TRUE))
788  {
789  PWARN("Accounts differ");
790  return FALSE;
791  }
792 
793  if (!gnc_numeric_equal(a->workday, b->workday))
794  {
795  PWARN("Workdays differ");
796  return FALSE;
797  }
798 
799  if (!gnc_numeric_equal(a->rate, b->rate))
800  {
801  PWARN("Rates differ");
802  return FALSE;
803  }
804 
805  return TRUE;
806 }
807 
808 /* Package-Private functions */
809 
810 static const char * _gncEmployeePrintable (gpointer item)
811 {
812  GncEmployee *v = item;
813  if (!item) return NULL;
814  return gncAddressGetName(v->addr);
815 }
816 
829 static void
830 empl_handle_qof_events (QofInstance *entity, QofEventId event_type,
831  gpointer user_data, gpointer event_data)
832 {
833 
834  /* Handle address change events */
835  if ((GNC_IS_ADDRESS (entity) &&
836  (event_type & QOF_EVENT_MODIFY) != 0))
837  {
838  if (GNC_IS_EMPLOYEE (event_data))
839  {
840  GncEmployee* empl = GNC_EMPLOYEE (event_data);
841  gncEmployeeBeginEdit (empl);
842  mark_employee (empl);
843  gncEmployeeCommitEdit (empl);
844  }
845  return;
846  }
847 
848  /* Handle lot change events */
849  if (GNC_IS_LOT (entity))
850  {
851  GNCLot *lot = GNC_LOT (entity);
852  GncOwner lot_owner;
853  const GncOwner *end_owner = NULL;
854  GncInvoice *invoice = gncInvoiceGetInvoiceFromLot (lot);
855 
856  /* Determine the owner associated with the lot */
857  if (invoice)
858  /* Invoice lots */
859  end_owner = gncOwnerGetEndOwner (gncInvoiceGetOwner (invoice));
860  else if (gncOwnerGetOwnerFromLot (lot, &lot_owner))
861  /* Pre-payment lots */
862  end_owner = gncOwnerGetEndOwner (&lot_owner);
863 
864  if (gncOwnerGetType (end_owner) == GNC_OWNER_EMPLOYEE)
865  {
866  /* Clear the cached balance */
867  GncEmployee* empl = gncOwnerGetEmployee (end_owner);
868  g_free (empl->balance);
869  empl->balance = NULL;
870  }
871  return;
872  }
873 }
874 
875 static void
876 destroy_employee_on_book_close(QofInstance *ent, gpointer data)
877 {
878  GncEmployee* e = GNC_EMPLOYEE(ent);
879 
880  gncEmployeeBeginEdit(e);
881  gncEmployeeDestroy(e);
882 }
883 
888 static void
889 gnc_employee_book_end(QofBook* book)
890 {
891  QofCollection *col;
892 
893  col = qof_book_get_collection(book, GNC_ID_EMPLOYEE);
894  qof_collection_foreach(col, destroy_employee_on_book_close, NULL);
895 }
896 
897 static QofObject gncEmployeeDesc =
898 {
899  DI(.interface_version = ) QOF_OBJECT_VERSION,
900  DI(.e_type = ) _GNC_MOD_NAME,
901  DI(.type_label = ) "Employee",
902  DI(.create = ) (gpointer)gncEmployeeCreate,
903  DI(.book_begin = ) NULL,
904  DI(.book_end = ) gnc_employee_book_end,
905  DI(.is_dirty = ) qof_collection_is_dirty,
906  DI(.mark_clean = ) qof_collection_mark_clean,
907  DI(.foreach = ) qof_collection_foreach,
908  DI(.printable = ) _gncEmployeePrintable,
909  DI(.version_cmp = ) (int (*)(gpointer, gpointer)) qof_instance_version_cmp,
910 };
911 
912 gboolean gncEmployeeRegister (void)
913 {
914  static QofParam params[] =
915  {
916  { EMPLOYEE_ID, QOF_TYPE_STRING, (QofAccessFunc)gncEmployeeGetID, (QofSetterFunc)gncEmployeeSetID },
917  {
918  EMPLOYEE_USERNAME, QOF_TYPE_STRING, (QofAccessFunc)gncEmployeeGetUsername,
919  (QofSetterFunc)gncEmployeeSetUsername
920  },
921  {
922  EMPLOYEE_NAME, QOF_TYPE_STRING, (QofAccessFunc)gncEmployeeGetName,
923  (QofSetterFunc)gncEmployeeSetName
924  },
925  {
926  EMPLOYEE_LANGUAGE, QOF_TYPE_STRING, (QofAccessFunc)gncEmployeeGetLanguage,
927  (QofSetterFunc)gncEmployeeSetLanguage
928  },
929  { EMPLOYEE_ACL, QOF_TYPE_STRING, (QofAccessFunc)gncEmployeeGetAcl, (QofSetterFunc)gncEmployeeSetAcl },
930  {
931  EMPLOYEE_WORKDAY, QOF_TYPE_NUMERIC, (QofAccessFunc)gncEmployeeGetWorkday,
932  (QofSetterFunc)gncEmployeeSetWorkday
933  },
934  { EMPLOYEE_RATE, QOF_TYPE_NUMERIC, (QofAccessFunc)gncEmployeeGetRate, (QofSetterFunc)gncEmployeeSetRate },
935  { EMPLOYEE_ADDR, GNC_ID_ADDRESS, (QofAccessFunc)gncEmployeeGetAddr, (QofSetterFunc)qofEmployeeSetAddr },
936  { EMPLOYEE_CC, GNC_ID_ACCOUNT, (QofAccessFunc)gncEmployeeGetCCard, (QofSetterFunc)gncEmployeeSetCCard },
937  { QOF_PARAM_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncEmployeeGetActive, (QofSetterFunc)gncEmployeeSetActive },
938  { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
939  { QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
940  { NULL },
941  };
942 
943  qof_class_register (_GNC_MOD_NAME, (QofSortFunc)gncEmployeeCompare, params);
944 
945  return qof_object_register (&gncEmployeeDesc);
946 }
947 
948 gchar *gncEmployeeNextID (QofBook *book)
949 {
950  return qof_book_increment_and_format_counter (book, _GNC_MOD_NAME);
951 }
952 
953 const gnc_numeric*
954 gncEmployeeGetCachedBalance (GncEmployee *empl)
955 {
956  return empl->balance;
957 }
958 
959 void gncEmployeeSetCachedBalance (GncEmployee *empl, const gnc_numeric *new_bal)
960 {
961  if (!new_bal)
962  {
963  if (empl->balance)
964  {
965  g_free (empl->balance);
966  empl->balance = NULL;
967  }
968  return;
969  }
970 
971  if (!empl->balance)
972  empl->balance = g_new0 (gnc_numeric, 1);
973 
974  *empl->balance = *new_bal;
975 }
int qof_instance_version_cmp(const QofInstance *left, const QofInstance *right)
Compare two instances, based on their last update times.
gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b)
Equivalence predicate: Returns TRUE (1) if a and b represent the same number.
Business Interface: Object OWNERs.
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
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.
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
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.
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
Account handling public routines.
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
gboolean xaccAccountEqual(const Account *aa, const Account *ab, gboolean check_guids)
Compare two accounts for equality - this is a deep compare.
Definition: Account.cpp:1625
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
Employee 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
GncEmployee * gncOwnerGetEmployee(const GncOwner *owner)
If the given owner is of type GNC_OWNER_EMPLOYEE, returns the pointer to the employee object...
Definition: gncOwner.c:391
Commodity handling public routines.
gboolean gncEmployeeEqual(const GncEmployee *a, const GncEmployee *b)
Test support function, used by test-dbi-business-stuff.c.
Definition: gncEmployee.c:737