mirror of
https://github.com/Gnucash/gnucash.git
synced 2024-11-29 12:14:31 -06:00
3360a6d13b
Courtesy of gcc -pedantic
593 lines
17 KiB
C
593 lines
17 KiB
C
/********************************************************************\
|
|
* gncOrder.c -- the Core Business Order *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or *
|
|
* modify it under the terms of the GNU General Public License as *
|
|
* published by the Free Software Foundation; either version 2 of *
|
|
* the License, or (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License*
|
|
* along with this program; if not, contact: *
|
|
* *
|
|
* Free Software Foundation Voice: +1-617-542-5942 *
|
|
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
|
|
* Boston, MA 02110-1301, USA gnu@gnu.org *
|
|
* *
|
|
\********************************************************************/
|
|
|
|
/*
|
|
* Copyright (C) 2001,2002 Derek Atkins
|
|
* Author: Derek Atkins <warlord@MIT.EDU>
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include <glib.h>
|
|
#include <glib/gi18n.h>
|
|
#include <qofinstance-p.h>
|
|
#include <stdint.h>
|
|
|
|
#include "gncEntry.h"
|
|
#include "gncEntryP.h"
|
|
#include "gncOrder.h"
|
|
#include "gncOrderP.h"
|
|
#include "gncOwner.h"
|
|
#include "gncOwnerP.h"
|
|
|
|
struct _gncOrder
|
|
{
|
|
QofInstance inst;
|
|
|
|
const char * id;
|
|
const char * notes;
|
|
gboolean active;
|
|
|
|
const char * reference;
|
|
char * printname;
|
|
GncOwner owner;
|
|
GList * entries;
|
|
time64 opened;
|
|
time64 closed;
|
|
};
|
|
|
|
struct _gncOrderClass
|
|
{
|
|
QofInstanceClass parent_class;
|
|
};
|
|
|
|
static QofLogModule log_module = GNC_MOD_BUSINESS;
|
|
|
|
#define _GNC_MOD_NAME GNC_ID_ORDER
|
|
|
|
#define SET_STR(obj, member, str) { \
|
|
if (!g_strcmp0 (member, str)) return; \
|
|
gncOrderBeginEdit (obj); \
|
|
CACHE_REPLACE (member, str); \
|
|
}
|
|
|
|
static inline void mark_order (GncOrder *order);
|
|
void mark_order (GncOrder *order)
|
|
{
|
|
qof_instance_set_dirty(&order->inst);
|
|
qof_event_gen (&order->inst, QOF_EVENT_MODIFY, NULL);
|
|
}
|
|
|
|
/* =============================================================== */
|
|
|
|
enum
|
|
{
|
|
PROP_0,
|
|
PROP_ID, /* Table */
|
|
PROP_NOTES, /* Table */
|
|
PROP_REFERENCE, /* Table */
|
|
PROP_ACTIVE, /* Table */
|
|
PROP_DATE_OPENED, /* Table */
|
|
PROP_DATE_CLOSED, /* Table */
|
|
// PROP_OWNER_TYPE, /* Table */
|
|
// PROP_OWNER, /* Table */
|
|
};
|
|
|
|
/* GObject Initialization */
|
|
G_DEFINE_TYPE(GncOrder, gnc_order, QOF_TYPE_INSTANCE)
|
|
|
|
static void
|
|
gnc_order_init(GncOrder* order)
|
|
{
|
|
order->closed = INT64_MAX;
|
|
}
|
|
|
|
static void
|
|
gnc_order_dispose(GObject *orderp)
|
|
{
|
|
G_OBJECT_CLASS(gnc_order_parent_class)->dispose(orderp);
|
|
}
|
|
|
|
static void
|
|
gnc_order_finalize(GObject* orderp)
|
|
{
|
|
G_OBJECT_CLASS(gnc_order_parent_class)->dispose(orderp);
|
|
}
|
|
|
|
static void
|
|
gnc_order_get_property (GObject *object,
|
|
guint prop_id,
|
|
GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
GncOrder *priv;
|
|
|
|
g_return_if_fail(GNC_IS_ORDER(object));
|
|
|
|
priv = GNC_ORDER(object);
|
|
switch (prop_id)
|
|
{
|
|
case PROP_ID:
|
|
g_value_set_string(value, priv->id);
|
|
break;
|
|
case PROP_NOTES:
|
|
g_value_set_string(value, priv->notes);
|
|
break;
|
|
case PROP_ACTIVE:
|
|
g_value_set_boolean(value, priv->active);
|
|
break;
|
|
case PROP_DATE_OPENED:
|
|
g_value_set_boxed(value, &priv->opened);
|
|
break;
|
|
case PROP_DATE_CLOSED:
|
|
g_value_set_boxed(value, &priv->closed);
|
|
break;
|
|
case PROP_REFERENCE:
|
|
g_value_set_string(value, priv->reference);
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gnc_order_set_property (GObject *object,
|
|
guint prop_id,
|
|
const GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
GncOrder *order;
|
|
|
|
g_return_if_fail(GNC_IS_ORDER(object));
|
|
|
|
order = GNC_ORDER(object);
|
|
g_assert (qof_instance_get_editlevel(order));
|
|
|
|
switch (prop_id)
|
|
{
|
|
case PROP_ID:
|
|
gncOrderSetID(order, g_value_get_string(value));
|
|
break;
|
|
case PROP_NOTES:
|
|
gncOrderSetNotes(order, g_value_get_string(value));
|
|
break;
|
|
case PROP_ACTIVE:
|
|
gncOrderSetActive(order, g_value_get_boolean(value));
|
|
break;
|
|
case PROP_DATE_OPENED:
|
|
gncOrderSetDateOpened(order, g_value_get_int64(value));
|
|
break;
|
|
case PROP_DATE_CLOSED:
|
|
gncOrderSetDateClosed(order, g_value_get_int64(value));
|
|
break;
|
|
case PROP_REFERENCE:
|
|
gncOrderSetReference(order, g_value_get_string(value));
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/** Returns a list of my type of object which refers to an object. For example, when called as
|
|
qof_instance_get_typed_referring_object_list(taxtable, account);
|
|
it will return the list of taxtables which refer to a specific account. The result should be the
|
|
same regardless of which taxtable object is used. The list must be freed by the caller but the
|
|
objects on the list must not.
|
|
*/
|
|
static GList*
|
|
impl_get_typed_referring_object_list(const QofInstance* inst, const QofInstance* ref)
|
|
{
|
|
/* Refers to nothing */
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
gnc_order_class_init (GncOrderClass *klass)
|
|
{
|
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
|
QofInstanceClass* qof_class = QOF_INSTANCE_CLASS(klass);
|
|
|
|
gobject_class->dispose = gnc_order_dispose;
|
|
gobject_class->finalize = gnc_order_finalize;
|
|
gobject_class->set_property = gnc_order_set_property;
|
|
gobject_class->get_property = gnc_order_get_property;
|
|
|
|
qof_class->get_display_name = NULL;
|
|
qof_class->refers_to_object = NULL;
|
|
qof_class->get_typed_referring_object_list = impl_get_typed_referring_object_list;
|
|
|
|
g_object_class_install_property
|
|
(gobject_class,
|
|
PROP_ID,
|
|
g_param_spec_string ("id",
|
|
"Order ID",
|
|
"The order id is an arbitrary string "
|
|
"assigned by the user to identify the order.",
|
|
NULL,
|
|
G_PARAM_READWRITE));
|
|
|
|
g_object_class_install_property
|
|
(gobject_class,
|
|
PROP_NOTES,
|
|
g_param_spec_string ("notes",
|
|
"Order Notes",
|
|
"The order notes is an arbitrary string "
|
|
"assigned by the user to provide notes about "
|
|
"this order.",
|
|
NULL,
|
|
G_PARAM_READWRITE));
|
|
|
|
g_object_class_install_property
|
|
(gobject_class,
|
|
PROP_ACTIVE,
|
|
g_param_spec_boolean ("active",
|
|
"Active",
|
|
"TRUE if the order is active. FALSE if inactive.",
|
|
FALSE,
|
|
G_PARAM_READWRITE));
|
|
|
|
g_object_class_install_property
|
|
(gobject_class,
|
|
PROP_DATE_OPENED,
|
|
g_param_spec_boxed("date-opened",
|
|
"Date Opened",
|
|
"The date the order was opened.",
|
|
GNC_TYPE_TIME64,
|
|
G_PARAM_READWRITE));
|
|
|
|
g_object_class_install_property
|
|
(gobject_class,
|
|
PROP_DATE_CLOSED,
|
|
g_param_spec_boxed("date-closed",
|
|
"Date Closed",
|
|
"The date the order was closed.",
|
|
GNC_TYPE_TIME64,
|
|
G_PARAM_READWRITE));
|
|
|
|
g_object_class_install_property
|
|
(gobject_class,
|
|
PROP_REFERENCE,
|
|
g_param_spec_string ("reference",
|
|
"Order Reference",
|
|
"The order reference is an arbitrary string "
|
|
"assigned by the user to provide a reference for "
|
|
"this order.",
|
|
NULL,
|
|
G_PARAM_READWRITE));
|
|
}
|
|
|
|
/* Create/Destroy Functions */
|
|
GncOrder *gncOrderCreate (QofBook *book)
|
|
{
|
|
GncOrder *order;
|
|
|
|
if (!book) return NULL;
|
|
|
|
order = g_object_new (GNC_TYPE_ORDER, NULL);
|
|
qof_instance_init_data (&order->inst, _GNC_MOD_NAME, book);
|
|
|
|
order->id = CACHE_INSERT ("");
|
|
order->notes = CACHE_INSERT ("");
|
|
order->reference = CACHE_INSERT ("");
|
|
|
|
order->active = TRUE;
|
|
|
|
qof_event_gen (&order->inst, QOF_EVENT_CREATE, NULL);
|
|
|
|
return order;
|
|
}
|
|
|
|
void gncOrderDestroy (GncOrder *order)
|
|
{
|
|
if (!order) return;
|
|
qof_instance_set_destroying(order, TRUE);
|
|
gncOrderCommitEdit (order);
|
|
}
|
|
|
|
static void gncOrderFree (GncOrder *order)
|
|
{
|
|
if (!order) return;
|
|
|
|
qof_event_gen (&order->inst, QOF_EVENT_DESTROY, NULL);
|
|
|
|
g_list_free (order->entries);
|
|
CACHE_REMOVE (order->id);
|
|
CACHE_REMOVE (order->notes);
|
|
CACHE_REMOVE (order->reference);
|
|
|
|
if (order->printname) g_free (order->printname);
|
|
|
|
/* qof_instance_release (&order->inst); */
|
|
g_object_unref (order);
|
|
}
|
|
|
|
/* =============================================================== */
|
|
/* Set Functions */
|
|
|
|
void gncOrderSetID (GncOrder *order, const char *id)
|
|
{
|
|
if (!order || !id) return;
|
|
SET_STR (order, order->id, id);
|
|
mark_order (order);
|
|
gncOrderCommitEdit (order);
|
|
}
|
|
|
|
void gncOrderSetOwner (GncOrder *order, GncOwner *owner)
|
|
{
|
|
if (!order || !owner) return;
|
|
if (gncOwnerEqual (&order->owner, owner)) return;
|
|
|
|
gncOrderBeginEdit (order);
|
|
gncOwnerCopy (owner, &order->owner);
|
|
mark_order (order);
|
|
gncOrderCommitEdit (order);
|
|
}
|
|
|
|
void gncOrderSetDateOpened (GncOrder *order, time64 date)
|
|
{
|
|
if (!order) return;
|
|
if (order->opened == date) return;
|
|
gncOrderBeginEdit (order);
|
|
order->opened = date;
|
|
mark_order (order);
|
|
gncOrderCommitEdit (order);
|
|
}
|
|
|
|
void gncOrderSetDateClosed (GncOrder *order, time64 date)
|
|
{
|
|
if (!order) return;
|
|
if (order->closed == date) return;
|
|
gncOrderBeginEdit (order);
|
|
order->closed = date;
|
|
mark_order (order);
|
|
gncOrderCommitEdit (order);
|
|
}
|
|
|
|
void gncOrderSetNotes (GncOrder *order, const char *notes)
|
|
{
|
|
if (!order || !notes) return;
|
|
SET_STR (order, order->notes, notes);
|
|
mark_order (order);
|
|
gncOrderCommitEdit (order);
|
|
}
|
|
|
|
void gncOrderSetReference (GncOrder *order, const char *reference)
|
|
{
|
|
if (!order || !reference) return;
|
|
SET_STR (order, order->reference, reference);
|
|
mark_order (order);
|
|
gncOrderCommitEdit (order);
|
|
}
|
|
|
|
void gncOrderSetActive (GncOrder *order, gboolean active)
|
|
{
|
|
if (!order) return;
|
|
if (order->active == active) return;
|
|
gncOrderBeginEdit (order);
|
|
order->active = active;
|
|
mark_order (order);
|
|
gncOrderCommitEdit (order);
|
|
}
|
|
|
|
/* =============================================================== */
|
|
/* Add an Entry to the Order */
|
|
void gncOrderAddEntry (GncOrder *order, GncEntry *entry)
|
|
{
|
|
GncOrder *old;
|
|
|
|
if (!order || !entry) return;
|
|
|
|
old = gncEntryGetOrder (entry);
|
|
if (old == order) return; /* I already own it */
|
|
if (old) gncOrderRemoveEntry (old, entry);
|
|
|
|
gncOrderBeginEdit (order);
|
|
order->entries = g_list_insert_sorted (order->entries, entry,
|
|
(GCompareFunc)gncEntryCompare);
|
|
|
|
/* This will send out an event -- make sure we're attached */
|
|
gncEntrySetOrder (entry, order);
|
|
mark_order (order);
|
|
gncOrderCommitEdit (order);
|
|
}
|
|
|
|
void gncOrderRemoveEntry (GncOrder *order, GncEntry *entry)
|
|
{
|
|
if (!order || !entry) return;
|
|
|
|
gncOrderBeginEdit (order);
|
|
gncEntrySetOrder (entry, NULL);
|
|
order->entries = g_list_remove (order->entries, entry);
|
|
mark_order (order);
|
|
gncOrderCommitEdit (order);
|
|
}
|
|
|
|
/* Get Functions */
|
|
|
|
const char * gncOrderGetID (const GncOrder *order)
|
|
{
|
|
if (!order) return NULL;
|
|
return order->id;
|
|
}
|
|
|
|
GncOwner * gncOrderGetOwner (GncOrder *order)
|
|
{
|
|
if (!order) return NULL;
|
|
return &order->owner;
|
|
}
|
|
|
|
time64 gncOrderGetDateOpened (const GncOrder *order)
|
|
{
|
|
if (!order) return INT64_MAX;
|
|
return order->opened;
|
|
}
|
|
|
|
time64 gncOrderGetDateClosed (const GncOrder *order)
|
|
{
|
|
if (!order) return INT64_MAX;
|
|
return order->closed;
|
|
}
|
|
|
|
const char * gncOrderGetNotes (const GncOrder *order)
|
|
{
|
|
if (!order) return NULL;
|
|
return order->notes;
|
|
}
|
|
|
|
const char * gncOrderGetReference (const GncOrder *order)
|
|
{
|
|
if (!order) return NULL;
|
|
return order->reference;
|
|
}
|
|
|
|
gboolean gncOrderGetActive (const GncOrder *order)
|
|
{
|
|
if (!order) return FALSE;
|
|
return order->active;
|
|
}
|
|
|
|
/* Get the list Entries */
|
|
GList * gncOrderGetEntries (GncOrder *order)
|
|
{
|
|
if (!order) return NULL;
|
|
return order->entries;
|
|
}
|
|
|
|
gboolean gncOrderIsClosed (const GncOrder *order)
|
|
{
|
|
if (!order) return FALSE;
|
|
if (order->closed != INT64_MAX) return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
/* =============================================================== */
|
|
|
|
void gncOrderBeginEdit (GncOrder *order)
|
|
{
|
|
qof_begin_edit(&order->inst);
|
|
}
|
|
|
|
static void gncOrderOnError (QofInstance *order, QofBackendError errcode)
|
|
{
|
|
PERR("Order QofBackend Failure: %d", errcode);
|
|
gnc_engine_signal_commit_error( errcode );
|
|
}
|
|
|
|
static void gncOrderOnDone (QofInstance *order) {}
|
|
|
|
static void order_free (QofInstance *inst)
|
|
{
|
|
GncOrder *order = (GncOrder *) inst;
|
|
gncOrderFree (order);
|
|
}
|
|
|
|
void gncOrderCommitEdit (GncOrder *order)
|
|
{
|
|
if (!qof_commit_edit (QOF_INSTANCE(order))) return;
|
|
qof_commit_edit_part2 (&order->inst, gncOrderOnError,
|
|
gncOrderOnDone, order_free);
|
|
}
|
|
|
|
int gncOrderCompare (const GncOrder *a, const GncOrder *b)
|
|
{
|
|
int compare;
|
|
|
|
if (a == b) return 0;
|
|
if (!a) return -1;
|
|
if (!b) return 1;
|
|
|
|
compare = g_strcmp0 (a->id, b->id);
|
|
if (compare) return compare;
|
|
|
|
if (a->opened != b->opened) return a->opened - b->opened;
|
|
if (a->closed != b->closed) return a->closed - b->closed;
|
|
|
|
return qof_instance_guid_compare(a, b);
|
|
}
|
|
|
|
|
|
/* =========================================================== */
|
|
/* Package-Private functions */
|
|
|
|
static const char *
|
|
_gncOrderPrintable (gpointer obj)
|
|
{
|
|
GncOrder *order = obj;
|
|
|
|
g_return_val_if_fail (order, NULL);
|
|
|
|
if (qof_instance_get_dirty_flag(order) || order->printname == NULL)
|
|
{
|
|
if (order->printname) g_free (order->printname);
|
|
|
|
order->printname =
|
|
g_strdup_printf ("%s%s", order->id,
|
|
gncOrderIsClosed (order) ? _(" (closed)") : "");
|
|
}
|
|
|
|
return order->printname;
|
|
}
|
|
|
|
static QofObject gncOrderDesc =
|
|
{
|
|
DI(.interface_version = ) QOF_OBJECT_VERSION,
|
|
DI(.e_type = ) _GNC_MOD_NAME,
|
|
DI(.type_label = ) "Order",
|
|
DI(.create = ) (gpointer)gncOrderCreate,
|
|
DI(.book_begin = ) NULL,
|
|
DI(.book_end = ) NULL,
|
|
DI(.is_dirty = ) qof_collection_is_dirty,
|
|
DI(.mark_clean = ) qof_collection_mark_clean,
|
|
DI(.foreach = ) qof_collection_foreach,
|
|
DI(.printable = ) _gncOrderPrintable,
|
|
DI(.version_cmp = ) (int (*)(gpointer, gpointer)) qof_instance_version_cmp,
|
|
};
|
|
|
|
gboolean gncOrderRegister (void)
|
|
{
|
|
static QofParam params[] =
|
|
{
|
|
{ ORDER_ID, QOF_TYPE_STRING, (QofAccessFunc)gncOrderGetID, (QofSetterFunc)gncOrderSetID },
|
|
{ ORDER_REFERENCE, QOF_TYPE_STRING, (QofAccessFunc)gncOrderGetReference, (QofSetterFunc)gncOrderSetReference },
|
|
{ ORDER_OWNER, GNC_ID_OWNER, (QofAccessFunc)gncOrderGetOwner, (QofSetterFunc)gncOrderSetOwner },
|
|
{ ORDER_OPENED, QOF_TYPE_DATE, (QofAccessFunc)gncOrderGetDateOpened, (QofSetterFunc)gncOrderSetDateOpened },
|
|
{ ORDER_IS_CLOSED, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncOrderIsClosed, NULL },
|
|
{ ORDER_CLOSED, QOF_TYPE_DATE, (QofAccessFunc)gncOrderGetDateClosed, (QofSetterFunc)gncOrderSetDateClosed },
|
|
{ ORDER_NOTES, QOF_TYPE_STRING, (QofAccessFunc)gncOrderGetNotes, (QofSetterFunc)gncOrderSetNotes },
|
|
{ QOF_PARAM_ACTIVE, QOF_TYPE_BOOLEAN, (QofAccessFunc)gncOrderGetActive, (QofSetterFunc)gncOrderSetActive },
|
|
{ QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
|
|
{ QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
|
|
{ NULL },
|
|
};
|
|
|
|
qof_class_register (_GNC_MOD_NAME, (QofSortFunc)gncOrderCompare, params);
|
|
|
|
return qof_object_register (&gncOrderDesc);
|
|
}
|
|
|
|
gchar *gncOrderNextID (QofBook *book)
|
|
{
|
|
return qof_book_increment_and_format_counter (book, _GNC_MOD_NAME);
|
|
}
|