2002-06-21 11:44:30 -05:00
|
|
|
/*
|
|
|
|
* gncBillTerm.c -- the Gnucash Billing Terms interface
|
|
|
|
* Copyright (C) 2002 Derek Atkins
|
|
|
|
* Author: Derek Atkins <warlord@MIT.EDU>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include <glib.h>
|
|
|
|
|
|
|
|
#include "messages.h"
|
|
|
|
#include "gnc-numeric.h"
|
2003-06-26 02:27:52 -05:00
|
|
|
#include "gnc-engine.h"
|
2002-06-21 11:44:30 -05:00
|
|
|
#include "gnc-engine-util.h"
|
2003-06-26 22:36:02 -05:00
|
|
|
#include "qofquerycore.h"
|
2002-06-21 11:44:30 -05:00
|
|
|
#include "gnc-event-p.h"
|
2002-11-03 14:21:42 -06:00
|
|
|
#include "gnc-be-utils.h"
|
2003-10-11 16:06:34 -05:00
|
|
|
#include "kvp_frame.h"
|
2003-06-26 22:36:02 -05:00
|
|
|
#include "qofbook.h"
|
2003-10-11 16:06:34 -05:00
|
|
|
#include "qofclass.h"
|
2003-06-26 22:36:02 -05:00
|
|
|
#include "qofid.h"
|
2003-06-26 02:27:52 -05:00
|
|
|
#include "qofid-p.h"
|
2003-10-11 16:06:34 -05:00
|
|
|
#include "qofinstance.h"
|
2003-06-26 22:36:02 -05:00
|
|
|
#include "qofquery.h"
|
2002-06-21 11:44:30 -05:00
|
|
|
|
|
|
|
#include "gncBusiness.h"
|
|
|
|
#include "gncBillTermP.h"
|
|
|
|
|
|
|
|
|
2003-10-11 20:49:08 -05:00
|
|
|
struct _gncBillTerm
|
|
|
|
{
|
|
|
|
QofInstance inst;
|
|
|
|
char * name;
|
|
|
|
char * desc;
|
|
|
|
GncBillTermType type;
|
|
|
|
gint due_days;
|
|
|
|
gint disc_days;
|
|
|
|
gnc_numeric discount;
|
|
|
|
gint cutoff;
|
|
|
|
|
|
|
|
gint64 refcount;
|
|
|
|
GncBillTerm * parent; /* if non-null, we are an immutable child */
|
|
|
|
GncBillTerm * child; /* if non-null, we have not changed */
|
|
|
|
gboolean invisible;
|
|
|
|
|
|
|
|
GList * children; /* list of children for disconnection */
|
2002-06-21 11:44:30 -05:00
|
|
|
};
|
|
|
|
|
2003-10-11 20:49:08 -05:00
|
|
|
struct _book_info
|
|
|
|
{
|
|
|
|
GncBookInfo bi;
|
|
|
|
GList * terms; /* visible terms */
|
2002-06-21 11:44:30 -05:00
|
|
|
};
|
|
|
|
|
2003-10-11 20:49:08 -05:00
|
|
|
static short module = MOD_BUSINESS;
|
2002-11-03 14:21:42 -06:00
|
|
|
|
2003-10-11 20:49:08 -05:00
|
|
|
#define _GNC_MOD_NAME GNC_BILLTERM_MODULE_NAME
|
2002-06-21 11:44:30 -05:00
|
|
|
|
|
|
|
#define CACHE_INSERT(str) g_cache_insert(gnc_engine_get_string_cache(), (gpointer)(str));
|
|
|
|
#define CACHE_REMOVE(str) g_cache_remove(gnc_engine_get_string_cache(), (str));
|
|
|
|
|
2002-11-03 18:41:01 -06:00
|
|
|
#define SET_STR(obj, member, str) { \
|
2003-10-11 20:49:08 -05:00
|
|
|
char * tmp; \
|
|
|
|
\
|
|
|
|
if (!safe_strcmp (member, str)) return; \
|
|
|
|
gncBillTermBeginEdit (obj); \
|
|
|
|
tmp = CACHE_INSERT (str); \
|
|
|
|
CACHE_REMOVE (member); \
|
|
|
|
member = tmp; \
|
|
|
|
}
|
2002-06-21 11:44:30 -05:00
|
|
|
|
|
|
|
static void add_or_rem_object (GncBillTerm *term, gboolean add);
|
2002-06-22 20:23:28 -05:00
|
|
|
static void maybe_resort_list (GncBillTerm *term);
|
2002-06-21 11:44:30 -05:00
|
|
|
|
2003-07-09 22:18:17 -05:00
|
|
|
static void gncBillTermRemoveChild (GncBillTerm *table, GncBillTerm *child);
|
|
|
|
|
2002-06-21 11:44:30 -05:00
|
|
|
G_INLINE_FUNC void mark_term (GncBillTerm *term);
|
|
|
|
G_INLINE_FUNC void
|
|
|
|
mark_term (GncBillTerm *term)
|
|
|
|
{
|
2003-10-11 20:49:08 -05:00
|
|
|
term->inst.dirty = TRUE;
|
|
|
|
gncBusinessSetDirtyFlag (term->inst.book, _GNC_MOD_NAME, TRUE);
|
|
|
|
|
|
|
|
gnc_engine_generate_event (&term->inst.guid, _GNC_MOD_NAME, GNC_EVENT_MODIFY);
|
|
|
|
}
|
2002-06-21 11:44:30 -05:00
|
|
|
|
2003-10-11 20:49:08 -05:00
|
|
|
static inline void addObj (GncBillTerm *term)
|
|
|
|
{
|
|
|
|
gncBusinessAddObject (term->inst.book, _GNC_MOD_NAME, term, &term->inst.guid);
|
|
|
|
add_or_rem_object (term, TRUE);
|
2002-06-21 11:44:30 -05:00
|
|
|
}
|
|
|
|
|
2003-10-11 20:49:08 -05:00
|
|
|
static inline void remObj (GncBillTerm *term)
|
|
|
|
{
|
|
|
|
gncBusinessRemoveObject (term->inst.book, _GNC_MOD_NAME, &term->inst.guid);
|
|
|
|
add_or_rem_object (term, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-06-21 11:44:30 -05:00
|
|
|
/* Create/Destroy Functions */
|
2003-06-26 22:05:25 -05:00
|
|
|
GncBillTerm * gncBillTermCreate (QofBook *book)
|
2002-06-21 11:44:30 -05:00
|
|
|
{
|
|
|
|
GncBillTerm *term;
|
|
|
|
if (!book) return NULL;
|
|
|
|
|
|
|
|
term = g_new0 (GncBillTerm, 1);
|
2003-10-11 17:46:12 -05:00
|
|
|
qof_instance_init(&term->inst, book);
|
2002-06-21 11:44:30 -05:00
|
|
|
term->name = CACHE_INSERT ("");
|
|
|
|
term->desc = CACHE_INSERT ("");
|
|
|
|
term->discount = gnc_numeric_zero ();
|
|
|
|
addObj (term);
|
2003-10-11 20:49:08 -05:00
|
|
|
gnc_engine_generate_event (&term->inst.guid, _GNC_MOD_NAME, GNC_EVENT_CREATE);
|
2002-06-21 11:44:30 -05:00
|
|
|
return term;
|
|
|
|
}
|
|
|
|
|
|
|
|
void gncBillTermDestroy (GncBillTerm *term)
|
2002-11-03 14:21:42 -06:00
|
|
|
{
|
|
|
|
if (!term) return;
|
2003-10-11 20:49:08 -05:00
|
|
|
term->inst.do_free = TRUE;
|
|
|
|
gncBusinessSetDirtyFlag (term->inst.book, _GNC_MOD_NAME, TRUE);
|
2002-11-03 14:21:42 -06:00
|
|
|
gncBillTermCommitEdit (term);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void gncBillTermFree (GncBillTerm *term)
|
2002-06-21 11:44:30 -05:00
|
|
|
{
|
2003-06-14 00:17:07 -05:00
|
|
|
GncBillTerm *child;
|
|
|
|
GList *list;
|
|
|
|
|
2002-06-21 11:44:30 -05:00
|
|
|
if (!term) return;
|
|
|
|
|
2003-10-11 20:49:08 -05:00
|
|
|
gnc_engine_generate_event (&term->inst.guid, _GNC_MOD_NAME, GNC_EVENT_DESTROY);
|
2002-06-21 11:44:30 -05:00
|
|
|
CACHE_REMOVE (term->name);
|
|
|
|
CACHE_REMOVE (term->desc);
|
2003-10-11 16:06:34 -05:00
|
|
|
qof_instance_release(&term->inst);
|
2002-06-21 11:44:30 -05:00
|
|
|
remObj (term);
|
|
|
|
|
2003-10-11 20:49:08 -05:00
|
|
|
if (!term->inst.do_free)
|
2003-06-14 00:17:07 -05:00
|
|
|
PERR("free a billterm without do_free set!");
|
|
|
|
|
2003-07-09 22:18:17 -05:00
|
|
|
/* disconnect from parent */
|
|
|
|
if (term->parent)
|
|
|
|
gncBillTermRemoveChild(term->parent, term);
|
|
|
|
|
2003-06-14 00:17:07 -05:00
|
|
|
/* disconnect from the children */
|
|
|
|
for (list = term->children; list; list=list->next) {
|
|
|
|
child = list->data;
|
|
|
|
gncBillTermSetParent(child, NULL);
|
|
|
|
}
|
|
|
|
g_list_free(term->children);
|
|
|
|
|
2002-06-21 11:44:30 -05:00
|
|
|
g_free (term);
|
|
|
|
}
|
|
|
|
|
2003-06-14 00:17:07 -05:00
|
|
|
static void
|
|
|
|
gncBillTermAddChild (GncBillTerm *table, GncBillTerm *child)
|
|
|
|
{
|
|
|
|
g_return_if_fail(table);
|
|
|
|
g_return_if_fail(child);
|
2003-10-11 20:49:08 -05:00
|
|
|
g_return_if_fail(table->inst.do_free == FALSE);
|
2003-06-14 00:17:07 -05:00
|
|
|
|
|
|
|
table->children = g_list_prepend(table->children, child);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gncBillTermRemoveChild (GncBillTerm *table, GncBillTerm *child)
|
|
|
|
{
|
|
|
|
g_return_if_fail(table);
|
|
|
|
g_return_if_fail(child);
|
|
|
|
|
2003-10-11 20:49:08 -05:00
|
|
|
if (table->inst.do_free)
|
2003-06-14 00:17:07 -05:00
|
|
|
return;
|
|
|
|
|
|
|
|
table->children = g_list_remove(table->children, child);
|
|
|
|
}
|
|
|
|
|
2002-06-21 11:44:30 -05:00
|
|
|
/* Set Functions */
|
|
|
|
void gncBillTermSetGUID (GncBillTerm *term, const GUID *guid)
|
|
|
|
{
|
|
|
|
if (!term || !guid) return;
|
2003-10-11 20:49:08 -05:00
|
|
|
if (guid_equal (guid, &term->inst.guid)) return;
|
2002-06-21 11:44:30 -05:00
|
|
|
|
2003-10-11 20:49:08 -05:00
|
|
|
/* xxx this looks fishy to me ... */
|
2002-11-03 18:41:01 -06:00
|
|
|
gncBillTermBeginEdit (term);
|
2002-06-21 11:44:30 -05:00
|
|
|
remObj (term);
|
2003-10-11 20:49:08 -05:00
|
|
|
term->inst.guid = *guid;
|
2002-06-21 11:44:30 -05:00
|
|
|
addObj (term);
|
2002-11-03 18:41:01 -06:00
|
|
|
gncBillTermCommitEdit (term);
|
2002-06-21 11:44:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void gncBillTermSetName (GncBillTerm *term, const char *name)
|
|
|
|
{
|
|
|
|
if (!term || !name) return;
|
2002-11-03 18:41:01 -06:00
|
|
|
SET_STR (term, term->name, name);
|
2002-06-21 11:44:30 -05:00
|
|
|
mark_term (term);
|
2002-06-22 20:23:28 -05:00
|
|
|
maybe_resort_list (term);
|
2002-11-03 18:41:01 -06:00
|
|
|
gncBillTermCommitEdit (term);
|
2002-06-21 11:44:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void gncBillTermSetDescription (GncBillTerm *term, const char *desc)
|
|
|
|
{
|
|
|
|
if (!term || !desc) return;
|
2002-11-03 18:41:01 -06:00
|
|
|
SET_STR (term, term->desc, desc);
|
2002-06-21 11:44:30 -05:00
|
|
|
mark_term (term);
|
2002-06-22 20:23:28 -05:00
|
|
|
maybe_resort_list (term);
|
2002-11-03 18:41:01 -06:00
|
|
|
gncBillTermCommitEdit (term);
|
2002-06-21 11:44:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void gncBillTermSetType (GncBillTerm *term, GncBillTermType type)
|
|
|
|
{
|
|
|
|
if (!term) return;
|
|
|
|
if (term->type == type) return;
|
2002-11-03 18:41:01 -06:00
|
|
|
gncBillTermBeginEdit (term);
|
2002-06-21 11:44:30 -05:00
|
|
|
term->type = type;
|
|
|
|
mark_term (term);
|
2002-11-03 18:41:01 -06:00
|
|
|
gncBillTermCommitEdit (term);
|
2002-06-21 11:44:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void gncBillTermSetDueDays (GncBillTerm *term, gint days)
|
|
|
|
{
|
|
|
|
if (!term) return;
|
|
|
|
if (term->due_days == days) return;
|
2002-11-03 18:41:01 -06:00
|
|
|
gncBillTermBeginEdit (term);
|
2002-06-21 11:44:30 -05:00
|
|
|
term->due_days = days;
|
|
|
|
mark_term (term);
|
2002-11-03 18:41:01 -06:00
|
|
|
gncBillTermCommitEdit (term);
|
2002-06-21 11:44:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void gncBillTermSetDiscountDays (GncBillTerm *term, gint days)
|
|
|
|
{
|
|
|
|
if (!term) return;
|
|
|
|
if (term->disc_days == days) return;
|
2002-11-03 18:41:01 -06:00
|
|
|
gncBillTermBeginEdit (term);
|
2002-06-21 11:44:30 -05:00
|
|
|
term->disc_days = days;
|
|
|
|
mark_term (term);
|
2002-11-03 18:41:01 -06:00
|
|
|
gncBillTermCommitEdit (term);
|
2002-06-21 11:44:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void gncBillTermSetDiscount (GncBillTerm *term, gnc_numeric discount)
|
|
|
|
{
|
|
|
|
if (!term) return;
|
|
|
|
if (gnc_numeric_eq (term->discount, discount)) return;
|
2002-11-03 18:41:01 -06:00
|
|
|
gncBillTermBeginEdit (term);
|
2002-06-21 11:44:30 -05:00
|
|
|
term->discount = discount;
|
|
|
|
mark_term (term);
|
2002-11-03 18:41:01 -06:00
|
|
|
gncBillTermCommitEdit (term);
|
2002-06-21 11:44:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void gncBillTermSetCutoff (GncBillTerm *term, gint cutoff)
|
|
|
|
{
|
|
|
|
if (!term) return;
|
|
|
|
if (term->cutoff == cutoff) return;
|
2002-11-03 18:41:01 -06:00
|
|
|
gncBillTermBeginEdit (term);
|
2002-06-21 11:44:30 -05:00
|
|
|
term->cutoff = cutoff;
|
|
|
|
mark_term (term);
|
2002-11-03 18:41:01 -06:00
|
|
|
gncBillTermCommitEdit (term);
|
2002-06-21 11:44:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void gncBillTermSetParent (GncBillTerm *term, GncBillTerm *parent)
|
|
|
|
{
|
|
|
|
if (!term) return;
|
2002-11-03 18:41:01 -06:00
|
|
|
gncBillTermBeginEdit (term);
|
2003-06-14 00:17:07 -05:00
|
|
|
if (term->parent)
|
|
|
|
gncBillTermRemoveChild(term->parent, term);
|
2002-06-21 11:44:30 -05:00
|
|
|
term->parent = parent;
|
2003-06-14 00:17:07 -05:00
|
|
|
if (parent)
|
|
|
|
gncBillTermAddChild(parent, term);
|
2002-06-21 11:44:30 -05:00
|
|
|
term->refcount = 0;
|
|
|
|
gncBillTermMakeInvisible (term);
|
2002-11-03 18:41:01 -06:00
|
|
|
gncBillTermCommitEdit (term);
|
2002-06-21 11:44:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void gncBillTermSetChild (GncBillTerm *term, GncBillTerm *child)
|
|
|
|
{
|
|
|
|
if (!term) return;
|
2002-11-03 18:41:01 -06:00
|
|
|
gncBillTermBeginEdit (term);
|
2002-06-21 11:44:30 -05:00
|
|
|
term->child = child;
|
2002-11-03 18:41:01 -06:00
|
|
|
gncBillTermCommitEdit (term);
|
2002-06-21 11:44:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void gncBillTermIncRef (GncBillTerm *term)
|
|
|
|
{
|
|
|
|
if (!term) return;
|
2003-10-11 20:49:08 -05:00
|
|
|
if (term->parent || term->invisible) return; /* children dont need refcounts */
|
2002-11-03 18:41:01 -06:00
|
|
|
gncBillTermBeginEdit (term);
|
2002-06-21 11:44:30 -05:00
|
|
|
term->refcount++;
|
2002-11-03 18:41:01 -06:00
|
|
|
gncBillTermCommitEdit (term);
|
2002-06-21 11:44:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void gncBillTermDecRef (GncBillTerm *term)
|
|
|
|
{
|
|
|
|
if (!term) return;
|
2003-10-11 20:49:08 -05:00
|
|
|
if (term->parent || term->invisible) return; /* children dont need refcounts */
|
2002-11-03 18:41:01 -06:00
|
|
|
gncBillTermBeginEdit (term);
|
2002-06-21 11:44:30 -05:00
|
|
|
term->refcount--;
|
|
|
|
g_return_if_fail (term->refcount >= 0);
|
2002-11-03 18:41:01 -06:00
|
|
|
gncBillTermCommitEdit (term);
|
2002-06-21 11:44:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void gncBillTermSetRefcount (GncBillTerm *term, gint64 refcount)
|
|
|
|
{
|
|
|
|
if (!term) return;
|
|
|
|
term->refcount = refcount;
|
|
|
|
}
|
|
|
|
|
|
|
|
void gncBillTermMakeInvisible (GncBillTerm *term)
|
|
|
|
{
|
|
|
|
if (!term) return;
|
2002-11-03 18:41:01 -06:00
|
|
|
gncBillTermBeginEdit (term);
|
2002-06-21 11:44:30 -05:00
|
|
|
term->invisible = TRUE;
|
|
|
|
add_or_rem_object (term, FALSE);
|
2002-11-03 18:41:01 -06:00
|
|
|
gncBillTermCommitEdit (term);
|
2002-06-21 11:44:30 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void gncBillTermChanged (GncBillTerm *term)
|
|
|
|
{
|
|
|
|
if (!term) return;
|
|
|
|
term->child = NULL;
|
|
|
|
}
|
|
|
|
|
2002-11-03 14:21:42 -06:00
|
|
|
void gncBillTermBeginEdit (GncBillTerm *term)
|
2002-06-21 11:44:30 -05:00
|
|
|
{
|
2003-10-11 20:49:08 -05:00
|
|
|
GNC_BEGIN_EDIT (&term->inst, _GNC_MOD_NAME);
|
2002-11-03 14:21:42 -06:00
|
|
|
}
|
|
|
|
|
2003-10-11 20:49:08 -05:00
|
|
|
static void gncBillTermOnError (QofInstance *inst, QofBackendError errcode)
|
2002-11-03 14:21:42 -06:00
|
|
|
{
|
2003-06-26 22:36:02 -05:00
|
|
|
PERR("BillTerm QofBackend Failure: %d", errcode);
|
2002-11-03 14:21:42 -06:00
|
|
|
}
|
2002-06-21 14:00:34 -05:00
|
|
|
|
2003-10-11 20:49:08 -05:00
|
|
|
static inline void bill_free (QofInstance *inst)
|
2002-11-03 14:21:42 -06:00
|
|
|
{
|
2003-10-11 20:49:08 -05:00
|
|
|
GncBillTerm *term = (GncBillTerm *) inst;
|
|
|
|
gncBillTermFree(term);
|
2002-06-21 11:44:30 -05:00
|
|
|
}
|
|
|
|
|
2003-10-11 20:49:08 -05:00
|
|
|
static inline void on_done (QofInstance *inst) {}
|
|
|
|
|
2002-11-03 14:21:42 -06:00
|
|
|
void gncBillTermCommitEdit (GncBillTerm *term)
|
|
|
|
{
|
2003-10-11 20:49:08 -05:00
|
|
|
GNC_COMMIT_EDIT_PART1 (&term->inst);
|
|
|
|
GNC_COMMIT_EDIT_PART2 (&term->inst, _GNC_MOD_NAME, gncBillTermOnError,
|
|
|
|
on_done, bill_free);
|
2002-11-03 14:21:42 -06:00
|
|
|
}
|
2002-06-21 11:44:30 -05:00
|
|
|
|
|
|
|
/* Get Functions */
|
2003-06-26 22:05:25 -05:00
|
|
|
GncBillTerm * gncBillTermLookup (QofBook *book, const GUID *guid)
|
2002-06-21 11:44:30 -05:00
|
|
|
{
|
|
|
|
if (!book || !guid) return NULL;
|
2003-06-26 22:36:02 -05:00
|
|
|
return qof_entity_lookup (gnc_book_get_entity_table (book),
|
2003-10-11 20:49:08 -05:00
|
|
|
guid, _GNC_MOD_NAME);
|
2002-06-21 11:44:30 -05:00
|
|
|
}
|
|
|
|
|
2003-06-26 22:05:25 -05:00
|
|
|
GncBillTerm *gncBillTermLookupByName (QofBook *book, const char *name)
|
2002-06-21 11:44:30 -05:00
|
|
|
{
|
|
|
|
GList *list = gncBillTermGetTerms (book);
|
|
|
|
|
|
|
|
for ( ; list; list = list->next) {
|
|
|
|
GncBillTerm *term = list->data;
|
|
|
|
if (!safe_strcmp (term->name, name))
|
|
|
|
return list->data;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2003-06-26 22:05:25 -05:00
|
|
|
GList * gncBillTermGetTerms (QofBook *book)
|
2002-06-21 11:44:30 -05:00
|
|
|
{
|
|
|
|
struct _book_info *bi;
|
|
|
|
if (!book) return NULL;
|
|
|
|
|
|
|
|
bi = gnc_book_get_data (book, _GNC_MOD_NAME);
|
|
|
|
return bi->terms;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *gncBillTermGetName (GncBillTerm *term)
|
|
|
|
{
|
|
|
|
if (!term) return NULL;
|
|
|
|
return term->name;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *gncBillTermGetDescription (GncBillTerm *term)
|
|
|
|
{
|
|
|
|
if (!term) return NULL;
|
|
|
|
return term->desc;
|
|
|
|
}
|
|
|
|
|
|
|
|
GncBillTermType gncBillTermGetType (GncBillTerm *term)
|
|
|
|
{
|
|
|
|
if (!term) return 0;
|
|
|
|
return term->type;
|
|
|
|
}
|
|
|
|
|
|
|
|
gint gncBillTermGetDueDays (GncBillTerm *term)
|
|
|
|
{
|
|
|
|
if (!term) return 0;
|
|
|
|
return term->due_days;
|
|
|
|
}
|
|
|
|
|
|
|
|
gint gncBillTermGetDiscountDays (GncBillTerm *term)
|
|
|
|
{
|
|
|
|
if (!term) return 0;
|
|
|
|
return term->disc_days;
|
|
|
|
}
|
|
|
|
|
|
|
|
gnc_numeric gncBillTermGetDiscount (GncBillTerm *term)
|
|
|
|
{
|
|
|
|
if (!term) return gnc_numeric_zero ();
|
|
|
|
return term->discount;
|
|
|
|
}
|
|
|
|
|
|
|
|
gint gncBillTermGetCutoff (GncBillTerm *term)
|
|
|
|
{
|
|
|
|
if (!term) return 0;
|
|
|
|
return term->cutoff;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GncBillTerm *gncBillTermCopy (GncBillTerm *term)
|
|
|
|
{
|
|
|
|
GncBillTerm *t;
|
|
|
|
|
|
|
|
if (!term) return NULL;
|
2003-10-11 20:49:08 -05:00
|
|
|
t = gncBillTermCreate (term->inst.book);
|
2003-06-17 16:38:41 -05:00
|
|
|
|
|
|
|
gncBillTermBeginEdit(t);
|
|
|
|
|
2002-06-21 11:44:30 -05:00
|
|
|
gncBillTermSetName (t, term->name);
|
|
|
|
gncBillTermSetDescription (t, term->desc);
|
|
|
|
|
2003-06-17 16:38:41 -05:00
|
|
|
t->type = term->type;
|
|
|
|
t->due_days = term->due_days;
|
|
|
|
t->disc_days = term->disc_days;
|
|
|
|
t->discount = term->discount;
|
|
|
|
t->cutoff = term->cutoff;
|
|
|
|
|
|
|
|
gncBillTermCommitEdit(t);
|
|
|
|
|
2002-06-21 11:44:30 -05:00
|
|
|
return t;
|
|
|
|
}
|
|
|
|
|
|
|
|
GncBillTerm *gncBillTermReturnChild (GncBillTerm *term, gboolean make_new)
|
|
|
|
{
|
|
|
|
GncBillTerm *child = NULL;
|
|
|
|
|
|
|
|
if (!term) return NULL;
|
|
|
|
if (term->child) return term->child;
|
2003-06-14 00:17:07 -05:00
|
|
|
if (term->parent || term->invisible) return term;
|
2002-06-21 11:44:30 -05:00
|
|
|
if (make_new) {
|
|
|
|
child = gncBillTermCopy (term);
|
|
|
|
gncBillTermSetChild (term, child);
|
|
|
|
gncBillTermSetParent (child, term);
|
|
|
|
}
|
|
|
|
return child;
|
|
|
|
}
|
|
|
|
|
|
|
|
GncBillTerm *gncBillTermGetParent (GncBillTerm *term)
|
|
|
|
{
|
|
|
|
if (!term) return NULL;
|
|
|
|
return term->parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
gint64 gncBillTermGetRefcount (GncBillTerm *term)
|
|
|
|
{
|
|
|
|
if (!term) return 0;
|
|
|
|
return term->refcount;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean gncBillTermGetInvisible (GncBillTerm *term)
|
|
|
|
{
|
|
|
|
if (!term) return FALSE;
|
|
|
|
return term->invisible;
|
|
|
|
}
|
|
|
|
|
|
|
|
int gncBillTermCompare (GncBillTerm *a, GncBillTerm *b)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!a && !b) return 0;
|
|
|
|
if (!a) return -1;
|
|
|
|
if (!b) return 1;
|
|
|
|
|
|
|
|
ret = safe_strcmp (a->name, b->name);
|
2002-06-22 20:23:28 -05:00
|
|
|
if (ret) return ret;
|
2002-06-21 11:44:30 -05:00
|
|
|
|
|
|
|
return safe_strcmp (a->desc, b->desc);
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean gncBillTermIsDirty (GncBillTerm *term)
|
|
|
|
{
|
|
|
|
if (!term) return FALSE;
|
2003-10-11 20:49:08 -05:00
|
|
|
return term->inst.dirty;
|
2002-06-21 11:44:30 -05:00
|
|
|
}
|
|
|
|
|
2002-06-22 16:55:00 -05:00
|
|
|
/********************************************************/
|
|
|
|
/* functions to compute dates from Bill Terms */
|
|
|
|
|
|
|
|
#define SECS_PER_DAY 86400
|
|
|
|
|
|
|
|
/* Based on the timespec and a proximo type, compute the month and
|
|
|
|
* year this is due. The actual day is filled in below.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
compute_monthyear (GncBillTerm *term, Timespec post_date,
|
2003-10-11 20:49:08 -05:00
|
|
|
int *month, int *year)
|
2002-06-22 16:55:00 -05:00
|
|
|
{
|
|
|
|
int iday, imonth, iyear;
|
|
|
|
int cutoff = term->cutoff;
|
|
|
|
|
|
|
|
g_return_if_fail (term->type == GNC_TERM_TYPE_PROXIMO);
|
|
|
|
|
|
|
|
gnc_timespec2dmy (post_date, &iday, &imonth, &iyear);
|
|
|
|
|
|
|
|
if (cutoff <= 0)
|
|
|
|
cutoff += gnc_timespec_last_mday (post_date);
|
|
|
|
|
|
|
|
if (iday <= cutoff) {
|
|
|
|
/* We apply this to next month */
|
|
|
|
imonth++;
|
|
|
|
} else {
|
|
|
|
/* We apply to the following month */
|
|
|
|
imonth += 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (imonth > 12) {
|
|
|
|
iyear++;
|
|
|
|
imonth -= 12;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (month) *month = imonth;
|
|
|
|
if (year) *year = iyear;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Timespec
|
|
|
|
compute_time (GncBillTerm *term, Timespec post_date, int days)
|
|
|
|
{
|
|
|
|
Timespec res = post_date;
|
|
|
|
int day, month, year;
|
|
|
|
|
|
|
|
switch (term->type) {
|
|
|
|
case GNC_TERM_TYPE_DAYS:
|
|
|
|
res.tv_sec += (SECS_PER_DAY * days);
|
|
|
|
break;
|
|
|
|
case GNC_TERM_TYPE_PROXIMO:
|
|
|
|
compute_monthyear (term, post_date, &month, &year);
|
|
|
|
day = gnc_date_my_last_mday (month, year);
|
|
|
|
if (days < day)
|
|
|
|
day = days;
|
|
|
|
res = gnc_dmy2timespec (day, month, year);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
Timespec
|
|
|
|
gncBillTermComputeDueDate (GncBillTerm *term, Timespec post_date)
|
|
|
|
{
|
|
|
|
Timespec res = post_date;
|
|
|
|
if (!term) return res;
|
|
|
|
|
|
|
|
return compute_time (term, post_date, term->due_days);
|
|
|
|
}
|
|
|
|
|
|
|
|
Timespec
|
|
|
|
gncBillTermComputeDiscountDate (GncBillTerm *term, Timespec post_date)
|
|
|
|
{
|
|
|
|
Timespec res = post_date;
|
|
|
|
if (!term) return res;
|
|
|
|
|
|
|
|
return compute_time (term, post_date, term->disc_days);
|
|
|
|
}
|
|
|
|
|
2002-06-21 11:44:30 -05:00
|
|
|
/* Package-Private functions */
|
|
|
|
|
2002-06-22 20:23:28 -05:00
|
|
|
static void maybe_resort_list (GncBillTerm *term)
|
|
|
|
{
|
|
|
|
struct _book_info *bi;
|
|
|
|
|
|
|
|
if (term->parent || term->invisible) return;
|
2003-10-11 20:49:08 -05:00
|
|
|
bi = gnc_book_get_data (term->inst.book, _GNC_MOD_NAME);
|
2002-06-22 20:23:28 -05:00
|
|
|
bi->terms = g_list_sort (bi->terms, (GCompareFunc)gncBillTermCompare);
|
|
|
|
}
|
|
|
|
|
2002-06-21 11:44:30 -05:00
|
|
|
static void add_or_rem_object (GncBillTerm *term, gboolean add)
|
|
|
|
{
|
|
|
|
struct _book_info *bi;
|
|
|
|
|
|
|
|
if (!term) return;
|
2003-10-11 20:49:08 -05:00
|
|
|
bi = gnc_book_get_data (term->inst.book, _GNC_MOD_NAME);
|
2002-06-21 11:44:30 -05:00
|
|
|
|
|
|
|
if (add)
|
|
|
|
bi->terms = g_list_insert_sorted (bi->terms, term,
|
2003-10-11 20:49:08 -05:00
|
|
|
(GCompareFunc)gncBillTermCompare);
|
2002-06-21 11:44:30 -05:00
|
|
|
else
|
|
|
|
bi->terms = g_list_remove (bi->terms, term);
|
|
|
|
}
|
|
|
|
|
2003-06-26 22:05:25 -05:00
|
|
|
static void _gncBillTermCreate (QofBook *book)
|
2002-06-21 11:44:30 -05:00
|
|
|
{
|
|
|
|
struct _book_info *bi;
|
|
|
|
|
|
|
|
if (!book) return;
|
|
|
|
|
|
|
|
bi = g_new0 (struct _book_info, 1);
|
|
|
|
bi->bi.ht = guid_hash_table_new ();
|
|
|
|
gnc_book_set_data (book, _GNC_MOD_NAME, bi);
|
|
|
|
}
|
|
|
|
|
2003-06-26 22:05:25 -05:00
|
|
|
static void _gncBillTermDestroy (QofBook *book)
|
2002-06-21 11:44:30 -05:00
|
|
|
{
|
|
|
|
struct _book_info *bi;
|
|
|
|
|
|
|
|
if (!book) return;
|
|
|
|
|
|
|
|
bi = gnc_book_get_data (book, _GNC_MOD_NAME);
|
|
|
|
|
|
|
|
/* XXX : Destroy the objects? */
|
|
|
|
g_hash_table_destroy (bi->bi.ht);
|
|
|
|
g_list_free (bi->terms);
|
|
|
|
g_free (bi);
|
|
|
|
}
|
|
|
|
|
2003-06-26 22:05:25 -05:00
|
|
|
static gboolean _gncBillTermIsDirty (QofBook *book)
|
2002-06-21 11:44:30 -05:00
|
|
|
{
|
|
|
|
return gncBusinessIsDirty (book, _GNC_MOD_NAME);
|
|
|
|
}
|
|
|
|
|
2003-06-26 22:05:25 -05:00
|
|
|
static void _gncBillTermMarkClean (QofBook *book)
|
2002-06-21 11:44:30 -05:00
|
|
|
{
|
|
|
|
gncBusinessSetDirtyFlag (book, _GNC_MOD_NAME, FALSE);
|
|
|
|
}
|
|
|
|
|
2003-06-26 22:36:02 -05:00
|
|
|
static void _gncBillTermForeach (QofBook *book, QofEntityForeachCB cb,
|
2003-10-11 20:49:08 -05:00
|
|
|
gpointer user_data)
|
2002-06-21 11:44:30 -05:00
|
|
|
{
|
|
|
|
gncBusinessForeach (book, _GNC_MOD_NAME, cb, user_data);
|
|
|
|
}
|
|
|
|
|
2003-10-11 20:49:08 -05:00
|
|
|
static QofObject gncBillTermDesc =
|
|
|
|
{
|
|
|
|
interface_version: QOF_OBJECT_VERSION,
|
|
|
|
name: _GNC_MOD_NAME,
|
|
|
|
type_label: "Billing Term",
|
|
|
|
book_begin: _gncBillTermCreate,
|
|
|
|
book_end: _gncBillTermDestroy,
|
|
|
|
is_dirty: _gncBillTermIsDirty,
|
|
|
|
mark_clean: _gncBillTermMarkClean,
|
|
|
|
foreach: _gncBillTermForeach,
|
|
|
|
printable: NULL
|
2002-06-21 11:44:30 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
gboolean gncBillTermRegister (void)
|
|
|
|
{
|
2003-09-27 05:21:27 -05:00
|
|
|
static QofParam params[] = {
|
2003-10-11 20:49:08 -05:00
|
|
|
{ QOF_QUERY_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
|
|
|
|
{ QOF_QUERY_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
|
2002-06-21 11:44:30 -05:00
|
|
|
{ NULL },
|
|
|
|
};
|
|
|
|
|
2003-09-27 11:33:06 -05:00
|
|
|
qof_class_register (_GNC_MOD_NAME, (QofSortFunc)gncBillTermCompare, params);
|
2002-06-21 11:44:30 -05:00
|
|
|
|
2003-06-26 22:09:39 -05:00
|
|
|
return qof_object_register (&gncBillTermDesc);
|
2002-06-21 11:44:30 -05:00
|
|
|
}
|