31 #include "gnc-xml-helper.h"
34 #include "sixtp-utils.h"
35 #include "sixtp-parsers.h"
36 #include "sixtp-utils.h"
37 #include "sixtp-dom-parsers.h"
38 #include "sixtp-dom-generators.h"
41 #include "io-gncxml-gen.h"
45 #include "gncTaxTableP.h"
46 #include "gnc-tax-table-xml-v2.h"
48 #define _GNC_MOD_NAME GNC_ID_TAXTABLE
52 const gchar *taxtable_version_string =
"2.0.0";
55 #define gnc_taxtable_string "gnc:GncTaxTable"
56 #define taxtable_guid_string "taxtable:guid"
57 #define taxtable_name_string "taxtable:name"
58 #define taxtable_refcount_string "taxtable:refcount"
59 #define taxtable_invisible_string "taxtable:invisible"
60 #define taxtable_parent_string "taxtable:parent"
61 #define taxtable_child_string "taxtable:child"
62 #define taxtable_entries_string "taxtable:entries"
63 #define taxtable_slots_string "taxtable:slots"
65 #define gnc_taxtableentry_string "gnc:GncTaxTableEntry"
66 #define ttentry_account_string "tte:acct"
67 #define ttentry_type_string "tte:type"
68 #define ttentry_amount_string "tte:amount"
77 xmlAddChild (ptr, guid_to_dom_tree (tag,
88 ret = xmlNewNode(NULL, BAD_CAST gnc_taxtableentry_string);
90 account = gncTaxTableEntryGetAccount (entry);
92 xmlAddChild(ret, guid_to_dom_tree (ttentry_account_string,
95 amount = gncTaxTableEntryGetAmount (entry);
96 xmlAddChild (ret, gnc_numeric_to_dom_tree (ttentry_amount_string, &amount));
98 xmlAddChild(ret, text_to_dom_tree (ttentry_type_string,
99 gncAmountTypeToString (
100 gncTaxTableEntryGetType (entry))));
108 xmlNodePtr ret, entries;
112 ret = xmlNewNode(NULL, BAD_CAST gnc_taxtable_string);
113 xmlSetProp(ret, BAD_CAST
"version", BAD_CAST taxtable_version_string);
115 maybe_add_guid(ret, taxtable_guid_string, table);
116 xmlAddChild(ret, text_to_dom_tree (taxtable_name_string,
117 gncTaxTableGetName (table)));
119 xmlAddChild(ret, int_to_dom_tree (taxtable_refcount_string,
120 gncTaxTableGetRefcount (table)));
121 xmlAddChild(ret, int_to_dom_tree (taxtable_invisible_string,
122 gncTaxTableGetInvisible (table)));
125 if (gncTaxTableGetChild(table) != table)
126 maybe_add_guid(ret, taxtable_child_string, gncTaxTableGetChild (table));
128 maybe_add_guid(ret, taxtable_parent_string, gncTaxTableGetParent (table));
130 entries = xmlNewChild (ret, NULL, BAD_CAST taxtable_entries_string, NULL);
131 for (list = gncTaxTableGetEntries (table); list; list = list->next)
134 xmlAddChild(entries, ttentry_dom_tree_create (entry));
137 kf = qof_instance_get_slots (QOF_INSTANCE(table));
140 xmlNodePtr kvpnode = kvp_frame_to_dom_tree(taxtable_slots_string, kf);
143 xmlAddChild(ret, kvpnode);
159 ttentry_acct_handler (xmlNodePtr node, gpointer
ttentry_pdata)
161 struct ttentry_pdata *pdata = ttentry_pdata;
165 guid = dom_tree_to_guid (node);
166 g_return_val_if_fail (guid, FALSE);
169 g_return_val_if_fail (acc, FALSE);
171 gncTaxTableEntrySetAccount (pdata->ttentry, acc);
183 str = dom_tree_to_text (node);
184 g_return_val_if_fail (str, FALSE);
186 ret = gncAmountStringToType (str, &type);
190 gncTaxTableEntrySetType (pdata->ttentry, type);
196 ttentry_amount_handler (xmlNodePtr node, gpointer
ttentry_pdata)
198 struct ttentry_pdata *pdata = ttentry_pdata;
200 g_return_val_if_fail(num, FALSE);
202 gncTaxTableEntrySetAmount (pdata->ttentry, *num);
209 { ttentry_account_string, ttentry_acct_handler, 0, 0 },
210 { ttentry_type_string, ttentry_type_handler, 1, 0 },
211 { ttentry_amount_string, ttentry_amount_handler, 1, 0 },
216 dom_tree_to_ttentry (xmlNodePtr node,
QofBook *book)
224 successful = dom_tree_generic_parse (node, ttentry_handlers_v2,
229 PERR (
"failed to parse tax table entry tree");
239 struct taxtable_pdata
246 set_parent_child (xmlNodePtr node,
struct taxtable_pdata *pdata,
252 guid = dom_tree_to_guid(node);
253 g_return_val_if_fail (guid, FALSE);
254 table = gncTaxTableLookup (pdata->book, guid);
257 if (table == pdata->table)
259 PINFO (
"found a self-referential parent/child; ignoring.\n");
265 table = gncTaxTableCreate (pdata->book);
266 gncTaxTableBeginEdit (table);
267 gncTaxTableSetGUID (table, guid);
268 gncTaxTableCommitEdit (table);
271 g_return_val_if_fail (table, FALSE);
272 func (pdata->table, table);
278 taxtable_guid_handler (xmlNodePtr node, gpointer taxtable_pdata)
280 struct taxtable_pdata *pdata = taxtable_pdata;
284 guid = dom_tree_to_guid(node);
285 g_return_val_if_fail (guid, FALSE);
286 table = gncTaxTableLookup (pdata->book, guid);
289 gncTaxTableDestroy (pdata->table);
290 pdata->table = table;
291 gncTaxTableBeginEdit (table);
295 gncTaxTableSetGUID(pdata->table, guid);
304 taxtable_name_handler (xmlNodePtr node, gpointer taxtable_pdata)
306 struct taxtable_pdata *pdata = taxtable_pdata;
307 char* txt = dom_tree_to_text(node);
308 g_return_val_if_fail(txt, FALSE);
310 gncTaxTableSetName (pdata->table, txt);
316 taxtable_refcount_handler (xmlNodePtr node, gpointer taxtable_pdata)
318 struct taxtable_pdata *pdata = taxtable_pdata;
321 dom_tree_to_integer(node, &val);
322 gncTaxTableSetRefcount (pdata->table, val);
327 taxtable_invisible_handler (xmlNodePtr node, gpointer taxtable_pdata)
329 struct taxtable_pdata *pdata = taxtable_pdata;
332 dom_tree_to_integer(node, &val);
334 gncTaxTableMakeInvisible (pdata->table);
339 taxtable_parent_handler (xmlNodePtr node, gpointer taxtable_pdata)
341 struct taxtable_pdata *pdata = taxtable_pdata;
342 return set_parent_child (node, pdata, gncTaxTableSetParent);
346 taxtable_child_handler (xmlNodePtr node, gpointer taxtable_pdata)
348 struct taxtable_pdata *pdata = taxtable_pdata;
349 return set_parent_child (node, pdata, gncTaxTableSetChild);
353 taxtable_entries_handler (xmlNodePtr node, gpointer taxtable_pdata)
355 struct taxtable_pdata *pdata = taxtable_pdata;
358 g_return_val_if_fail (node, FALSE);
359 g_return_val_if_fail (node->xmlChildrenNode, FALSE);
361 for (mark = node->xmlChildrenNode; mark; mark = mark->next)
365 if (g_strcmp0 (
"text", (
char*)mark->name) == 0)
368 if (g_strcmp0 (gnc_taxtableentry_string, (
char*)mark->name))
371 entry = dom_tree_to_ttentry (mark, pdata->book);
374 gncTaxTableAddEntry (pdata->table, entry);
383 taxtable_slots_handler (xmlNodePtr node, gpointer taxtable_pdata)
385 struct taxtable_pdata *pdata = taxtable_pdata;
387 return dom_tree_to_kvp_frame_given
388 (node, qof_instance_get_slots (QOF_INSTANCE (pdata->table)));
393 { taxtable_guid_string, taxtable_guid_handler, 1, 0 },
394 { taxtable_name_string, taxtable_name_handler, 1, 0 },
395 { taxtable_refcount_string, taxtable_refcount_handler, 1, 0 },
396 { taxtable_invisible_string, taxtable_invisible_handler, 1, 0 },
397 { taxtable_parent_string, taxtable_parent_handler, 0, 0 },
398 { taxtable_child_string, taxtable_child_handler, 0, 0 },
399 { taxtable_entries_string, taxtable_entries_handler, 1, 0 },
400 { taxtable_slots_string, taxtable_slots_handler, 0, 0 },
405 dom_tree_to_taxtable (xmlNodePtr node,
QofBook *book)
407 struct taxtable_pdata taxtable_pdata;
410 taxtable_pdata.table = gncTaxTableCreate (book);
411 taxtable_pdata.book = book;
412 gncTaxTableBeginEdit (taxtable_pdata.table);
414 successful = dom_tree_generic_parse (node, taxtable_handlers_v2,
418 gncTaxTableCommitEdit (taxtable_pdata.table);
421 PERR (
"failed to parse tax table tree");
422 gncTaxTableDestroy (taxtable_pdata.table);
423 taxtable_pdata.table = NULL;
426 return taxtable_pdata.table;
430 gnc_taxtable_end_handler(gpointer data_for_children,
431 GSList* data_from_children, GSList* sibling_data,
432 gpointer parent_data, gpointer global_data,
433 gpointer *result,
const gchar *tag)
436 xmlNodePtr tree = (xmlNodePtr)data_for_children;
438 QofBook *book = gdata->bookdata;
452 g_return_val_if_fail(tree, FALSE);
454 table = dom_tree_to_taxtable (tree, book);
457 gdata->cb(tag, gdata->parsedata, table);
462 return table != NULL;
466 taxtable_sixtp_parser_create(
void)
468 return sixtp_dom_parser_new(gnc_taxtable_end_handler, NULL, NULL);
474 int *count = count_p;
479 taxtable_get_count (
QofBook *book)
487 xml_add_taxtable (
QofInstance * table_p, gpointer out_p)
496 node = taxtable_dom_tree_create (table);
497 xmlElemDump(out, NULL, node);
499 if (ferror(out) || fprintf(out,
"\n") < 0)
504 taxtable_write (FILE *out,
QofBook *book)
507 return ferror(out) == 0;
514 return (gncTaxTableGetParent(gncTaxTableGetParent(table)) != NULL);
526 parent = gncTaxTableGetParent(temp);
529 gp = gncTaxTableGetParent(parent);
546 g_assert (gp == NULL);
554 taxtable_scrub_cb (
QofInstance * table_p, gpointer list_p)
557 GList **list = list_p;
559 if (taxtable_is_grandchild(table) || gncTaxTableGetEntries(table) == NULL)
560 *list = g_list_prepend(*list, table);
567 taxtable_scrub_entries (
QofInstance * entry_p, gpointer ht_p)
569 GHashTable *ht = ht_p;
570 GncEntry *entry = GNC_ENTRY(entry_p);
574 table = gncEntryGetInvTaxTable(entry);
577 if (taxtable_is_grandchild(table))
581 PINFO(
"Fixing i-taxtable on entry %s\n",guidstr);
582 new_tt = taxtable_find_senior(table);
583 gncEntryBeginEdit(entry);
584 gncEntrySetInvTaxTable(entry, new_tt);
585 gncEntryCommitEdit(entry);
590 count = GPOINTER_TO_INT(g_hash_table_lookup(ht, table));
592 g_hash_table_insert(ht, table, GINT_TO_POINTER(count));
596 table = gncEntryGetBillTaxTable(entry);
599 if (taxtable_is_grandchild(table))
603 PINFO(
"Fixing b-taxtable on entry %s\n",guidstr);
604 new_tt = taxtable_find_senior(table);
605 gncEntryBeginEdit(entry);
606 gncEntrySetBillTaxTable(entry, new_tt);
607 gncEntryCommitEdit(entry);
612 count = GPOINTER_TO_INT(g_hash_table_lookup(ht, table));
614 g_hash_table_insert(ht, table, GINT_TO_POINTER(count));
620 taxtable_scrub_cust (
QofInstance * cust_p, gpointer ht_p)
622 GHashTable *ht = ht_p;
627 table = gncCustomerGetTaxTable(cust);
630 count = GPOINTER_TO_INT(g_hash_table_lookup(ht, table));
632 g_hash_table_insert(ht, table, GINT_TO_POINTER(count));
637 taxtable_scrub_vendor (
QofInstance * vendor_p, gpointer ht_p)
639 GHashTable *ht = ht_p;
640 GncVendor *vendor = GNC_VENDOR(vendor_p);
644 table = gncVendorGetTaxTable(vendor);
647 count = GPOINTER_TO_INT(g_hash_table_lookup(ht, table));
649 g_hash_table_insert(ht, table, GINT_TO_POINTER(count));
654 taxtable_reset_refcount (gpointer key, gpointer value, gpointer notused)
657 gint32 count = GPOINTER_TO_INT(value);
659 if (count != gncTaxTableGetRefcount(table) && !gncTaxTableGetInvisible(table))
663 PWARN(
"Fixing refcount on taxtable %s (%" G_GINT64_FORMAT
" -> %d)\n",
664 guidstr,gncTaxTableGetRefcount(table), count);
665 gncTaxTableSetRefcount(table, count);
675 GHashTable *ht = g_hash_table_new(g_direct_hash, g_direct_equal);
683 for (node = list; node; node = node->next)
689 PINFO (
"deleting grandchild taxtable: %s\n", guidstr);
692 parent = gncTaxTableGetParent(table);
693 gncTaxTableSetChild(parent, NULL);
696 gncTaxTableBeginEdit(table);
697 gncTaxTableDestroy(table);
701 g_hash_table_foreach(ht, taxtable_reset_refcount, NULL);
704 g_hash_table_destroy(ht);
708 taxtable_ns(FILE *out)
710 g_return_val_if_fail(out, FALSE);
717 gnc_taxtable_xml_initialize (
void)
721 GNC_FILE_BACKEND_VERS,
723 taxtable_sixtp_parser_create,
gboolean qof_object_register_backend(QofIdTypeConst type_name, const char *backend_name, gpointer be_data)
const GncGUID * qof_instance_get_guid(gconstpointer)
#define PINFO(format, args...)
gchar * guid_to_string_buff(const GncGUID *guid, gchar *buff)
#define PERR(format, args...)
#define PWARN(format, args...)
void qof_object_foreach_sorted(QofIdTypeConst type_name, QofBook *book, QofInstanceForeachCB cb, gpointer user_data)
api for GnuCash version 2 XML-based file format
#define GUID_ENCODING_LENGTH
void qof_object_foreach(QofIdTypeConst type_name, QofBook *book, QofInstanceForeachCB cb, gpointer user_data)
gboolean gnc_xml2_write_namespace_decl(FILE *out, const char *name_space)
struct KvpFrameImpl KvpFrame
Business Entry Interface.
const gchar * QofLogModule
Account * xaccAccountLookup(const GncGUID *guid, QofBook *book)