GnuCash c935c2f+
Loading...
Searching...
No Matches
gncJob.c
1/********************************************************************\
2 * gncJob.c -- the Core Job 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 "gnc-features.h"
36#include "gncInvoice.h"
37#include "gncJob.h"
38#include "gncJobP.h"
39#include "gncOwnerP.h"
40
41struct _gncJob
42{
43 QofInstance inst;
44 const char * id;
45 const char * name;
46 const char * desc;
47 GncOwner owner;
48 gboolean active;
49};
50
52{
53 QofInstanceClass parent_class;
54};
55
56static QofLogModule log_module = GNC_MOD_BUSINESS;
57
58#define _GNC_MOD_NAME GNC_ID_JOB
59#define GNC_JOB_RATE "job-rate"
60
61/* ================================================================== */
62/* misc inline functions */
63
64static inline void mark_job (GncJob *job);
65void mark_job (GncJob *job)
66{
67 qof_instance_set_dirty(&job->inst);
68 qof_event_gen (&job->inst, QOF_EVENT_MODIFY, NULL);
69}
70
71/* ================================================================== */
72
73enum
74{
75 PROP_0,
76// PROP_ID, /* Table */
77 PROP_NAME, /* Table */
78// PROP_REFERENCE, /* Table */
79// PROP_ACTIVE, /* Table */
80// PROP_OWNER_TYPE, /* Table */
81// PROP_OWNER, /* Table */
82 PROP_PDF_DIRNAME, /* KVP */
83};
84
85/* GObject Initialization */
86G_DEFINE_TYPE(GncJob, gnc_job, QOF_TYPE_INSTANCE)
87
88static void
89gnc_job_init(GncJob* job)
90{
91}
92
93static void
94gnc_job_dispose(GObject *jobp)
95{
96 G_OBJECT_CLASS(gnc_job_parent_class)->dispose(jobp);
97}
98
99static void
100gnc_job_finalize(GObject* jobp)
101{
102 G_OBJECT_CLASS(gnc_job_parent_class)->finalize(jobp);
103}
104
105static void
106gnc_job_get_property (GObject *object,
107 guint prop_id,
108 GValue *value,
109 GParamSpec *pspec)
110{
111 GncJob *job;
112
113 g_return_if_fail(GNC_IS_JOB(object));
114
115 job = GNC_JOB(object);
116 switch (prop_id)
117 {
118 case PROP_NAME:
119 g_value_set_string(value, job->name);
120 break;
121 case PROP_PDF_DIRNAME:
122 qof_instance_get_kvp (QOF_INSTANCE (job), value, 1, OWNER_EXPORT_PDF_DIRNAME);
123 break;
124 default:
125 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
126 break;
127 }
128}
129
130static void
131gnc_job_set_property (GObject *object,
132 guint prop_id,
133 const GValue *value,
134 GParamSpec *pspec)
135{
136 GncJob *job;
137
138 g_return_if_fail(GNC_IS_JOB(object));
139
140 job = GNC_JOB(object);
141 g_assert (qof_instance_get_editlevel(job));
142
143 switch (prop_id)
144 {
145 case PROP_NAME:
146 gncJobSetName(job, g_value_get_string(value));
147 break;
148 case PROP_PDF_DIRNAME:
149 qof_instance_set_kvp (QOF_INSTANCE (job), value, 1, OWNER_EXPORT_PDF_DIRNAME);
150 break;
151 default:
152 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
153 break;
154 }
155}
156
163static GList*
164impl_get_typed_referring_object_list(const QofInstance* inst, const QofInstance* ref)
165{
166 /* Refers to nothing */
167 return NULL;
168}
169
170static void
171gnc_job_class_init (GncJobClass *klass)
172{
173 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
174 QofInstanceClass* qof_class = QOF_INSTANCE_CLASS(klass);
175
176 gobject_class->dispose = gnc_job_dispose;
177 gobject_class->finalize = gnc_job_finalize;
178 gobject_class->set_property = gnc_job_set_property;
179 gobject_class->get_property = gnc_job_get_property;
180
181 qof_class->get_display_name = NULL;
182 qof_class->refers_to_object = NULL;
183 qof_class->get_typed_referring_object_list = impl_get_typed_referring_object_list;
184
185 g_object_class_install_property
186 (gobject_class,
187 PROP_NAME,
188 g_param_spec_string ("name",
189 "Job Name",
190 "The job name is an arbitrary string "
191 "assigned by the user. It is intended to "
192 "a short character string that is displayed "
193 "by the GUI as the job mnemonic.",
194 NULL,
195 G_PARAM_READWRITE));
196
197 g_object_class_install_property
198 (gobject_class,
199 PROP_PDF_DIRNAME,
200 g_param_spec_string ("export-pdf-dir",
201 "Export PDF Directory Name",
202 "A subdirectory for exporting PDF reports which is "
203 "appended to the target directory when writing them "
204 "out. It is retrieved from preferences and stored on "
205 "each 'Owner' object which prints items after "
206 "printing.",
207 NULL,
208 G_PARAM_READWRITE));
209}
210
211/* Create/Destroy Functions */
212GncJob *gncJobCreate (QofBook *book)
213{
214 GncJob *job;
215
216 if (!book) return NULL;
217
218 job = g_object_new (GNC_TYPE_JOB, NULL);
219 qof_instance_init_data (&job->inst, _GNC_MOD_NAME, book);
220
221 job->id = CACHE_INSERT ("");
222 job->name = CACHE_INSERT ("");
223 job->desc = CACHE_INSERT ("");
224 job->active = TRUE;
225
226 /* GncOwner not initialized */
227 qof_event_gen (&job->inst, QOF_EVENT_CREATE, NULL);
228
229 return job;
230}
231
232static void free_job_list (GncJob *job)
233{
234 gncJobBeginEdit (job);
235 gncJobDestroy (job);
236}
237
238void gncJobFreeList (GList *jobs)
239{
240 GList *job_list = g_list_copy (jobs);
241 g_list_free_full (job_list, (GDestroyNotify)free_job_list);
242}
243
244void gncJobDestroy (GncJob *job)
245{
246 if (!job) return;
247 qof_instance_set_destroying(job, TRUE);
248 gncJobCommitEdit (job);
249}
250
251static void gncJobFree (GncJob *job)
252{
253 if (!job) return;
254
255 qof_event_gen (&job->inst, QOF_EVENT_DESTROY, NULL);
256
257 CACHE_REMOVE (job->id);
258 CACHE_REMOVE (job->name);
259 CACHE_REMOVE (job->desc);
260
261 switch (gncOwnerGetType (&(job->owner)))
262 {
263 case GNC_OWNER_CUSTOMER:
264 gncCustomerRemoveJob (gncOwnerGetCustomer(&job->owner), job);
265 break;
266 case GNC_OWNER_VENDOR:
267 gncVendorRemoveJob (gncOwnerGetVendor(&job->owner), job);
268 break;
269 default:
270 break;
271 }
272
273 /* qof_instance_release (&job->inst); */
274 g_object_unref (job);
275}
276
277
278/* ================================================================== */
279/* Set Functions */
280
281#define SET_STR(obj, member, str) { \
282 if (!g_strcmp0 (member, str)) return; \
283 gncJobBeginEdit (obj); \
284 CACHE_REPLACE (member, str); \
285 }
286
287void gncJobSetID (GncJob *job, const char *id)
288{
289 if (!job) return;
290 if (!id) return;
291 SET_STR(job, job->id, id);
292 mark_job (job);
293 gncJobCommitEdit (job);
294}
295
296void gncJobSetName (GncJob *job, const char *name)
297{
298 if (!job) return;
299 if (!name) return;
300 SET_STR(job, job->name, name);
301 mark_job (job);
302 gncJobCommitEdit (job);
303}
304
305void gncJobSetReference (GncJob *job, const char *desc)
306{
307 if (!job) return;
308 if (!desc) return;
309 SET_STR(job, job->desc, desc);
310 mark_job (job);
311 gncJobCommitEdit (job);
312}
313
314void gncJobSetRate (GncJob *job, gnc_numeric rate)
315{
316 if (!job) return;
317 if (gnc_numeric_equal (gncJobGetRate(job), rate)) return;
318
319 gncJobBeginEdit (job);
320 if (!gnc_numeric_zero_p(rate))
321 {
322 GValue v = G_VALUE_INIT;
323 g_value_init (&v, GNC_TYPE_NUMERIC);
324 g_value_set_boxed (&v, &rate);
325 qof_instance_set_kvp (QOF_INSTANCE (job), &v, 1, GNC_JOB_RATE);
326 g_value_unset (&v);
327 }
328 else
329 {
330 qof_instance_set_kvp (QOF_INSTANCE (job), NULL, 1, GNC_JOB_RATE);
331 }
332 mark_job (job);
333 gncJobCommitEdit (job);
334}
335
336void gncJobSetOwner (GncJob *job, GncOwner *owner)
337{
338 if (!job) return;
339 if (!owner) return;
340 if (gncOwnerEqual (owner, &(job->owner))) return;
341
342 switch (gncOwnerGetType (owner))
343 {
344 case GNC_OWNER_CUSTOMER:
345 case GNC_OWNER_VENDOR:
346 break;
347 default:
348 PERR("Unsupported Owner type: %d", gncOwnerGetType(owner));
349 return;
350 }
351
352 gncJobBeginEdit (job);
353
354 switch (gncOwnerGetType (&(job->owner)))
355 {
356 case GNC_OWNER_CUSTOMER:
357 gncCustomerRemoveJob (gncOwnerGetCustomer(&job->owner), job);
358 break;
359 case GNC_OWNER_VENDOR:
360 gncVendorRemoveJob (gncOwnerGetVendor(&job->owner), job);
361 break;
362 default:
363 break;
364 }
365
366 gncOwnerCopy (owner, &(job->owner));
367
368 switch (gncOwnerGetType (&(job->owner)))
369 {
370 case GNC_OWNER_CUSTOMER:
371 gncCustomerAddJob (gncOwnerGetCustomer(&job->owner), job);
372 break;
373 case GNC_OWNER_VENDOR:
374 gncVendorAddJob (gncOwnerGetVendor(&job->owner), job);
375 break;
376 default:
377 break;
378 }
379
380 mark_job (job);
381 gncJobCommitEdit (job);
382}
383
384void gncJobSetActive (GncJob *job, gboolean active)
385{
386 if (!job) return;
387 if (active == job->active) return;
388 gncJobBeginEdit (job);
389 job->active = active;
390 mark_job (job);
391 gncJobCommitEdit (job);
392}
393
394static void
395qofJobSetOwner (GncJob *job, QofInstance *ent)
396{
397 if (!job || !ent)
398 {
399 return;
400 }
401
402 gncJobBeginEdit (job);
403 qofOwnerSetEntity(&job->owner, ent);
404 mark_job (job);
405 gncJobCommitEdit (job);
406}
407
408void gncJobBeginEdit (GncJob *job)
409{
410 qof_begin_edit(&job->inst);
411}
412
413static void gncJobOnError (QofInstance *inst, QofBackendError errcode)
414{
415 PERR("Job QofBackend Failure: %d", errcode);
416 gnc_engine_signal_commit_error( errcode );
417}
418
419static void job_free (QofInstance *inst)
420{
421 GncJob *job = (GncJob *)inst;
422 gncJobFree (job);
423}
424
425static void gncJobOnDone (QofInstance *qof) { }
426
427void gncJobCommitEdit (GncJob *job)
428{
429 /* GnuCash 2.6.3 and earlier didn't handle job kvp's... */
430 if (qof_instance_has_kvp (QOF_INSTANCE (job)))
431 gnc_features_set_used (qof_instance_get_book (QOF_INSTANCE (job)), GNC_FEATURE_KVP_EXTRA_DATA);
432
433 if (!qof_commit_edit (QOF_INSTANCE(job))) return;
434 qof_commit_edit_part2 (&job->inst, gncJobOnError,
435 gncJobOnDone, job_free);
436}
437
438/* ================================================================== */
439/* Get Functions */
440
441const char * gncJobGetID (const GncJob *job)
442{
443 if (!job) return NULL;
444 return job->id;
445}
446
447const char * gncJobGetName (const GncJob *job)
448{
449 if (!job) return NULL;
450 return job->name;
451}
452
453const char * gncJobGetReference (const GncJob *job)
454{
455 if (!job) return NULL;
456 return job->desc;
457}
458
459gnc_numeric gncJobGetRate (const GncJob *job)
460{
461 GValue v = G_VALUE_INIT;
462 gnc_numeric *rate = NULL;
463 gnc_numeric retval;
464 if (!job) return gnc_numeric_zero ();
465 qof_instance_get_kvp (QOF_INSTANCE (job), &v, 1, GNC_JOB_RATE);
466 if (G_VALUE_HOLDS_BOXED (&v))
467 rate = (gnc_numeric*)g_value_get_boxed (&v);
468 retval = rate ? *rate : gnc_numeric_zero ();
469 g_value_unset (&v);
470 return retval;
471}
472
473GncOwner * gncJobGetOwner (GncJob *job)
474{
475 if (!job) return NULL;
476 return &(job->owner);
477}
478
479gboolean gncJobGetActive (const GncJob *job)
480{
481 if (!job) return FALSE;
482 return job->active;
483}
484
485static QofInstance*
486qofJobGetOwner (GncJob *job)
487{
488 if (!job)
489 {
490 return NULL;
491 }
492 return QOF_INSTANCE(qofOwnerGetOwner(&job->owner));
493}
494
495/* Other functions */
496
497int gncJobCompare (const GncJob * a, const GncJob *b)
498{
499 if (!a && !b) return 0;
500 if (!a && b) return 1;
501 if (a && !b) return -1;
502
503 return (g_strcmp0(a->id, b->id));
504}
505
506gboolean gncJobEqual(const GncJob * a, const GncJob *b)
507{
508 if (a == NULL && b == NULL) return TRUE;
509 if (a == NULL || b == NULL) return FALSE;
510
511 g_return_val_if_fail(GNC_IS_JOB(a), FALSE);
512 g_return_val_if_fail(GNC_IS_JOB(b), FALSE);
513
514 if (g_strcmp0(a->id, b->id) != 0)
515 {
516 PWARN("IDs differ: %s vs %s", a->id, b->id);
517 return FALSE;
518 }
519
520 if (g_strcmp0(a->name, b->name) != 0)
521 {
522 PWARN("Names differ: %s vs %s", a->name, b->name);
523 return FALSE;
524 }
525
526 if (g_strcmp0(a->desc, b->desc) != 0)
527 {
528 PWARN("Descriptions differ: %s vs %s", a->desc, b->desc);
529 return FALSE;
530 }
531
532 if (!gnc_numeric_equal(gncJobGetRate(a), gncJobGetRate(b)))
533 {
534 PWARN("Rates differ");
535 return FALSE;
536 }
537
538 if (a->active != b->active)
539 {
540 PWARN("Active flags differ");
541 return FALSE;
542 }
543
544 /* FIXME: Need real tests */
545#if 0
546 GncOwner owner;
547#endif
548
549 return TRUE;
550}
551
552/* ================================================================== */
553/* Package-Private functions */
554
555static const char * _gncJobPrintable (gpointer item)
556{
557 GncJob *c;
558 if (!item) return NULL;
559 c = item;
560 return c->name;
561}
562
563static QofObject gncJobDesc =
564{
565 DI(.interface_version = ) QOF_OBJECT_VERSION,
566 DI(.e_type = ) _GNC_MOD_NAME,
567 DI(.type_label = ) "Job",
568 DI(.create = ) (gpointer)gncJobCreate,
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 = ) _gncJobPrintable,
575 DI(.version_cmp = ) (int (*)(gpointer, gpointer)) qof_instance_version_cmp,
576};
577
578gboolean gncJobRegister (void)
579{
580 static QofParam params[] =
581 {
582 { JOB_ID, QOF_TYPE_STRING, (QofAccessFunc)gncJobGetID, (QofSetterFunc)gncJobSetID },
583 { JOB_NAME, QOF_TYPE_STRING, (QofAccessFunc)gncJobGetName, (QofSetterFunc)gncJobSetName },
584 { JOB_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncJobGetActive, (QofSetterFunc)gncJobSetActive },
585 { JOB_REFERENCE, QOF_TYPE_STRING, (QofAccessFunc)gncJobGetReference, (QofSetterFunc)gncJobSetReference },
586 { JOB_RATE, QOF_TYPE_NUMERIC, (QofAccessFunc)gncJobGetRate, (QofSetterFunc)gncJobSetRate },
587 { JOB_OWNER, GNC_ID_OWNER, (QofAccessFunc)gncJobGetOwner, NULL },
588 { QOF_PARAM_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncJobGetActive, NULL },
589 { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
590 { QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
591 { NULL },
592 };
593
594 qof_class_register (_GNC_MOD_NAME, (QofSortFunc)gncJobCompare, params);
595 qofJobGetOwner(NULL);
596 qofJobSetOwner(NULL, NULL);
597 return qof_object_register (&gncJobDesc);
598}
599
600gchar *gncJobNextID (QofBook *book)
601{
602 return qof_book_increment_and_format_counter (book, _GNC_MOD_NAME);
603}
Utility functions for file access.
Business Invoice Interface.
Job Interface.
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
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_has_kvp(QofInstance *inst)
Report whether a QofInstance has anything stored in KVP.
void qof_instance_get_kvp(QofInstance *, GValue *value, unsigned count,...)
Retrieves the contents of a KVP slot into a provided GValue.
void qof_instance_set_kvp(QofInstance *, GValue const *value, unsigned count,...)
Sets a KVP slot to a value from a GValue.
#define PERR(format, args...)
Log a serious error.
Definition qoflog.h:244
#define PWARN(format, args...)
Log a warning.
Definition qoflog.h:250
gboolean gnc_numeric_zero_p(gnc_numeric a)
Returns 1 if the given gnc_numeric is 0 (zero), else returns 0.
gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b)
Equivalence predicate: Returns TRUE (1) if a and b represent the same number.
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.
GncCustomer * gncOwnerGetCustomer(const GncOwner *owner)
If the given owner is of type GNC_OWNER_CUSTOMER, returns the pointer to the customer object.
Definition gncOwner.c:369
GncVendor * gncOwnerGetVendor(const GncOwner *owner)
If the given owner is of type GNC_OWNER_VENDOR, returns the pointer to the vendor object.
Definition gncOwner.c:383
gboolean gncOwnerEqual(const GncOwner *a, const GncOwner *b)
Assess equality by checking.
Definition gncOwner.c:404
GncOwnerType gncOwnerGetType(const GncOwner *owner)
Returns the GncOwnerType of this owner.
Definition gncOwner.c:200
QofInstance * qofOwnerGetOwner(const GncOwner *owner)
return the owner itself as an entity.
Definition gncOwner.c:275
void qofOwnerSetEntity(GncOwner *owner, QofInstance *ent)
set the owner from the entity.
Definition gncOwner.c:319
#define QOF_PARAM_BOOK
"Known" Object Parameters – all objects must support these
Definition qofquery.h:108
void gnc_features_set_used(QofBook *book, const gchar *feature)
Indicate that the current book uses the given feature.
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