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"
44 #include "gncBillTermP.h"
46 #include "gnc-bill-term-xml-v2.h"
49 #include "xml-helpers.h"
51 #define _GNC_MOD_NAME GNC_ID_BILLTERM
55 const gchar *billterm_version_string =
"2.0.0";
58 #define gnc_billterm_string "gnc:GncBillTerm"
59 #define billterm_guid_string "billterm:guid"
60 #define billterm_name_string "billterm:name"
61 #define billterm_desc_string "billterm:desc"
62 #define billterm_refcount_string "billterm:refcount"
63 #define billterm_invisible_string "billterm:invisible"
64 #define billterm_parent_string "billterm:parent"
65 #define billterm_child_string "billterm:child"
66 #define billterm_slots_string "billterm:slots"
68 #define gnc_daystype_string "billterm:days"
69 #define days_duedays_string "bt-days:due-days"
70 #define days_discdays_string "bt-days:disc-days"
71 #define days_discount_string "bt-days:discount"
73 #define gnc_proximotype_string "billterm:proximo"
74 #define prox_dueday_string "bt-prox:due-day"
75 #define prox_discday_string "bt-prox:disc-day"
76 #define prox_discount_string "bt-prox:discount"
77 #define prox_cutoff_string "bt-prox:cutoff-day"
82 xmlNodePtr ret, data, kvpnode;
84 ret = xmlNewNode(NULL, BAD_CAST gnc_billterm_string);
85 xmlSetProp(ret, BAD_CAST
"version", BAD_CAST billterm_version_string);
87 maybe_add_guid(ret, billterm_guid_string, QOF_INSTANCE(term));
88 xmlAddChild(ret, text_to_dom_tree (billterm_name_string,
89 gncBillTermGetName (term)));
90 xmlAddChild(ret, text_to_dom_tree (billterm_desc_string,
91 gncBillTermGetDescription (term)));
93 xmlAddChild(ret, int_to_dom_tree (billterm_refcount_string,
94 gncBillTermGetRefcount (term)));
95 xmlAddChild(ret, int_to_dom_tree (billterm_invisible_string,
96 gncBillTermGetInvisible (term)));
98 kvpnode = kvp_frame_to_dom_tree (billterm_slots_string,
99 qof_instance_get_slots (QOF_INSTANCE(term)));
100 if (kvpnode) xmlAddChild (ret, kvpnode);
104 if (gncBillTermGetChild(term) != term)
105 maybe_add_guid(ret, billterm_child_string,
106 QOF_INSTANCE(gncBillTermGetChild (term)));
108 maybe_add_guid(ret, billterm_parent_string,
109 QOF_INSTANCE(gncBillTermGetParent (term)));
111 switch (gncBillTermGetType (term))
113 case GNC_TERM_TYPE_DAYS:
114 data = xmlNewChild (ret, NULL, BAD_CAST gnc_daystype_string, NULL);
115 maybe_add_int (data, days_duedays_string, gncBillTermGetDueDays (term));
116 maybe_add_int (data, days_discdays_string,
117 gncBillTermGetDiscountDays (term));
118 maybe_add_numeric (data, days_discount_string,
119 gncBillTermGetDiscount (term));
122 case GNC_TERM_TYPE_PROXIMO:
123 data = xmlNewChild (ret, NULL, BAD_CAST gnc_proximotype_string, NULL);
124 maybe_add_int (data, prox_dueday_string, gncBillTermGetDueDays (term));
125 maybe_add_int (data, prox_discday_string,
126 gncBillTermGetDiscountDays (term));
127 maybe_add_numeric (data, prox_discount_string,
128 gncBillTermGetDiscount (term));
129 maybe_add_int (data, prox_cutoff_string, gncBillTermGetCutoff (term));
149 dom_tree_to_integer (node, &val);
159 g_return_val_if_fail (num, FALSE);
171 struct billterm_pdata *pdata = billterm_pdata;
172 return set_int (node, pdata->term, gncBillTermSetDueDays);
178 struct billterm_pdata *pdata = billterm_pdata;
179 return set_int (node, pdata->term, gncBillTermSetDiscountDays);
185 struct billterm_pdata *pdata = billterm_pdata;
186 return set_numeric (node, pdata->term, gncBillTermSetDiscount);
191 { days_duedays_string, days_duedays_handler, 0, 0 },
192 { days_discdays_string, days_discdays_handler, 0, 0 },
193 { days_discount_string, days_discount_handler, 0, 0 },
198 dom_tree_to_days_data (xmlNodePtr node,
struct billterm_pdata *pdata)
202 successful = dom_tree_generic_parse (node, days_data_handlers_v2, pdata);
205 PERR (
"failed to parse billing term days data");
215 struct billterm_pdata *pdata = billterm_pdata;
216 return set_int (node, pdata->term, gncBillTermSetDueDays);
222 struct billterm_pdata *pdata = billterm_pdata;
223 return set_int (node, pdata->term, gncBillTermSetDiscountDays);
229 struct billterm_pdata *pdata = billterm_pdata;
230 return set_numeric (node, pdata->term, gncBillTermSetDiscount);
236 struct billterm_pdata *pdata = billterm_pdata;
237 return set_int (node, pdata->term, gncBillTermSetCutoff);
242 { prox_dueday_string, prox_dueday_handler, 0, 0 },
243 { prox_discday_string, prox_discday_handler, 0, 0 },
244 { prox_discount_string, prox_discount_handler, 0, 0 },
245 { prox_cutoff_string, prox_cutoff_handler, 0, 0 },
250 dom_tree_to_prox_data (xmlNodePtr node,
struct billterm_pdata *pdata)
254 successful = dom_tree_generic_parse (node, prox_data_handlers_v2, pdata);
257 PERR (
"failed to parse billing term prox data");
271 guid = dom_tree_to_guid(node);
272 g_return_val_if_fail (guid, FALSE);
273 term = gncBillTermLookup (pdata->book, guid);
276 term = gncBillTermCreate (pdata->book);
277 gncBillTermBeginEdit (term);
278 gncBillTermSetGUID (term, guid);
279 gncBillTermCommitEdit (term);
282 g_return_val_if_fail (term, FALSE);
283 func (pdata->term, term);
292 char* txt = dom_tree_to_text(node);
293 g_return_val_if_fail(txt, FALSE);
302 struct billterm_pdata *pdata = billterm_pdata;
306 guid = dom_tree_to_guid(node);
307 g_return_val_if_fail (guid, FALSE);
308 term = gncBillTermLookup (pdata->book, guid);
311 gncBillTermDestroy (pdata->term);
313 gncBillTermBeginEdit (term);
317 gncBillTermSetGUID(pdata->term, guid);
326 billterm_name_handler (xmlNodePtr node, gpointer billterm_pdata)
328 struct billterm_pdata *pdata = billterm_pdata;
329 return set_string (node, pdata->term, gncBillTermSetName);
333 billterm_desc_handler (xmlNodePtr node, gpointer billterm_pdata)
335 struct billterm_pdata *pdata = billterm_pdata;
336 return set_string (node, pdata->term, gncBillTermSetDescription);
340 billterm_refcount_handler (xmlNodePtr node, gpointer billterm_pdata)
342 struct billterm_pdata *pdata = billterm_pdata;
345 dom_tree_to_integer(node, &val);
346 gncBillTermSetRefcount (pdata->term, val);
351 billterm_invisible_handler (xmlNodePtr node, gpointer billterm_pdata)
353 struct billterm_pdata *pdata = billterm_pdata;
356 dom_tree_to_integer(node, &val);
358 gncBillTermMakeInvisible (pdata->term);
363 billterm_parent_handler (xmlNodePtr node, gpointer billterm_pdata)
365 struct billterm_pdata *pdata = billterm_pdata;
366 return set_parent_child (node, pdata, gncBillTermSetParent);
370 billterm_child_handler (xmlNodePtr node, gpointer billterm_pdata)
372 struct billterm_pdata *pdata = billterm_pdata;
373 return set_parent_child (node, pdata, gncBillTermSetChild);
377 billterm_days_data_handler (xmlNodePtr node, gpointer billterm_pdata)
379 struct billterm_pdata *pdata = billterm_pdata;
381 g_return_val_if_fail (node, FALSE);
382 g_return_val_if_fail (gncBillTermGetType (pdata->term) == 0, FALSE);
384 gncBillTermSetType (pdata->term, GNC_TERM_TYPE_DAYS);
385 return dom_tree_to_days_data (node, pdata);
389 billterm_prox_data_handler (xmlNodePtr node, gpointer billterm_pdata)
391 struct billterm_pdata *pdata = billterm_pdata;
393 g_return_val_if_fail (node, FALSE);
394 g_return_val_if_fail (gncBillTermGetType (pdata->term) == 0, FALSE);
396 gncBillTermSetType (pdata->term, GNC_TERM_TYPE_PROXIMO);
397 return dom_tree_to_prox_data (node, pdata);
401 billterm_slots_handler (xmlNodePtr node, gpointer billterm_pdata)
403 struct billterm_pdata *pdata = billterm_pdata;
404 return dom_tree_to_kvp_frame_given (node,
405 qof_instance_get_slots (QOF_INSTANCE(pdata->term)));
410 { billterm_guid_string, billterm_guid_handler, 1, 0 },
411 { billterm_name_string, billterm_name_handler, 1, 0 },
412 { billterm_desc_string, billterm_desc_handler, 1, 0 },
413 { billterm_refcount_string, billterm_refcount_handler, 1, 0 },
414 { billterm_invisible_string, billterm_invisible_handler, 1, 0 },
415 { billterm_parent_string, billterm_parent_handler, 0, 0 },
416 { billterm_child_string, billterm_child_handler, 0, 0 },
417 { billterm_slots_string, billterm_slots_handler, 0, 0 },
418 { gnc_daystype_string, billterm_days_data_handler, 0, 0 },
419 { gnc_proximotype_string, billterm_prox_data_handler, 0, 0 },
424 dom_tree_to_billterm (xmlNodePtr node,
QofBook *book)
426 struct billterm_pdata billterm_pdata;
429 billterm_pdata.term = gncBillTermCreate (book);
430 billterm_pdata.book = book;
431 gncBillTermBeginEdit (billterm_pdata.term);
433 successful = dom_tree_generic_parse (node, billterm_handlers_v2,
438 gncBillTermCommitEdit (billterm_pdata.term);
442 PERR (
"failed to parse billing term tree");
443 gncBillTermDestroy (billterm_pdata.term);
444 billterm_pdata.term = NULL;
447 return billterm_pdata.term;
451 gnc_billterm_end_handler(gpointer data_for_children,
452 GSList* data_from_children, GSList* sibling_data,
453 gpointer parent_data, gpointer global_data,
454 gpointer *result,
const gchar *tag)
457 xmlNodePtr tree = (xmlNodePtr)data_for_children;
459 QofBook *book = gdata->bookdata;
474 g_return_val_if_fail(tree, FALSE);
476 term = dom_tree_to_billterm (tree, book);
479 gdata->cb(tag, gdata->parsedata, term);
488 billterm_sixtp_parser_create(
void)
490 return sixtp_dom_parser_new(gnc_billterm_end_handler, NULL, NULL);
496 int *count = count_p;
501 billterm_get_count (
QofBook *book)
509 xml_add_billterm (
QofInstance *term_p, gpointer out_p)
518 node = billterm_dom_tree_create (term);
519 xmlElemDump(out, NULL, node);
521 if (ferror(out) || fprintf(out,
"\n") < 0)
526 billterm_write (FILE *out,
QofBook *book)
529 return ferror(out) == 0;
535 return (gncBillTermGetParent(gncBillTermGetParent(term)) != NULL);
547 parent = gncBillTermGetParent(temp);
550 gp = gncBillTermGetParent(parent);
567 g_assert (gp == NULL);
575 billterm_scrub_cb (
QofInstance *term_p, gpointer list_p)
578 GList **list = list_p;
580 if (billterm_is_grandchild(term))
582 *list = g_list_prepend(*list, term);
585 else if (!gncBillTermGetType(term))
593 PWARN(
"Fixing broken child billterm: %s", guidstr);
595 gncBillTermBeginEdit(term);
596 gncBillTermSetType(term, gncBillTermGetType(t));
597 gncBillTermSetDueDays (term, gncBillTermGetDueDays(t));
598 gncBillTermSetDiscountDays (term, gncBillTermGetDiscountDays(t));
599 gncBillTermSetDiscount (term, gncBillTermGetDiscount(t));
600 gncBillTermSetCutoff (term, gncBillTermGetCutoff(t));
601 gncBillTermCommitEdit(term);
607 *list = g_list_prepend(*list, term);
616 billterm_scrub_invoices (
QofInstance * invoice_p, gpointer ht_p)
618 GHashTable *ht = ht_p;
623 term = gncInvoiceGetTerms(invoice);
626 if (billterm_is_grandchild(term))
630 PWARN(
"Fixing i-billterm on invoice %s\n", guidstr);
631 new_bt = billterm_find_senior(term);
632 gncInvoiceBeginEdit(invoice);
633 gncInvoiceSetTerms(invoice, new_bt);
634 gncInvoiceCommitEdit(invoice);
639 count = GPOINTER_TO_INT(g_hash_table_lookup(ht, term));
641 g_hash_table_insert(ht, term, GINT_TO_POINTER(count));
647 billterm_scrub_cust (
QofInstance * cust_p, gpointer ht_p)
649 GHashTable *ht = ht_p;
654 term = gncCustomerGetTerms(cust);
657 count = GPOINTER_TO_INT(g_hash_table_lookup(ht, term));
659 g_hash_table_insert(ht, term, GINT_TO_POINTER(count));
660 if (billterm_is_grandchild(term))
666 PWARN(
"customer %s has grandchild billterm %s\n", custstr,termstr);
672 billterm_scrub_vendor (
QofInstance * vendor_p, gpointer ht_p)
674 GHashTable *ht = ht_p;
675 GncVendor *vendor = GNC_VENDOR(vendor_p);
679 term = gncVendorGetTerms(vendor);
682 count = GPOINTER_TO_INT(g_hash_table_lookup(ht, term));
684 g_hash_table_insert(ht, term, GINT_TO_POINTER(count));
685 if (billterm_is_grandchild(term))
691 PWARN(
"vendor %s has grandchild billterm %s\n", vendstr, termstr);
697 billterm_reset_refcount (gpointer key, gpointer value, gpointer notused)
700 gint32 count = GPOINTER_TO_INT(value);
702 if (count != gncBillTermGetRefcount(term) && !gncBillTermGetInvisible(term))
706 PWARN(
"Fixing refcount on billterm %s (%" G_GINT64_FORMAT
" -> %d)\n",
707 termstr, gncBillTermGetRefcount(term), count);
708 gncBillTermSetRefcount(term, count);
718 GHashTable *ht = g_hash_table_new(g_direct_hash, g_direct_equal);
720 DEBUG(
"scrubbing billterms...");
727 for (node = list; node; node = node->next)
733 PWARN (
"deleting grandchild billterm: %s\n", termstr);
736 parent = gncBillTermGetParent(term);
737 gncBillTermSetChild(parent, NULL);
740 gncBillTermBeginEdit(term);
741 gncBillTermDestroy(term);
745 g_hash_table_foreach(ht, billterm_reset_refcount, NULL);
748 g_hash_table_destroy(ht);
752 billterm_ns(FILE *out)
754 g_return_val_if_fail(out, FALSE);
762 gnc_billterm_xml_initialize (
void)
766 GNC_FILE_BACKEND_VERS,
768 billterm_sixtp_parser_create,
788 g_return_val_if_fail(book, NULL);
789 g_return_val_if_fail(guid, NULL);
790 term = gncBillTermLookup(book, guid);
791 DEBUG(
"looking for billterm %s, found %p", guidstr, term);
794 term = gncBillTermCreate(book);
795 gncBillTermBeginEdit(term);
796 gncBillTermSetGUID(term, guid);
797 gncBillTermCommitEdit(term);
798 DEBUG(
"Created term: %p", term);
801 gncBillTermDecRef(term);
gboolean qof_object_register_backend(QofIdTypeConst type_name, const char *backend_name, gpointer be_data)
const GncGUID * qof_instance_get_guid(gconstpointer)
#define DEBUG(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)
Business Invoice Interface.
gboolean gnc_xml2_write_namespace_decl(FILE *out, const char *name_space)
const gchar * QofLogModule