GnuCash c935c2f+
Loading...
Searching...
No Matches
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
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
63static 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
73static inline void mark_order (GncOrder *order);
74void 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
82enum
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 */
96G_DEFINE_TYPE(GncOrder, gnc_order, QOF_TYPE_INSTANCE)
97
98static void
99gnc_order_init(GncOrder* order)
100{
101 order->closed = INT64_MAX;
102}
103
104static void
105gnc_order_dispose(GObject *orderp)
106{
107 G_OBJECT_CLASS(gnc_order_parent_class)->dispose(orderp);
108}
109
110static void
111gnc_order_finalize(GObject* orderp)
112{
113 G_OBJECT_CLASS(gnc_order_parent_class)->dispose(orderp);
114}
115
116static void
117gnc_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
153static void
154gnc_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
198static GList*
199impl_get_typed_referring_object_list(const QofInstance* inst, const QofInstance* ref)
200{
201 /* Refers to nothing */
202 return NULL;
203}
204
205static void
206gnc_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 */
281GncOrder *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
301void gncOrderDestroy (GncOrder *order)
302{
303 if (!order) return;
304 qof_instance_set_destroying(order, TRUE);
305 gncOrderCommitEdit (order);
306}
307
308static 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
328void 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
336void 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
347void 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
357void 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
367void 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
375void 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
383void 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 */
395void 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
415void 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
428const char * gncOrderGetID (const GncOrder *order)
429{
430 if (!order) return NULL;
431 return order->id;
432}
433
434GncOwner * gncOrderGetOwner (GncOrder *order)
435{
436 if (!order) return NULL;
437 return &order->owner;
438}
439
440time64 gncOrderGetDateOpened (const GncOrder *order)
441{
442 if (!order) return INT64_MAX;
443 return order->opened;
444}
445
446time64 gncOrderGetDateClosed (const GncOrder *order)
447{
448 if (!order) return INT64_MAX;
449 return order->closed;
450}
451
452const char * gncOrderGetNotes (const GncOrder *order)
453{
454 if (!order) return NULL;
455 return order->notes;
456}
457
458const char * gncOrderGetReference (const GncOrder *order)
459{
460 if (!order) return NULL;
461 return order->reference;
462}
463
464gboolean gncOrderGetActive (const GncOrder *order)
465{
466 if (!order) return FALSE;
467 return order->active;
468}
469
470/* Get the list Entries */
471GList * gncOrderGetEntries (GncOrder *order)
472{
473 if (!order) return NULL;
474 return order->entries;
475}
476
477gboolean 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
486void gncOrderBeginEdit (GncOrder *order)
487{
488 qof_begin_edit(&order->inst);
489}
490
491static void gncOrderOnError (QofInstance *order, QofBackendError errcode)
492{
493 PERR("Order QofBackend Failure: %d", errcode);
494 gnc_engine_signal_commit_error( errcode );
495}
496
497static void gncOrderOnDone (QofInstance *order) {}
498
499static void order_free (QofInstance *inst)
500{
501 GncOrder *order = (GncOrder *) inst;
502 gncOrderFree (order);
503}
504
505void 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
512int 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
533static 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
552static 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
567gboolean 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
589gchar *gncOrderNextID (QofBook *book)
590{
591 return qof_book_increment_and_format_counter (book, _GNC_MOD_NAME);
592}
Business Entry Interface.
Business Interface: Object OWNERs.
QofBackendError
The errors that can be reported to the GUI & other front-end users.
Definition qofbackend.h:58
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
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
Definition gnc-date.h:87
gboolean qof_collection_is_dirty(const QofCollection *col)
Return value of 'dirty' flag on collection.
Definition qofid.cpp:232
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
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.
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.
gint qof_instance_guid_compare(gconstpointer ptr1, gconstpointer ptr2)
Compare the GncGUID values of two instances.
#define PERR(format, args...)
Log a serious error.
Definition qoflog.h:244
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 gncOwnerEqual(const GncOwner *a, const GncOwner *b)
Assess equality by checking.
Definition gncOwner.c:404
#define QOF_PARAM_BOOK
"Known" Object Parameters – all objects must support these
Definition qofquery.h:108
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
QofBook reference.
Definition qofbook-p.hpp:47