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