2003-10-12 10:28:29 -05:00
|
|
|
/********************************************************************\
|
|
|
|
* gncTaxTable.c -- the Gnucash Tax Table interface *
|
|
|
|
* *
|
|
|
|
* 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 *
|
2005-11-16 23:35:02 -06:00
|
|
|
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
|
|
|
|
* Boston, MA 02110-1301, USA gnu@gnu.org *
|
2003-10-12 10:28:29 -05:00
|
|
|
* *
|
|
|
|
\********************************************************************/
|
|
|
|
|
2002-06-14 12:08:19 -05:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2002 Derek Atkins
|
2003-10-12 10:28:29 -05:00
|
|
|
* Copyright (C) 2003 Linas Vepstas <linas@linas.org>
|
2002-06-14 12:08:19 -05:00
|
|
|
* Author: Derek Atkins <warlord@MIT.EDU>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include <glib.h>
|
|
|
|
|
|
|
|
#include "gncTaxTableP.h"
|
|
|
|
|
2003-10-11 19:42:56 -05:00
|
|
|
struct _gncTaxTable
|
|
|
|
{
|
2003-10-12 10:28:29 -05:00
|
|
|
QofInstance inst;
|
|
|
|
char * name;
|
|
|
|
GList * entries;
|
2003-10-12 22:56:23 -05:00
|
|
|
Timespec modtime; /* internal date of last modtime */
|
2002-11-03 14:21:42 -06:00
|
|
|
|
2003-10-12 14:08:47 -05:00
|
|
|
/* See src/doc/business.txt for an explanation of the following */
|
2003-10-12 22:56:23 -05:00
|
|
|
/* Code that handles this is *identical* to that in gncBillTerm */
|
2003-10-12 10:28:29 -05:00
|
|
|
gint64 refcount;
|
2003-10-12 22:56:23 -05:00
|
|
|
GncTaxTable * parent; /* if non-null, we are an immutable child */
|
|
|
|
GncTaxTable * child; /* if non-null, we have not changed */
|
2003-10-11 19:42:56 -05:00
|
|
|
gboolean invisible;
|
2003-10-12 22:56:23 -05:00
|
|
|
GList * children; /* list of children for disconnection */
|
2002-06-14 12:08:19 -05:00
|
|
|
};
|
|
|
|
|
2003-10-11 19:42:56 -05:00
|
|
|
struct _gncTaxTableEntry
|
|
|
|
{
|
2003-10-12 10:28:29 -05:00
|
|
|
GncTaxTable * table;
|
|
|
|
Account * account;
|
|
|
|
GncAmountType type;
|
|
|
|
gnc_numeric amount;
|
2002-06-14 12:08:19 -05:00
|
|
|
};
|
|
|
|
|
2003-10-12 10:28:29 -05:00
|
|
|
struct _book_info
|
|
|
|
{
|
|
|
|
GList * tables; /* visible tables */
|
2002-06-14 12:08:19 -05:00
|
|
|
};
|
|
|
|
|
2003-10-12 20:52:42 -05:00
|
|
|
static GncTaxTableEntry * CloneTaxEntry (GncTaxTableEntry*, QofBook *);
|
|
|
|
|
2005-11-01 21:32:36 -06:00
|
|
|
static QofLogModule log_module = GNC_MOD_BUSINESS;
|
2002-11-03 14:21:42 -06:00
|
|
|
|
2003-10-12 20:52:42 -05:00
|
|
|
/* =============================================================== */
|
2002-07-01 13:31:48 -05:00
|
|
|
/* You must edit the functions in this block in tandem. KEEP THEM IN
|
|
|
|
SYNC! */
|
|
|
|
|
|
|
|
#define GNC_RETURN_ENUM_AS_STRING(x,s) case (x): return (s);
|
|
|
|
const char *
|
|
|
|
gncAmountTypeToString (GncAmountType type)
|
|
|
|
{
|
|
|
|
switch(type)
|
|
|
|
{
|
|
|
|
GNC_RETURN_ENUM_AS_STRING(GNC_AMT_TYPE_VALUE, "VALUE");
|
|
|
|
GNC_RETURN_ENUM_AS_STRING(GNC_AMT_TYPE_PERCENT, "PERCENT");
|
|
|
|
default:
|
|
|
|
g_warning ("asked to translate unknown amount type %d.\n", type);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
|
|
|
gncTaxIncludedTypeToString (GncTaxIncluded type)
|
|
|
|
{
|
|
|
|
switch(type)
|
|
|
|
{
|
|
|
|
GNC_RETURN_ENUM_AS_STRING(GNC_TAXINCLUDED_YES, "YES");
|
|
|
|
GNC_RETURN_ENUM_AS_STRING(GNC_TAXINCLUDED_NO, "NO");
|
|
|
|
GNC_RETURN_ENUM_AS_STRING(GNC_TAXINCLUDED_USEGLOBAL, "USEGLOBAL");
|
|
|
|
default:
|
|
|
|
g_warning ("asked to translate unknown taxincluded type %d.\n", type);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
#undef GNC_RETURN_ENUM_AS_STRING
|
|
|
|
#define GNC_RETURN_ON_MATCH(s,x) \
|
|
|
|
if(safe_strcmp((s), (str)) == 0) { *type = x; return(TRUE); }
|
|
|
|
gboolean
|
|
|
|
gncAmountStringToType (const char *str, GncAmountType *type)
|
|
|
|
{
|
|
|
|
GNC_RETURN_ON_MATCH ("VALUE", GNC_AMT_TYPE_VALUE);
|
|
|
|
GNC_RETURN_ON_MATCH ("PERCENT", GNC_AMT_TYPE_PERCENT);
|
|
|
|
g_warning ("asked to translate unknown amount type string %s.\n",
|
|
|
|
str ? str : "(null)");
|
|
|
|
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
gncTaxIncludedStringToType (const char *str, GncTaxIncluded *type)
|
|
|
|
{
|
|
|
|
GNC_RETURN_ON_MATCH ("YES", GNC_TAXINCLUDED_YES);
|
|
|
|
GNC_RETURN_ON_MATCH ("NO", GNC_TAXINCLUDED_NO);
|
|
|
|
GNC_RETURN_ON_MATCH ("USEGLOBAL", GNC_TAXINCLUDED_USEGLOBAL);
|
|
|
|
g_warning ("asked to translate unknown taxincluded type string %s.\n",
|
|
|
|
str ? str : "(null)");
|
|
|
|
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
#undef GNC_RETURN_ON_MATCH
|
|
|
|
|
2003-10-12 10:28:29 -05:00
|
|
|
/* =============================================================== */
|
|
|
|
/* Misc inline functions */
|
|
|
|
|
2003-10-19 00:13:59 -05:00
|
|
|
#define _GNC_MOD_NAME GNC_ID_TAXTABLE
|
2002-06-14 12:08:19 -05:00
|
|
|
|
2002-11-03 18:41:01 -06:00
|
|
|
#define SET_STR(obj, member, str) { \
|
2003-10-11 19:42:56 -05:00
|
|
|
char * tmp; \
|
|
|
|
\
|
|
|
|
if (!safe_strcmp (member, str)) return; \
|
|
|
|
gncTaxTableBeginEdit (obj); \
|
|
|
|
tmp = CACHE_INSERT (str); \
|
|
|
|
CACHE_REMOVE (member); \
|
|
|
|
member = tmp; \
|
|
|
|
}
|
2002-06-14 12:08:19 -05:00
|
|
|
|
2003-10-12 10:28:29 -05:00
|
|
|
static inline void
|
2002-06-14 12:08:19 -05:00
|
|
|
mark_table (GncTaxTable *table)
|
|
|
|
{
|
2006-05-02 21:28:18 -05:00
|
|
|
qof_instance_set_dirty(&table->inst);
|
2006-03-08 21:48:49 -06:00
|
|
|
qof_event_gen (&table->inst.entity, QOF_EVENT_MODIFY, NULL);
|
2002-06-14 12:08:19 -05:00
|
|
|
}
|
|
|
|
|
2003-10-12 10:28:29 -05:00
|
|
|
static inline void
|
|
|
|
maybe_resort_list (GncTaxTable *table)
|
|
|
|
{
|
|
|
|
struct _book_info *bi;
|
|
|
|
|
|
|
|
if (table->parent || table->invisible) return;
|
2003-10-14 16:20:55 -05:00
|
|
|
bi = qof_book_get_data (table->inst.book, _GNC_MOD_NAME);
|
2003-10-12 10:28:29 -05:00
|
|
|
bi->tables = g_list_sort (bi->tables, (GCompareFunc)gncTaxTableCompare);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
2002-06-16 00:11:33 -05:00
|
|
|
mod_table (GncTaxTable *table)
|
|
|
|
{
|
|
|
|
timespecFromTime_t (&table->modtime, time(NULL));
|
|
|
|
}
|
|
|
|
|
2003-10-12 10:28:29 -05:00
|
|
|
static inline void addObj (GncTaxTable *table)
|
|
|
|
{
|
|
|
|
struct _book_info *bi;
|
2003-10-14 16:20:55 -05:00
|
|
|
bi = qof_book_get_data (table->inst.book, _GNC_MOD_NAME);
|
2003-10-12 10:28:29 -05:00
|
|
|
bi->tables = g_list_insert_sorted (bi->tables, table,
|
|
|
|
(GCompareFunc)gncTaxTableCompare);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void remObj (GncTaxTable *table)
|
|
|
|
{
|
|
|
|
struct _book_info *bi;
|
2003-10-14 16:20:55 -05:00
|
|
|
bi = qof_book_get_data (table->inst.book, _GNC_MOD_NAME);
|
2003-10-12 10:28:29 -05:00
|
|
|
bi->tables = g_list_remove (bi->tables, table);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
gncTaxTableAddChild (GncTaxTable *table, GncTaxTable *child)
|
|
|
|
{
|
|
|
|
g_return_if_fail(table);
|
|
|
|
g_return_if_fail(child);
|
|
|
|
g_return_if_fail(table->inst.do_free == FALSE);
|
|
|
|
|
|
|
|
table->children = g_list_prepend(table->children, child);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
gncTaxTableRemoveChild (GncTaxTable *table, GncTaxTable *child)
|
|
|
|
{
|
|
|
|
g_return_if_fail(table);
|
|
|
|
g_return_if_fail(child);
|
|
|
|
|
|
|
|
if (table->inst.do_free) return;
|
|
|
|
|
|
|
|
table->children = g_list_remove(table->children, child);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* =============================================================== */
|
2002-06-14 12:08:19 -05:00
|
|
|
/* Create/Destroy Functions */
|
2003-10-12 10:28:29 -05:00
|
|
|
|
|
|
|
GncTaxTable *
|
|
|
|
gncTaxTableCreate (QofBook *book)
|
2002-06-14 12:08:19 -05:00
|
|
|
{
|
|
|
|
GncTaxTable *table;
|
|
|
|
if (!book) return NULL;
|
|
|
|
|
|
|
|
table = g_new0 (GncTaxTable, 1);
|
2003-10-14 16:20:55 -05:00
|
|
|
qof_instance_init (&table->inst, _GNC_MOD_NAME, book);
|
2002-06-14 12:08:19 -05:00
|
|
|
table->name = CACHE_INSERT ("");
|
|
|
|
addObj (table);
|
2006-03-08 21:48:49 -06:00
|
|
|
qof_event_gen (&table->inst.entity, QOF_EVENT_CREATE, NULL);
|
2002-06-14 12:08:19 -05:00
|
|
|
return table;
|
|
|
|
}
|
|
|
|
|
2003-10-12 10:28:29 -05:00
|
|
|
|
|
|
|
GncTaxTable *
|
|
|
|
gncCloneTaxTable (GncTaxTable *from, QofBook *book)
|
|
|
|
{
|
2003-10-12 20:52:42 -05:00
|
|
|
GList *node;
|
2003-10-12 10:28:29 -05:00
|
|
|
GncTaxTable *table;
|
|
|
|
if (!book) return NULL;
|
|
|
|
|
|
|
|
table = g_new0 (GncTaxTable, 1);
|
2003-10-14 16:20:55 -05:00
|
|
|
qof_instance_init (&table->inst, _GNC_MOD_NAME, book);
|
2003-10-12 10:28:29 -05:00
|
|
|
qof_instance_gemini (&table->inst, &from->inst);
|
|
|
|
|
|
|
|
table->name = CACHE_INSERT (from->name);
|
|
|
|
table->modtime = from->modtime;
|
|
|
|
table->invisible = from->invisible;
|
|
|
|
|
2003-10-12 22:56:23 -05:00
|
|
|
table->refcount = 0;
|
2003-10-12 10:28:29 -05:00
|
|
|
|
2003-10-12 14:08:47 -05:00
|
|
|
/* Make copies of parents and children. Note that this can be
|
2003-10-12 22:56:23 -05:00
|
|
|
* a recursive copy ... treat as doubly-linked list. */
|
2003-10-12 14:08:47 -05:00
|
|
|
if (from->child)
|
|
|
|
{
|
|
|
|
table->child = gncTaxTableObtainTwin (from->child, book);
|
|
|
|
table->child->parent = table;
|
|
|
|
}
|
|
|
|
if (from->parent)
|
|
|
|
{
|
|
|
|
table->parent = gncTaxTableObtainTwin (from->parent, book);
|
|
|
|
table->parent->child = table;
|
|
|
|
}
|
2003-10-12 22:56:23 -05:00
|
|
|
for (node=g_list_last(from->children); node; node=node->next)
|
|
|
|
{
|
|
|
|
GncTaxTable *tbl = node->data;
|
|
|
|
tbl = gncTaxTableObtainTwin (tbl, book);
|
|
|
|
tbl->parent = table;
|
|
|
|
table->children = g_list_prepend(table->children, tbl);
|
|
|
|
}
|
2003-10-12 14:08:47 -05:00
|
|
|
|
2003-10-12 20:52:42 -05:00
|
|
|
/* Copy tax entries, preserving the order in the list */
|
|
|
|
table->entries = NULL;
|
|
|
|
for (node=g_list_last(from->entries); node; node=node->prev)
|
|
|
|
{
|
|
|
|
GncTaxTableEntry *ent = node->data;
|
|
|
|
ent = CloneTaxEntry (ent, book);
|
|
|
|
table->entries = g_list_prepend (table->entries, ent);
|
|
|
|
}
|
|
|
|
|
2003-10-12 10:28:29 -05:00
|
|
|
addObj (table);
|
2006-03-08 21:48:49 -06:00
|
|
|
qof_event_gen (&table->inst.entity, QOF_EVENT_CREATE, NULL);
|
2003-10-12 10:28:29 -05:00
|
|
|
return table;
|
|
|
|
}
|
|
|
|
|
2003-10-12 14:08:47 -05:00
|
|
|
GncTaxTable *
|
|
|
|
gncTaxTableObtainTwin (GncTaxTable *from, QofBook *book)
|
|
|
|
{
|
|
|
|
GncTaxTable *table;
|
|
|
|
if (!from) return NULL;
|
|
|
|
|
|
|
|
table = (GncTaxTable *) qof_instance_lookup_twin (QOF_INSTANCE(from), book);
|
|
|
|
if (!table)
|
|
|
|
{
|
|
|
|
table = gncCloneTaxTable (table, book);
|
|
|
|
}
|
|
|
|
return table;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-10-12 10:28:29 -05:00
|
|
|
void
|
|
|
|
gncTaxTableDestroy (GncTaxTable *table)
|
2002-11-03 14:21:42 -06:00
|
|
|
{
|
|
|
|
if (!table) return;
|
2003-10-11 19:42:56 -05:00
|
|
|
table->inst.do_free = TRUE;
|
2006-05-02 21:28:18 -05:00
|
|
|
qof_instance_set_dirty (&table->inst);
|
2002-11-03 14:21:42 -06:00
|
|
|
gncTaxTableCommitEdit (table);
|
|
|
|
}
|
|
|
|
|
2003-10-12 10:28:29 -05:00
|
|
|
static void
|
|
|
|
gncTaxTableFree (GncTaxTable *table)
|
2002-06-14 12:08:19 -05:00
|
|
|
{
|
|
|
|
GList *list;
|
2003-06-13 23:31:03 -05:00
|
|
|
GncTaxTable *child;
|
|
|
|
|
2002-06-14 12:08:19 -05:00
|
|
|
if (!table) return;
|
|
|
|
|
2006-03-08 21:48:49 -06:00
|
|
|
qof_event_gen (&table->inst.entity, QOF_EVENT_DESTROY, NULL);
|
2002-06-14 12:08:19 -05:00
|
|
|
CACHE_REMOVE (table->name);
|
|
|
|
remObj (table);
|
|
|
|
|
2003-06-13 23:31:03 -05:00
|
|
|
/* destroy the list of entries */
|
2002-06-14 12:08:19 -05:00
|
|
|
for (list = table->entries; list; list=list->next)
|
|
|
|
gncTaxTableEntryDestroy (list->data);
|
|
|
|
g_list_free (table->entries);
|
2003-06-13 23:31:03 -05:00
|
|
|
|
2003-10-11 19:42:56 -05:00
|
|
|
if (!table->inst.do_free)
|
2003-06-13 23:31:03 -05:00
|
|
|
PERR("free a taxtable without do_free set!");
|
|
|
|
|
2003-07-09 22:18:17 -05:00
|
|
|
/* disconnect from parent */
|
|
|
|
if (table->parent)
|
|
|
|
gncTaxTableRemoveChild(table->parent, table);
|
|
|
|
|
2003-06-13 23:31:03 -05:00
|
|
|
/* disconnect from the children */
|
|
|
|
for (list = table->children; list; list=list->next) {
|
|
|
|
child = list->data;
|
|
|
|
gncTaxTableSetParent(child, NULL);
|
|
|
|
}
|
|
|
|
g_list_free(table->children);
|
|
|
|
|
2003-10-11 19:42:56 -05:00
|
|
|
qof_instance_release (&table->inst);
|
2002-06-14 12:08:19 -05:00
|
|
|
g_free (table);
|
|
|
|
}
|
|
|
|
|
2003-10-12 20:52:42 -05:00
|
|
|
/* =============================================================== */
|
|
|
|
|
2002-06-14 12:08:19 -05:00
|
|
|
GncTaxTableEntry * gncTaxTableEntryCreate (void)
|
|
|
|
{
|
|
|
|
GncTaxTableEntry *entry;
|
|
|
|
entry = g_new0 (GncTaxTableEntry, 1);
|
|
|
|
entry->amount = gnc_numeric_zero ();
|
|
|
|
return entry;
|
|
|
|
}
|
|
|
|
|
|
|
|
void gncTaxTableEntryDestroy (GncTaxTableEntry *entry)
|
|
|
|
{
|
|
|
|
if (!entry) return;
|
|
|
|
g_free (entry);
|
|
|
|
}
|
|
|
|
|
2003-10-12 20:52:42 -05:00
|
|
|
/** Makes a clone. The account is from the appriate book.
|
|
|
|
* Note that the table is left blank (for performance reasons
|
|
|
|
* we set it above, when cloning the table).
|
|
|
|
*/
|
|
|
|
static GncTaxTableEntry *
|
|
|
|
CloneTaxEntry (GncTaxTableEntry*from, QofBook *book)
|
|
|
|
{
|
|
|
|
QofInstance *acc;
|
|
|
|
GncTaxTableEntry *entry;
|
|
|
|
entry = g_new0 (GncTaxTableEntry, 1);
|
|
|
|
|
|
|
|
entry->type = from->type;
|
|
|
|
entry->amount = from->amount;
|
|
|
|
|
|
|
|
acc = qof_instance_lookup_twin (QOF_INSTANCE(from->account), book);
|
|
|
|
entry->account = (Account *) acc;
|
|
|
|
return entry;
|
|
|
|
}
|
2002-06-14 12:08:19 -05:00
|
|
|
|
2003-10-12 10:28:29 -05:00
|
|
|
/* =============================================================== */
|
2002-06-14 12:08:19 -05:00
|
|
|
/* Set Functions */
|
2003-10-12 10:28:29 -05:00
|
|
|
|
2002-06-14 12:08:19 -05:00
|
|
|
void gncTaxTableSetName (GncTaxTable *table, const char *name)
|
|
|
|
{
|
|
|
|
if (!table || !name) return;
|
2002-11-03 18:41:01 -06:00
|
|
|
SET_STR (table, table->name, name);
|
2002-06-14 12:08:19 -05:00
|
|
|
mark_table (table);
|
2002-06-22 20:23:28 -05:00
|
|
|
maybe_resort_list (table);
|
2002-11-03 18:41:01 -06:00
|
|
|
gncTaxTableCommitEdit (table);
|
2002-06-14 12:08:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void gncTaxTableSetParent (GncTaxTable *table, GncTaxTable *parent)
|
|
|
|
{
|
|
|
|
if (!table) return;
|
2002-11-03 18:41:01 -06:00
|
|
|
gncTaxTableBeginEdit (table);
|
2003-06-13 23:31:03 -05:00
|
|
|
if (table->parent)
|
|
|
|
gncTaxTableRemoveChild(table->parent, table);
|
2002-06-14 12:08:19 -05:00
|
|
|
table->parent = parent;
|
2003-06-13 23:31:03 -05:00
|
|
|
if (parent)
|
|
|
|
gncTaxTableAddChild(parent, table);
|
2002-06-16 00:11:33 -05:00
|
|
|
table->refcount = 0;
|
2002-06-14 12:08:19 -05:00
|
|
|
gncTaxTableMakeInvisible (table);
|
2002-11-03 18:41:01 -06:00
|
|
|
gncTaxTableCommitEdit (table);
|
2002-06-14 12:08:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void gncTaxTableSetChild (GncTaxTable *table, GncTaxTable *child)
|
|
|
|
{
|
|
|
|
if (!table) return;
|
2002-11-03 18:41:01 -06:00
|
|
|
gncTaxTableBeginEdit (table);
|
2002-06-14 12:08:19 -05:00
|
|
|
table->child = child;
|
2002-11-03 18:41:01 -06:00
|
|
|
gncTaxTableCommitEdit (table);
|
2002-06-14 12:08:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void gncTaxTableIncRef (GncTaxTable *table)
|
|
|
|
{
|
|
|
|
if (!table) return;
|
2003-10-11 19:42:56 -05:00
|
|
|
if (table->parent || table->invisible) return; /* children dont need refcounts */
|
2002-11-03 18:41:01 -06:00
|
|
|
gncTaxTableBeginEdit (table);
|
2002-06-14 12:08:19 -05:00
|
|
|
table->refcount++;
|
2002-11-03 18:41:01 -06:00
|
|
|
gncTaxTableCommitEdit (table);
|
2002-06-14 12:08:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void gncTaxTableDecRef (GncTaxTable *table)
|
|
|
|
{
|
|
|
|
if (!table) return;
|
2003-10-11 19:42:56 -05:00
|
|
|
if (table->parent || table->invisible) return; /* children dont need refcounts */
|
2002-11-03 18:41:01 -06:00
|
|
|
gncTaxTableBeginEdit (table);
|
2002-06-14 12:08:19 -05:00
|
|
|
table->refcount--;
|
2002-06-16 00:11:33 -05:00
|
|
|
g_return_if_fail (table->refcount >= 0);
|
2002-11-03 18:41:01 -06:00
|
|
|
gncTaxTableCommitEdit (table);
|
2002-06-14 12:08:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void gncTaxTableSetRefcount (GncTaxTable *table, gint64 refcount)
|
|
|
|
{
|
|
|
|
if (!table) return;
|
|
|
|
table->refcount = refcount;
|
|
|
|
}
|
|
|
|
|
|
|
|
void gncTaxTableMakeInvisible (GncTaxTable *table)
|
|
|
|
{
|
2003-10-12 10:28:29 -05:00
|
|
|
struct _book_info *bi;
|
2002-06-14 12:08:19 -05:00
|
|
|
if (!table) return;
|
2002-11-03 18:41:01 -06:00
|
|
|
gncTaxTableBeginEdit (table);
|
2002-06-14 12:08:19 -05:00
|
|
|
table->invisible = TRUE;
|
2003-10-14 16:20:55 -05:00
|
|
|
bi = qof_book_get_data (table->inst.book, _GNC_MOD_NAME);
|
2003-10-12 10:28:29 -05:00
|
|
|
bi->tables = g_list_remove (bi->tables, table);
|
2002-11-03 18:41:01 -06:00
|
|
|
gncTaxTableCommitEdit (table);
|
2002-06-14 12:08:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void gncTaxTableEntrySetAccount (GncTaxTableEntry *entry, Account *account)
|
|
|
|
{
|
|
|
|
if (!entry || !account) return;
|
|
|
|
if (entry->account == account) return;
|
|
|
|
entry->account = account;
|
2002-06-16 00:11:33 -05:00
|
|
|
if (entry->table) {
|
2002-06-14 12:08:19 -05:00
|
|
|
mark_table (entry->table);
|
2002-06-16 00:11:33 -05:00
|
|
|
mod_table (entry->table);
|
|
|
|
}
|
2002-06-14 12:08:19 -05:00
|
|
|
}
|
|
|
|
|
2002-06-16 00:11:33 -05:00
|
|
|
void gncTaxTableEntrySetType (GncTaxTableEntry *entry, GncAmountType type)
|
2002-06-14 12:08:19 -05:00
|
|
|
{
|
|
|
|
if (!entry) return;
|
|
|
|
if (entry->type == type) return;
|
|
|
|
entry->type = type;
|
2002-06-16 00:11:33 -05:00
|
|
|
if (entry->table) {
|
2002-06-14 12:08:19 -05:00
|
|
|
mark_table (entry->table);
|
2002-06-16 00:11:33 -05:00
|
|
|
mod_table (entry->table);
|
|
|
|
}
|
2002-06-14 12:08:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void gncTaxTableEntrySetAmount (GncTaxTableEntry *entry, gnc_numeric amount)
|
|
|
|
{
|
|
|
|
if (!entry) return;
|
|
|
|
if (gnc_numeric_eq (entry->amount, amount)) return;
|
|
|
|
entry->amount = amount;
|
2002-06-16 00:11:33 -05:00
|
|
|
if (entry->table) {
|
2002-06-14 12:08:19 -05:00
|
|
|
mark_table (entry->table);
|
2002-06-16 00:11:33 -05:00
|
|
|
mod_table (entry->table);
|
|
|
|
}
|
2002-06-14 12:08:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void gncTaxTableAddEntry (GncTaxTable *table, GncTaxTableEntry *entry)
|
|
|
|
{
|
|
|
|
if (!table || !entry) return;
|
|
|
|
if (entry->table == table) return; /* already mine */
|
2002-11-03 18:41:01 -06:00
|
|
|
|
|
|
|
gncTaxTableBeginEdit (table);
|
2002-06-14 12:08:19 -05:00
|
|
|
if (entry->table)
|
|
|
|
gncTaxTableRemoveEntry (entry->table, entry);
|
|
|
|
|
|
|
|
entry->table = table;
|
|
|
|
table->entries = g_list_insert_sorted (table->entries, entry,
|
2003-10-11 19:42:56 -05:00
|
|
|
(GCompareFunc)gncTaxTableEntryCompare);
|
2002-06-14 12:08:19 -05:00
|
|
|
mark_table (table);
|
2002-06-16 00:11:33 -05:00
|
|
|
mod_table (table);
|
2002-11-03 18:41:01 -06:00
|
|
|
gncTaxTableCommitEdit (table);
|
2002-06-14 12:08:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void gncTaxTableRemoveEntry (GncTaxTable *table, GncTaxTableEntry *entry)
|
|
|
|
{
|
|
|
|
if (!table || !entry) return;
|
2002-11-03 18:41:01 -06:00
|
|
|
gncTaxTableBeginEdit (table);
|
2002-06-14 12:08:19 -05:00
|
|
|
entry->table = NULL;
|
|
|
|
table->entries = g_list_remove (table->entries, entry);
|
|
|
|
mark_table (table);
|
2002-06-16 00:11:33 -05:00
|
|
|
mod_table (table);
|
2002-11-03 18:41:01 -06:00
|
|
|
gncTaxTableCommitEdit (table);
|
2002-06-14 12:08:19 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void gncTaxTableChanged (GncTaxTable *table)
|
|
|
|
{
|
|
|
|
if (!table) return;
|
2002-11-03 18:41:01 -06:00
|
|
|
gncTaxTableBeginEdit (table);
|
2002-06-14 12:08:19 -05:00
|
|
|
table->child = NULL;
|
2002-11-03 18:41:01 -06:00
|
|
|
gncTaxTableCommitEdit (table);
|
2002-06-14 12:08:19 -05:00
|
|
|
}
|
|
|
|
|
2003-10-12 10:28:29 -05:00
|
|
|
/* =============================================================== */
|
|
|
|
|
2002-11-03 14:21:42 -06:00
|
|
|
void gncTaxTableBeginEdit (GncTaxTable *table)
|
2002-06-14 12:08:19 -05:00
|
|
|
{
|
2004-06-13 11:48:32 -05:00
|
|
|
QOF_BEGIN_EDIT (&table->inst);
|
2002-11-03 14:21:42 -06:00
|
|
|
}
|
2002-06-21 14:00:34 -05:00
|
|
|
|
2003-10-16 23:32:04 -05:00
|
|
|
static inline void gncTaxTableOnError (QofInstance *inst, QofBackendError errcode)
|
2002-11-03 14:21:42 -06:00
|
|
|
{
|
2003-06-26 22:36:02 -05:00
|
|
|
PERR("TaxTable QofBackend Failure: %d", errcode);
|
2002-11-03 14:21:42 -06:00
|
|
|
}
|
|
|
|
|
2003-10-16 23:32:04 -05:00
|
|
|
static inline void gncTaxTableOnDone (QofInstance *inst) {}
|
2003-10-11 19:42:56 -05:00
|
|
|
|
2003-10-16 23:32:04 -05:00
|
|
|
static inline void table_free (QofInstance *inst)
|
2003-10-11 19:42:56 -05:00
|
|
|
{
|
|
|
|
GncTaxTable *table = (GncTaxTable *) inst;
|
|
|
|
gncTaxTableFree (table);
|
2002-06-14 12:08:19 -05:00
|
|
|
}
|
|
|
|
|
2002-11-03 14:21:42 -06:00
|
|
|
void gncTaxTableCommitEdit (GncTaxTable *table)
|
|
|
|
{
|
2006-04-21 23:42:29 -05:00
|
|
|
if (!qof_commit_edit (QOF_INSTANCE(table))) return;
|
2006-02-26 12:36:05 -06:00
|
|
|
qof_commit_edit_part2 (&table->inst, gncTaxTableOnError,
|
2003-10-11 19:42:56 -05:00
|
|
|
gncTaxTableOnDone, table_free);
|
2002-11-03 14:21:42 -06:00
|
|
|
}
|
|
|
|
|
2002-06-14 12:08:19 -05:00
|
|
|
|
2003-10-12 10:28:29 -05:00
|
|
|
/* =============================================================== */
|
2002-06-14 12:08:19 -05:00
|
|
|
/* Get Functions */
|
2002-06-14 15:18:34 -05:00
|
|
|
|
2003-06-26 22:05:25 -05:00
|
|
|
GncTaxTable *gncTaxTableLookupByName (QofBook *book, const char *name)
|
2002-06-14 12:08:19 -05:00
|
|
|
{
|
|
|
|
GList *list = gncTaxTableGetTables (book);
|
|
|
|
|
|
|
|
for ( ; list; list = list->next) {
|
|
|
|
GncTaxTable *table = list->data;
|
|
|
|
if (!safe_strcmp (table->name, name))
|
|
|
|
return list->data;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2003-06-26 22:05:25 -05:00
|
|
|
GList * gncTaxTableGetTables (QofBook *book)
|
2002-06-14 12:08:19 -05:00
|
|
|
{
|
|
|
|
struct _book_info *bi;
|
|
|
|
if (!book) return NULL;
|
|
|
|
|
2003-10-14 16:20:55 -05:00
|
|
|
bi = qof_book_get_data (book, _GNC_MOD_NAME);
|
2002-06-14 12:08:19 -05:00
|
|
|
return bi->tables;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *gncTaxTableGetName (GncTaxTable *table)
|
|
|
|
{
|
|
|
|
if (!table) return NULL;
|
|
|
|
return table->name;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GncTaxTableEntry *gncTaxTableEntryCopy (GncTaxTableEntry *entry)
|
|
|
|
{
|
|
|
|
GncTaxTableEntry *e;
|
|
|
|
if (!entry) return NULL;
|
|
|
|
|
|
|
|
e = gncTaxTableEntryCreate ();
|
|
|
|
gncTaxTableEntrySetAccount (e, entry->account);
|
|
|
|
gncTaxTableEntrySetType (e, entry->type);
|
|
|
|
gncTaxTableEntrySetAmount (e, entry->amount);
|
|
|
|
|
|
|
|
return e;
|
|
|
|
}
|
|
|
|
|
|
|
|
static GncTaxTable *gncTaxTableCopy (GncTaxTable *table)
|
|
|
|
{
|
|
|
|
GncTaxTable *t;
|
|
|
|
GList *list;
|
|
|
|
|
|
|
|
if (!table) return NULL;
|
2003-10-11 19:42:56 -05:00
|
|
|
t = gncTaxTableCreate (table->inst.book);
|
2002-06-14 12:08:19 -05:00
|
|
|
gncTaxTableSetName (t, table->name);
|
|
|
|
for (list = table->entries; list; list=list->next) {
|
|
|
|
GncTaxTableEntry *entry, *e;
|
|
|
|
entry = list->data;
|
|
|
|
e = gncTaxTableEntryCopy (entry);
|
|
|
|
gncTaxTableAddEntry (t, e);
|
|
|
|
}
|
|
|
|
return t;
|
|
|
|
}
|
|
|
|
|
2002-06-14 15:18:34 -05:00
|
|
|
GncTaxTable *gncTaxTableReturnChild (GncTaxTable *table, gboolean make_new)
|
2002-06-14 12:08:19 -05:00
|
|
|
{
|
|
|
|
GncTaxTable *child = NULL;
|
|
|
|
|
|
|
|
if (!table) return NULL;
|
|
|
|
if (table->child) return table->child;
|
2003-06-13 23:31:03 -05:00
|
|
|
if (table->parent || table->invisible) return table;
|
2002-06-14 12:08:19 -05:00
|
|
|
if (make_new) {
|
|
|
|
child = gncTaxTableCopy (table);
|
|
|
|
gncTaxTableSetChild (table, child);
|
|
|
|
gncTaxTableSetParent (child, table);
|
|
|
|
}
|
|
|
|
return child;
|
|
|
|
}
|
|
|
|
|
|
|
|
GncTaxTable *gncTaxTableGetParent (GncTaxTable *table)
|
|
|
|
{
|
|
|
|
if (!table) return NULL;
|
|
|
|
return table->parent;
|
|
|
|
}
|
|
|
|
|
|
|
|
GList *gncTaxTableGetEntries (GncTaxTable *table)
|
|
|
|
{
|
|
|
|
if (!table) return NULL;
|
|
|
|
return table->entries;
|
|
|
|
}
|
|
|
|
|
|
|
|
gint64 gncTaxTableGetRefcount (GncTaxTable *table)
|
|
|
|
{
|
|
|
|
if (!table) return 0;
|
|
|
|
return table->refcount;
|
|
|
|
}
|
|
|
|
|
2002-06-16 00:11:33 -05:00
|
|
|
Timespec gncTaxTableLastModified (GncTaxTable *table)
|
|
|
|
{
|
|
|
|
Timespec ts = { 0 , 0 };
|
|
|
|
if (!table) return ts;
|
|
|
|
return table->modtime;
|
|
|
|
}
|
|
|
|
|
2002-06-14 12:08:19 -05:00
|
|
|
gboolean gncTaxTableGetInvisible (GncTaxTable *table)
|
|
|
|
{
|
|
|
|
if (!table) return FALSE;
|
|
|
|
return table->invisible;
|
|
|
|
}
|
|
|
|
|
|
|
|
Account * gncTaxTableEntryGetAccount (GncTaxTableEntry *entry)
|
|
|
|
{
|
|
|
|
if (!entry) return NULL;
|
|
|
|
return entry->account;
|
|
|
|
}
|
|
|
|
|
2002-06-16 00:11:33 -05:00
|
|
|
GncAmountType gncTaxTableEntryGetType (GncTaxTableEntry *entry)
|
2002-06-14 12:08:19 -05:00
|
|
|
{
|
2002-06-16 00:11:33 -05:00
|
|
|
if (!entry) return 0;
|
2002-06-14 12:08:19 -05:00
|
|
|
return entry->type;
|
|
|
|
}
|
|
|
|
|
|
|
|
gnc_numeric gncTaxTableEntryGetAmount (GncTaxTableEntry *entry)
|
|
|
|
{
|
|
|
|
if (!entry) return gnc_numeric_zero();
|
|
|
|
return entry->amount;
|
|
|
|
}
|
|
|
|
|
|
|
|
int gncTaxTableEntryCompare (GncTaxTableEntry *a, GncTaxTableEntry *b)
|
|
|
|
{
|
|
|
|
char *name_a, *name_b;
|
|
|
|
int retval;
|
|
|
|
|
|
|
|
if (!a && !b) return 0;
|
|
|
|
if (!a) return -1;
|
|
|
|
if (!b) return 1;
|
|
|
|
|
2006-03-02 01:20:33 -06:00
|
|
|
name_a = xaccAccountGetFullName (a->account);
|
|
|
|
name_b = xaccAccountGetFullName (b->account);
|
2002-06-14 12:08:19 -05:00
|
|
|
retval = safe_strcmp(name_a, name_b);
|
|
|
|
g_free(name_a);
|
|
|
|
g_free(name_b);
|
|
|
|
|
|
|
|
if (retval)
|
|
|
|
return retval;
|
|
|
|
|
|
|
|
return gnc_numeric_compare (a->amount, b->amount);
|
|
|
|
}
|
|
|
|
|
|
|
|
int gncTaxTableCompare (GncTaxTable *a, GncTaxTable *b)
|
|
|
|
{
|
|
|
|
if (!a && !b) return 0;
|
|
|
|
if (!a) return -1;
|
|
|
|
if (!b) return 1;
|
|
|
|
return safe_strcmp (a->name, b->name);
|
|
|
|
}
|
|
|
|
|
2002-06-16 00:11:33 -05:00
|
|
|
|
|
|
|
/*
|
|
|
|
* This will add value to the account-value for acc, creating a new
|
|
|
|
* list object if necessary
|
|
|
|
*/
|
|
|
|
GList *gncAccountValueAdd (GList *list, Account *acc, gnc_numeric value)
|
|
|
|
{
|
|
|
|
GList *li;
|
|
|
|
GncAccountValue *res = NULL;
|
|
|
|
|
|
|
|
g_return_val_if_fail (acc, list);
|
|
|
|
g_return_val_if_fail (gnc_numeric_check (value) == GNC_ERROR_OK, list);
|
|
|
|
|
|
|
|
/* Try to find the account in the list */
|
|
|
|
for (li = list; li; li = li->next) {
|
|
|
|
res = li->data;
|
|
|
|
if (res->account == acc) {
|
|
|
|
res->value = gnc_numeric_add (res->value, value, GNC_DENOM_AUTO,
|
2003-10-11 19:42:56 -05:00
|
|
|
GNC_DENOM_LCD);
|
2002-06-16 00:11:33 -05:00
|
|
|
return list;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Nope, didn't find it. */
|
|
|
|
|
|
|
|
res = g_new0 (GncAccountValue, 1);
|
|
|
|
res->account = acc;
|
|
|
|
res->value = value;
|
|
|
|
return g_list_prepend (list, res);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Merge l2 into l1. l2 is not touched. */
|
|
|
|
GList *gncAccountValueAddList (GList *l1, GList *l2)
|
|
|
|
{
|
|
|
|
GList *li;
|
|
|
|
|
|
|
|
for (li = l2; li; li = li->next ) {
|
|
|
|
GncAccountValue *val = li->data;
|
|
|
|
l1 = gncAccountValueAdd (l1, val->account, val->value);
|
|
|
|
}
|
|
|
|
|
|
|
|
return l1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* return the total for this list */
|
|
|
|
gnc_numeric gncAccountValueTotal (GList *list)
|
|
|
|
{
|
|
|
|
gnc_numeric total = gnc_numeric_zero ();
|
|
|
|
|
|
|
|
for ( ; list ; list = list->next) {
|
|
|
|
GncAccountValue *val = list->data;
|
|
|
|
total = gnc_numeric_add (total, val->value, GNC_DENOM_AUTO, GNC_DENOM_LCD);
|
|
|
|
}
|
|
|
|
return total;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Destroy a list of accountvalues */
|
|
|
|
void gncAccountValueDestroy (GList *list)
|
|
|
|
{
|
|
|
|
GList *node;
|
|
|
|
for ( node = list; node ; node = node->next)
|
|
|
|
g_free (node->data);
|
|
|
|
|
|
|
|
g_list_free (list);
|
|
|
|
}
|
|
|
|
|
2002-06-14 12:08:19 -05:00
|
|
|
/* Package-Private functions */
|
|
|
|
|
2003-06-26 22:05:25 -05:00
|
|
|
static void _gncTaxTableCreate (QofBook *book)
|
2002-06-14 12:08:19 -05:00
|
|
|
{
|
|
|
|
struct _book_info *bi;
|
|
|
|
|
|
|
|
if (!book) return;
|
|
|
|
|
|
|
|
bi = g_new0 (struct _book_info, 1);
|
2003-10-14 16:20:55 -05:00
|
|
|
qof_book_set_data (book, _GNC_MOD_NAME, bi);
|
2002-06-14 12:08:19 -05:00
|
|
|
}
|
|
|
|
|
2003-06-26 22:05:25 -05:00
|
|
|
static void _gncTaxTableDestroy (QofBook *book)
|
2002-06-14 12:08:19 -05:00
|
|
|
{
|
|
|
|
struct _book_info *bi;
|
|
|
|
|
|
|
|
if (!book) return;
|
|
|
|
|
2003-10-14 16:20:55 -05:00
|
|
|
bi = qof_book_get_data (book, _GNC_MOD_NAME);
|
2002-06-14 12:08:19 -05:00
|
|
|
|
|
|
|
g_list_free (bi->tables);
|
|
|
|
g_free (bi);
|
|
|
|
}
|
|
|
|
|
2003-10-11 19:42:56 -05:00
|
|
|
static QofObject gncTaxTableDesc =
|
|
|
|
{
|
2003-10-19 00:13:59 -05:00
|
|
|
interface_version: QOF_OBJECT_VERSION,
|
|
|
|
e_type: _GNC_MOD_NAME,
|
|
|
|
type_label: "Tax Table",
|
2004-08-19 14:47:34 -05:00
|
|
|
create: (gpointer)gncTaxTableCreate,
|
2003-10-19 00:13:59 -05:00
|
|
|
book_begin: _gncTaxTableCreate,
|
|
|
|
book_end: _gncTaxTableDestroy,
|
|
|
|
is_dirty: qof_collection_is_dirty,
|
|
|
|
mark_clean: qof_collection_mark_clean,
|
|
|
|
foreach: qof_collection_foreach,
|
|
|
|
printable: NULL,
|
2004-06-12 15:27:08 -05:00
|
|
|
version_cmp: (int (*)(gpointer, gpointer)) qof_instance_version_cmp,
|
2002-06-14 12:08:19 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
gboolean gncTaxTableRegister (void)
|
|
|
|
{
|
2003-09-27 05:21:27 -05:00
|
|
|
static QofParam params[] = {
|
2004-10-16 10:51:26 -05:00
|
|
|
{ GNC_TT_NAME, QOF_TYPE_STRING, (QofAccessFunc)gncTaxTableGetName, (QofSetterFunc)gncTaxTableSetName },
|
|
|
|
{ GNC_TT_REFCOUNT, QOF_TYPE_INT64, (QofAccessFunc)gncTaxTableGetRefcount, (QofSetterFunc)gncTaxTableSetRefcount },
|
|
|
|
{ QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
|
|
|
|
{ QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
|
2002-06-14 12:08:19 -05:00
|
|
|
{ NULL },
|
|
|
|
};
|
|
|
|
|
2003-09-27 11:33:06 -05:00
|
|
|
qof_class_register (_GNC_MOD_NAME, (QofSortFunc)gncTaxTableCompare, params);
|
2002-06-14 12:08:19 -05:00
|
|
|
|
2003-06-26 22:09:39 -05:00
|
|
|
return qof_object_register (&gncTaxTableDesc);
|
2002-06-14 12:08:19 -05:00
|
|
|
}
|
2004-08-19 14:47:34 -05:00
|
|
|
|
|
|
|
/* need a QOF tax table entry object */
|
|
|
|
//gncTaxTableEntrySetType_q int32
|
|
|
|
//gint gncTaxTableEntryGetType_q (GncTaxTableEntry *entry);
|