GnuCash  5.6-150-g038405b370+
gncOrder.c
1 /********************************************************************\
2  * gncOrder.c -- the Core Business Order *
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  * Author: Derek Atkins <warlord@MIT.EDU>
26  */
27 
28 #include <config.h>
29 
30 #include <glib.h>
31 #include <glib/gi18n.h>
32 #include <qofinstance-p.h>
33 #include <stdint.h>
34 
35 #include "gncEntry.h"
36 #include "gncEntryP.h"
37 #include "gncOrder.h"
38 #include "gncOrderP.h"
39 #include "gncOwner.h"
40 #include "gncOwnerP.h"
41 
42 struct _gncOrder
43 {
44  QofInstance inst;
45 
46  const char * id;
47  const char * notes;
48  gboolean active;
49 
50  const char * reference;
51  char * printname;
52  GncOwner owner;
53  GList * entries;
54  time64 opened;
55  time64 closed;
56 };
57 
59 {
60  QofInstanceClass parent_class;
61 };
62 
63 static QofLogModule log_module = GNC_MOD_BUSINESS;
64 
65 #define _GNC_MOD_NAME GNC_ID_ORDER
66 
67 #define SET_STR(obj, member, str) { \
68  if (!g_strcmp0 (member, str)) return; \
69  gncOrderBeginEdit (obj); \
70  CACHE_REPLACE (member, str); \
71  }
72 
73 static inline void mark_order (GncOrder *order);
74 void mark_order (GncOrder *order)
75 {
76  qof_instance_set_dirty(&order->inst);
77  qof_event_gen (&order->inst, QOF_EVENT_MODIFY, NULL);
78 }
79 
80 /* =============================================================== */
81 
82 enum
83 {
84  PROP_0,
85  PROP_ID, /* Table */
86  PROP_NOTES, /* Table */
87  PROP_REFERENCE, /* Table */
88  PROP_ACTIVE, /* Table */
89  PROP_DATE_OPENED, /* Table */
90  PROP_DATE_CLOSED, /* Table */
91 // PROP_OWNER_TYPE, /* Table */
92 // PROP_OWNER, /* Table */
93 };
94 
95 /* GObject Initialization */
96 G_DEFINE_TYPE(GncOrder, gnc_order, QOF_TYPE_INSTANCE)
97 
98 static void
99 gnc_order_init(GncOrder* order)
100 {
101  order->closed = INT64_MAX;
102 }
103 
104 static void
105 gnc_order_dispose(GObject *orderp)
106 {
107  G_OBJECT_CLASS(gnc_order_parent_class)->dispose(orderp);
108 }
109 
110 static void
111 gnc_order_finalize(GObject* orderp)
112 {
113  G_OBJECT_CLASS(gnc_order_parent_class)->dispose(orderp);
114 }
115 
116 static void
117 gnc_order_get_property (GObject *object,
118  guint prop_id,
119  GValue *value,
120  GParamSpec *pspec)
121 {
122  GncOrder *priv;
123 
124  g_return_if_fail(GNC_IS_ORDER(object));
125 
126  priv = GNC_ORDER(object);
127  switch (prop_id)
128  {
129  case PROP_ID:
130  g_value_set_string(value, priv->id);
131  break;
132  case PROP_NOTES:
133  g_value_set_string(value, priv->notes);
134  break;
135  case PROP_ACTIVE:
136  g_value_set_boolean(value, priv->active);
137  break;
138  case PROP_DATE_OPENED:
139  g_value_set_boxed(value, &priv->opened);
140  break;
141  case PROP_DATE_CLOSED:
142  g_value_set_boxed(value, &priv->closed);
143  break;
144  case PROP_REFERENCE:
145  g_value_set_string(value, priv->reference);
146  break;
147  default:
148  G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
149  break;
150  }
151 }
152 
153 static void
154 gnc_order_set_property (GObject *object,
155  guint prop_id,
156  const GValue *value,
157  GParamSpec *pspec)
158 {
159  GncOrder *order;
160 
161  g_return_if_fail(GNC_IS_ORDER(object));
162 
163  order = GNC_ORDER(object);
164  g_assert (qof_instance_get_editlevel(order));
165 
166  switch (prop_id)
167  {
168  case PROP_ID:
169  gncOrderSetID(order, g_value_get_string(value));
170  break;
171  case PROP_NOTES:
172  gncOrderSetNotes(order, g_value_get_string(value));
173  break;
174  case PROP_ACTIVE:
175  gncOrderSetActive(order, g_value_get_boolean(value));
176  break;
177  case PROP_DATE_OPENED:
178  gncOrderSetDateOpened(order, g_value_get_int64(value));
179  break;
180  case PROP_DATE_CLOSED:
181  gncOrderSetDateClosed(order, g_value_get_int64(value));
182  break;
183  case PROP_REFERENCE:
184  gncOrderSetReference(order, g_value_get_string(value));
185  break;
186  default:
187  G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
188  break;
189  }
190 }
191 
198 static GList*
199 impl_get_typed_referring_object_list(const QofInstance* inst, const QofInstance* ref)
200 {
201  /* Refers to nothing */
202  return NULL;
203 }
204 
205 static void
206 gnc_order_class_init (GncOrderClass *klass)
207 {
208  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
209  QofInstanceClass* qof_class = QOF_INSTANCE_CLASS(klass);
210 
211  gobject_class->dispose = gnc_order_dispose;
212  gobject_class->finalize = gnc_order_finalize;
213  gobject_class->set_property = gnc_order_set_property;
214  gobject_class->get_property = gnc_order_get_property;
215 
216  qof_class->get_display_name = NULL;
217  qof_class->refers_to_object = NULL;
218  qof_class->get_typed_referring_object_list = impl_get_typed_referring_object_list;
219 
220  g_object_class_install_property
221  (gobject_class,
222  PROP_ID,
223  g_param_spec_string ("id",
224  "Order ID",
225  "The order id is an arbitrary string "
226  "assigned by the user to identify the order.",
227  NULL,
228  G_PARAM_READWRITE));
229 
230  g_object_class_install_property
231  (gobject_class,
232  PROP_NOTES,
233  g_param_spec_string ("notes",
234  "Order Notes",
235  "The order notes is an arbitrary string "
236  "assigned by the user to provide notes about "
237  "this order.",
238  NULL,
239  G_PARAM_READWRITE));
240 
241  g_object_class_install_property
242  (gobject_class,
243  PROP_ACTIVE,
244  g_param_spec_boolean ("active",
245  "Active",
246  "TRUE if the order is active. FALSE if inactive.",
247  FALSE,
248  G_PARAM_READWRITE));
249 
250  g_object_class_install_property
251  (gobject_class,
252  PROP_DATE_OPENED,
253  g_param_spec_boxed("date-opened",
254  "Date Opened",
255  "The date the order was opened.",
256  GNC_TYPE_TIME64,
257  G_PARAM_READWRITE));
258 
259  g_object_class_install_property
260  (gobject_class,
261  PROP_DATE_CLOSED,
262  g_param_spec_boxed("date-closed",
263  "Date Closed",
264  "The date the order was closed.",
265  GNC_TYPE_TIME64,
266  G_PARAM_READWRITE));
267 
268  g_object_class_install_property
269  (gobject_class,
270  PROP_REFERENCE,
271  g_param_spec_string ("reference",
272  "Order Reference",
273  "The order reference is an arbitrary string "
274  "assigned by the user to provide a reference for "
275  "this order.",
276  NULL,
277  G_PARAM_READWRITE));
278 }
279 
280 /* Create/Destroy Functions */
281 GncOrder *gncOrderCreate (QofBook *book)
282 {
283  GncOrder *order;
284 
285  if (!book) return NULL;
286 
287  order = g_object_new (GNC_TYPE_ORDER, NULL);
288  qof_instance_init_data (&order->inst, _GNC_MOD_NAME, book);
289 
290  order->id = CACHE_INSERT ("");
291  order->notes = CACHE_INSERT ("");
292  order->reference = CACHE_INSERT ("");
293 
294  order->active = TRUE;
295 
296  qof_event_gen (&order->inst, QOF_EVENT_CREATE, NULL);
297 
298  return order;
299 }
300 
301 void gncOrderDestroy (GncOrder *order)
302 {
303  if (!order) return;
304  qof_instance_set_destroying(order, TRUE);
305  gncOrderCommitEdit (order);
306 }
307 
308 static void gncOrderFree (GncOrder *order)
309 {
310  if (!order) return;
311 
312  qof_event_gen (&order->inst, QOF_EVENT_DESTROY, NULL);
313 
314  g_list_free (order->entries);
315  CACHE_REMOVE (order->id);
316  CACHE_REMOVE (order->notes);
317  CACHE_REMOVE (order->reference);
318 
319  if (order->printname) g_free (order->printname);
320 
321  /* qof_instance_release (&order->inst); */
322  g_object_unref (order);
323 }
324 
325 /* =============================================================== */
326 /* Set Functions */
327 
328 void gncOrderSetID (GncOrder *order, const char *id)
329 {
330  if (!order || !id) return;
331  SET_STR (order, order->id, id);
332  mark_order (order);
333  gncOrderCommitEdit (order);
334 }
335 
336 void gncOrderSetOwner (GncOrder *order, GncOwner *owner)
337 {
338  if (!order || !owner) return;
339  if (gncOwnerEqual (&order->owner, owner)) return;
340 
341  gncOrderBeginEdit (order);
342  gncOwnerCopy (owner, &order->owner);
343  mark_order (order);
344  gncOrderCommitEdit (order);
345 }
346 
347 void gncOrderSetDateOpened (GncOrder *order, time64 date)
348 {
349  if (!order) return;
350  if (order->opened == date) return;
351  gncOrderBeginEdit (order);
352  order->opened = date;
353  mark_order (order);
354  gncOrderCommitEdit (order);
355 }
356 
357 void gncOrderSetDateClosed (GncOrder *order, time64 date)
358 {
359  if (!order) return;
360  if (order->closed == date) return;
361  gncOrderBeginEdit (order);
362  order->closed = date;
363  mark_order (order);
364  gncOrderCommitEdit (order);
365 }
366 
367 void gncOrderSetNotes (GncOrder *order, const char *notes)
368 {
369  if (!order || !notes) return;
370  SET_STR (order, order->notes, notes);
371  mark_order (order);
372  gncOrderCommitEdit (order);
373 }
374 
375 void gncOrderSetReference (GncOrder *order, const char *reference)
376 {
377  if (!order || !reference) return;
378  SET_STR (order, order->reference, reference);
379  mark_order (order);
380  gncOrderCommitEdit (order);
381 }
382 
383 void gncOrderSetActive (GncOrder *order, gboolean active)
384 {
385  if (!order) return;
386  if (order->active == active) return;
387  gncOrderBeginEdit (order);
388  order->active = active;
389  mark_order (order);
390  gncOrderCommitEdit (order);
391 }
392 
393 /* =============================================================== */
394 /* Add an Entry to the Order */
395 void gncOrderAddEntry (GncOrder *order, GncEntry *entry)
396 {
397  GncOrder *old;
398 
399  if (!order || !entry) return;
400 
401  old = gncEntryGetOrder (entry);
402  if (old == order) return; /* I already own it */
403  if (old) gncOrderRemoveEntry (old, entry);
404 
405  gncOrderBeginEdit (order);
406  order->entries = g_list_insert_sorted (order->entries, entry,
407  (GCompareFunc)gncEntryCompare);
408 
409  /* This will send out an event -- make sure we're attached */
410  gncEntrySetOrder (entry, order);
411  mark_order (order);
412  gncOrderCommitEdit (order);
413 }
414 
415 void gncOrderRemoveEntry (GncOrder *order, GncEntry *entry)
416 {
417  if (!order || !entry) return;
418 
419  gncOrderBeginEdit (order);
420  gncEntrySetOrder (entry, NULL);
421  order->entries = g_list_remove (order->entries, entry);
422  mark_order (order);
423  gncOrderCommitEdit (order);
424 }
425 
426 /* Get Functions */
427 
428 const char * gncOrderGetID (const GncOrder *order)
429 {
430  if (!order) return NULL;
431  return order->id;
432 }
433 
434 GncOwner * gncOrderGetOwner (GncOrder *order)
435 {
436  if (!order) return NULL;
437  return &order->owner;
438 }
439 
440 time64 gncOrderGetDateOpened (const GncOrder *order)
441 {
442  if (!order) return INT64_MAX;
443  return order->opened;
444 }
445 
446 time64 gncOrderGetDateClosed (const GncOrder *order)
447 {
448  if (!order) return INT64_MAX;
449  return order->closed;
450 }
451 
452 const char * gncOrderGetNotes (const GncOrder *order)
453 {
454  if (!order) return NULL;
455  return order->notes;
456 }
457 
458 const char * gncOrderGetReference (const GncOrder *order)
459 {
460  if (!order) return NULL;
461  return order->reference;
462 }
463 
464 gboolean gncOrderGetActive (const GncOrder *order)
465 {
466  if (!order) return FALSE;
467  return order->active;
468 }
469 
470 /* Get the list Entries */
471 GList * gncOrderGetEntries (GncOrder *order)
472 {
473  if (!order) return NULL;
474  return order->entries;
475 }
476 
477 gboolean gncOrderIsClosed (const GncOrder *order)
478 {
479  if (!order) return FALSE;
480  if (order->closed != INT64_MAX) return TRUE;
481  return FALSE;
482 }
483 
484 /* =============================================================== */
485 
486 void gncOrderBeginEdit (GncOrder *order)
487 {
488  qof_begin_edit(&order->inst);
489 }
490 
491 static void gncOrderOnError (QofInstance *order, QofBackendError errcode)
492 {
493  PERR("Order QofBackend Failure: %d", errcode);
494  gnc_engine_signal_commit_error( errcode );
495 }
496 
497 static void gncOrderOnDone (QofInstance *order) {}
498 
499 static void order_free (QofInstance *inst)
500 {
501  GncOrder *order = (GncOrder *) inst;
502  gncOrderFree (order);
503 }
504 
505 void gncOrderCommitEdit (GncOrder *order)
506 {
507  if (!qof_commit_edit (QOF_INSTANCE(order))) return;
508  qof_commit_edit_part2 (&order->inst, gncOrderOnError,
509  gncOrderOnDone, order_free);
510 }
511 
512 int gncOrderCompare (const GncOrder *a, const GncOrder *b)
513 {
514  int compare;
515 
516  if (a == b) return 0;
517  if (!a) return -1;
518  if (!b) return 1;
519 
520  compare = g_strcmp0 (a->id, b->id);
521  if (compare) return compare;
522 
523  if (a->opened != b->opened) return a->opened - b->opened;
524  if (a->closed != b->closed) return a->closed - b->closed;
525 
526  return qof_instance_guid_compare(a, b);
527 }
528 
529 
530 /* =========================================================== */
531 /* Package-Private functions */
532 
533 static const char *
534 _gncOrderPrintable (gpointer obj)
535 {
536  GncOrder *order = obj;
537 
538  g_return_val_if_fail (order, NULL);
539 
540  if (qof_instance_get_dirty_flag(order) || order->printname == NULL)
541  {
542  if (order->printname) g_free (order->printname);
543 
544  order->printname =
545  g_strdup_printf ("%s%s", order->id,
546  gncOrderIsClosed (order) ? _(" (closed)") : "");
547  }
548 
549  return order->printname;
550 }
551 
552 static QofObject gncOrderDesc =
553 {
554  DI(.interface_version = ) QOF_OBJECT_VERSION,
555  DI(.e_type = ) _GNC_MOD_NAME,
556  DI(.type_label = ) "Order",
557  DI(.create = ) (gpointer)gncOrderCreate,
558  DI(.book_begin = ) NULL,
559  DI(.book_end = ) NULL,
560  DI(.is_dirty = ) qof_collection_is_dirty,
561  DI(.mark_clean = ) qof_collection_mark_clean,
562  DI(.foreach = ) qof_collection_foreach,
563  DI(.printable = ) _gncOrderPrintable,
564  DI(.version_cmp = ) (int (*)(gpointer, gpointer)) qof_instance_version_cmp,
565 };
566 
567 gboolean gncOrderRegister (void)
568 {
569  static QofParam params[] =
570  {
571  { ORDER_ID, QOF_TYPE_STRING, (QofAccessFunc)gncOrderGetID, (QofSetterFunc)gncOrderSetID },
572  { ORDER_REFERENCE, QOF_TYPE_STRING, (QofAccessFunc)gncOrderGetReference, (QofSetterFunc)gncOrderSetReference },
573  { ORDER_OWNER, GNC_ID_OWNER, (QofAccessFunc)gncOrderGetOwner, (QofSetterFunc)gncOrderSetOwner },
574  { ORDER_OPENED, QOF_TYPE_DATE, (QofAccessFunc)gncOrderGetDateOpened, (QofSetterFunc)gncOrderSetDateOpened },
575  { ORDER_IS_CLOSED, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncOrderIsClosed, NULL },
576  { ORDER_CLOSED, QOF_TYPE_DATE, (QofAccessFunc)gncOrderGetDateClosed, (QofSetterFunc)gncOrderSetDateClosed },
577  { ORDER_NOTES, QOF_TYPE_STRING, (QofAccessFunc)gncOrderGetNotes, (QofSetterFunc)gncOrderSetNotes },
578  { QOF_PARAM_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncOrderGetActive, (QofSetterFunc)gncOrderSetActive },
579  { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
580  { QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
581  { NULL },
582  };
583 
584  qof_class_register (_GNC_MOD_NAME, (QofSortFunc)gncOrderCompare, params);
585 
586  return qof_object_register (&gncOrderDesc);
587 }
588 
589 gchar *gncOrderNextID (QofBook *book)
590 {
591  return qof_book_increment_and_format_counter (book, _GNC_MOD_NAME);
592 }
int qof_instance_version_cmp(const QofInstance *left, const QofInstance *right)
Compare two instances, based on their last update times.
Business Interface: Object OWNERs.
const GncGUID * qof_instance_get_guid(gconstpointer inst)
Return the GncGUID of this instance.
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:255
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:625
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 gncOwnerEqual(const GncOwner *a, const GncOwner *b)
Assess equality by checking.
Definition: gncOwner.c:404
int(* QofSortFunc)(gconstpointer, gconstpointer)
This function is the default sort function for a particular object type.
Definition: qofclass.h:223
#define QOF_OBJECT_VERSION
Defines the version of the core object object registration interface.
Definition: qofobject.h:63
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:108
void(* QofSetterFunc)(gpointer, gpointer)
The QofSetterFunc defines an function pointer for parameter setters.
Definition: qofclass.h:185
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
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
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
The QofAccessFunc defines an arbitrary function pointer for access functions.
Definition: qofclass.h:178
void qof_collection_mark_clean(QofCollection *)
reset value of dirty flag
Definition: qofid.cpp:261
gint qof_instance_guid_compare(gconstpointer ptr1, gconstpointer ptr2)
Compare the GncGUID values of two instances.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
Definition: gnc-date.h:87
gboolean qof_object_register(const QofObject *object)
Register new types of object objects.
Definition: qofobject.cpp:299
Business Entry Interface.
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