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 "gncEntryP.h"
45 #include "gncOrderP.h"
46 #include "gncInvoiceP.h"
47 #include "gncTaxTableP.h"
48 #include "gnc-entry-xml-v2.h"
49 #include "gnc-owner-xml-v2.h"
51 #define _GNC_MOD_NAME GNC_ID_ENTRY
55 const gchar *entry_version_string =
"2.0.0";
58 #define gnc_entry_string "gnc:GncEntry"
59 #define entry_guid_string "entry:guid"
60 #define entry_date_string "entry:date"
61 #define entry_dateentered_string "entry:entered"
62 #define entry_description_string "entry:description"
63 #define entry_action_string "entry:action"
64 #define entry_notes_string "entry:notes"
65 #define entry_qty_string "entry:qty"
68 #define entry_invacct_string "entry:i-acct"
69 #define entry_iprice_string "entry:i-price"
70 #define entry_idiscount_string "entry:i-discount"
71 #define entry_idisctype_string "entry:i-disc-type"
72 #define entry_idischow_string "entry:i-disc-how"
73 #define entry_itaxable_string "entry:i-taxable"
74 #define entry_itaxincluded_string "entry:i-taxincluded"
75 #define entry_itaxtable_string "entry:i-taxtable"
78 #define entry_billacct_string "entry:b-acct"
79 #define entry_bprice_string "entry:b-price"
80 #define entry_btaxable_string "entry:b-taxable"
81 #define entry_btaxincluded_string "entry:b-taxincluded"
82 #define entry_btaxtable_string "entry:b-taxtable"
83 #define entry_billable_string "entry:billable"
84 #define entry_billto_string "entry:billto"
87 #define entry_billpayment_string "entry:b-pay"
90 #define entry_order_string "entry:order"
91 #define entry_invoice_string "entry:invoice"
92 #define entry_bill_string "entry:bill"
93 #define entry_slots_string "entry:slots"
99 maybe_add_string (xmlNodePtr ptr,
const char *tag,
const char *str)
101 if (str && strlen(str) > 0)
102 xmlAddChild (ptr, text_to_dom_tree (tag, str));
106 maybe_add_numeric (xmlNodePtr ptr,
const char *tag,
gnc_numeric num)
109 xmlAddChild (ptr, gnc_numeric_to_dom_tree (tag, &num));
113 entry_dom_tree_create (
GncEntry *entry)
123 ret = xmlNewNode(NULL, BAD_CAST gnc_entry_string);
124 xmlSetProp(ret, BAD_CAST
"version", BAD_CAST entry_version_string);
126 xmlAddChild(ret, guid_to_dom_tree(entry_guid_string,
130 xmlAddChild(ret, timespec_to_dom_tree (entry_date_string, &ts));
132 ts = gncEntryGetDateEntered (entry);
133 xmlAddChild(ret, timespec_to_dom_tree (entry_dateentered_string, &ts));
135 maybe_add_string (ret, entry_description_string,
136 gncEntryGetDescription (entry));
137 maybe_add_string (ret, entry_action_string, gncEntryGetAction (entry));
138 maybe_add_string (ret, entry_notes_string, gncEntryGetNotes (entry));
144 acc = gncEntryGetInvAccount (entry);
146 xmlAddChild (ret, guid_to_dom_tree (entry_invacct_string,
149 maybe_add_numeric (ret, entry_iprice_string, gncEntryGetInvPrice (entry));
151 maybe_add_numeric (ret, entry_idiscount_string, gncEntryGetInvDiscount (entry));
153 invoice = gncEntryGetInvoice (entry);
156 xmlAddChild (ret, guid_to_dom_tree (entry_invoice_string,
159 xmlAddChild(ret, text_to_dom_tree(entry_idisctype_string,
160 gncAmountTypeToString (
161 gncEntryGetInvDiscountType (entry))));
162 xmlAddChild(ret, text_to_dom_tree(entry_idischow_string,
164 gncEntryGetInvDiscountHow (entry))));
166 xmlAddChild(ret, int_to_dom_tree(entry_itaxable_string,
167 gncEntryGetInvTaxable (entry)));
168 xmlAddChild(ret, int_to_dom_tree(entry_itaxincluded_string,
169 gncEntryGetInvTaxIncluded (entry)));
172 taxtable = gncEntryGetInvTaxTable (entry);
174 xmlAddChild (ret, guid_to_dom_tree (entry_itaxtable_string,
179 acc = gncEntryGetBillAccount (entry);
181 xmlAddChild (ret, guid_to_dom_tree (entry_billacct_string,
184 maybe_add_numeric (ret, entry_bprice_string, gncEntryGetBillPrice (entry));
186 invoice = gncEntryGetBill (entry);
190 xmlAddChild (ret, guid_to_dom_tree (entry_bill_string,
192 xmlAddChild(ret, int_to_dom_tree(entry_billable_string,
193 gncEntryGetBillable (entry)));
194 owner = gncEntryGetBillTo (entry);
195 if (owner && owner->owner.undefined != NULL)
196 xmlAddChild (ret, gnc_owner_to_dom_tree (entry_billto_string, owner));
198 xmlAddChild(ret, int_to_dom_tree(entry_btaxable_string,
199 gncEntryGetBillTaxable (entry)));
200 xmlAddChild(ret, int_to_dom_tree(entry_btaxincluded_string,
201 gncEntryGetBillTaxIncluded (entry)));
202 maybe_add_string (ret, entry_billpayment_string,
203 gncEntryPaymentTypeToString (gncEntryGetBillPayment (entry)));
206 taxtable = gncEntryGetBillTaxTable (entry);
208 xmlAddChild (ret, guid_to_dom_tree (entry_btaxtable_string,
213 order = gncEntryGetOrder (entry);
215 xmlAddChild (ret, guid_to_dom_tree (entry_order_string,
218 kf = qof_instance_get_slots (QOF_INSTANCE(entry));
221 xmlNodePtr kvpnode = kvp_frame_to_dom_tree(entry_slots_string, kf);
224 xmlAddChild(ret, kvpnode);
240 static inline gboolean
241 set_string(xmlNodePtr node,
GncEntry* entry,
242 void (*func)(
GncEntry *entry,
const char *txt))
244 char* txt = dom_tree_to_text(node);
245 g_return_val_if_fail(txt, FALSE);
252 static inline gboolean
253 set_timespec(xmlNodePtr node,
GncEntry* entry,
256 Timespec ts = dom_tree_to_timespec (node);
257 if (!dom_tree_valid_timespec(&ts, node->name))
return FALSE;
263 static inline gboolean
264 set_numeric(xmlNodePtr node,
GncEntry* entry,
268 g_return_val_if_fail(num, FALSE);
275 static inline gboolean
276 set_boolean(xmlNodePtr node,
GncEntry* entry,
277 void (*func)(
GncEntry *entry, gboolean val))
281 if (!dom_tree_to_integer(node, &val))
283 func (entry, (gboolean)val);
287 static inline gboolean
288 set_account(xmlNodePtr node,
struct entry_pdata *pdata,
294 guid = dom_tree_to_guid (node);
295 g_return_val_if_fail (guid, FALSE);
298 g_return_val_if_fail (acc, FALSE);
301 func (pdata->entry, acc);
307 static inline gboolean
308 set_taxtable (xmlNodePtr node,
struct entry_pdata *pdata,
314 guid = dom_tree_to_guid (node);
315 g_return_val_if_fail (guid, FALSE);
316 taxtable = gncTaxTableLookup (pdata->book, guid);
319 taxtable = gncTaxTableCreate (pdata->book);
320 gncTaxTableBeginEdit (taxtable);
321 gncTaxTableSetGUID (taxtable, guid);
322 gncTaxTableCommitEdit (taxtable);
325 gncTaxTableDecRef (taxtable);
327 func (pdata->entry, taxtable);
333 entry_guid_handler (xmlNodePtr node, gpointer
entry_pdata)
335 struct entry_pdata *pdata = entry_pdata;
339 guid = dom_tree_to_guid(node);
340 g_return_val_if_fail (guid, FALSE);
341 entry = gncEntryLookup (pdata->book, guid);
344 gncEntryDestroy (pdata->entry);
345 pdata->entry = entry;
346 gncEntryBeginEdit (entry);
350 gncEntrySetGUID(pdata->entry, guid);
359 entry_date_handler (xmlNodePtr node, gpointer entry_pdata)
361 struct entry_pdata *pdata = entry_pdata;
367 entry_dateentered_handler (xmlNodePtr node, gpointer entry_pdata)
369 struct entry_pdata *pdata = entry_pdata;
371 return set_timespec(node, pdata->entry, gncEntrySetDateEntered);
375 entry_description_handler (xmlNodePtr node, gpointer entry_pdata)
377 struct entry_pdata *pdata = entry_pdata;
379 return set_string(node, pdata->entry, gncEntrySetDescription);
383 entry_action_handler (xmlNodePtr node, gpointer entry_pdata)
385 struct entry_pdata *pdata = entry_pdata;
387 return set_string(node, pdata->entry, gncEntrySetAction);
391 entry_notes_handler (xmlNodePtr node, gpointer entry_pdata)
393 struct entry_pdata *pdata = entry_pdata;
395 return set_string(node, pdata->entry, gncEntrySetNotes);
399 entry_qty_handler (xmlNodePtr node, gpointer entry_pdata)
401 struct entry_pdata *pdata = entry_pdata;
409 entry_invacct_handler (xmlNodePtr node, gpointer entry_pdata)
411 struct entry_pdata *pdata = entry_pdata;
412 return set_account (node, pdata, gncEntrySetInvAccount);
416 entry_iprice_handler (xmlNodePtr node, gpointer entry_pdata)
418 struct entry_pdata *pdata = entry_pdata;
420 return set_numeric(node, pdata->entry, gncEntrySetInvPrice);
424 entry_idiscount_handler (xmlNodePtr node, gpointer entry_pdata)
426 struct entry_pdata *pdata = entry_pdata;
428 return set_numeric(node, pdata->entry, gncEntrySetInvDiscount);
432 entry_idisctype_handler (xmlNodePtr node, gpointer entry_pdata)
434 struct entry_pdata *pdata = entry_pdata;
439 str = dom_tree_to_text (node);
440 g_return_val_if_fail (str, FALSE);
442 ret = gncAmountStringToType (str, &type);
446 gncEntrySetInvDiscountType(pdata->entry, type);
452 entry_idischow_handler (xmlNodePtr node, gpointer entry_pdata)
454 struct entry_pdata *pdata = entry_pdata;
459 str = dom_tree_to_text (node);
460 g_return_val_if_fail (str, FALSE);
462 ret = gncEntryDiscountStringToHow (str, &how);
466 gncEntrySetInvDiscountHow(pdata->entry, how);
472 entry_itaxable_handler (xmlNodePtr node, gpointer entry_pdata)
474 struct entry_pdata *pdata = entry_pdata;
475 return set_boolean (node, pdata->entry, gncEntrySetInvTaxable);
479 entry_itaxincluded_handler (xmlNodePtr node, gpointer entry_pdata)
481 struct entry_pdata *pdata = entry_pdata;
482 return set_boolean (node, pdata->entry, gncEntrySetInvTaxIncluded);
486 entry_itaxtable_handler (xmlNodePtr node, gpointer entry_pdata)
488 struct entry_pdata *pdata = entry_pdata;
489 return set_taxtable (node, pdata, gncEntrySetInvTaxTable);
495 entry_billacct_handler (xmlNodePtr node, gpointer entry_pdata)
497 struct entry_pdata *pdata = entry_pdata;
498 return set_account (node, pdata, gncEntrySetBillAccount);
502 entry_bprice_handler (xmlNodePtr node, gpointer entry_pdata)
504 struct entry_pdata *pdata = entry_pdata;
506 return set_numeric(node, pdata->entry, gncEntrySetBillPrice);
510 entry_btaxable_handler (xmlNodePtr node, gpointer entry_pdata)
512 struct entry_pdata *pdata = entry_pdata;
513 return set_boolean (node, pdata->entry, gncEntrySetBillTaxable);
517 entry_btaxincluded_handler (xmlNodePtr node, gpointer entry_pdata)
519 struct entry_pdata *pdata = entry_pdata;
520 return set_boolean (node, pdata->entry, gncEntrySetBillTaxIncluded);
524 entry_btaxtable_handler (xmlNodePtr node, gpointer entry_pdata)
526 struct entry_pdata *pdata = entry_pdata;
527 return set_taxtable (node, pdata, gncEntrySetBillTaxTable);
531 entry_billable_handler (xmlNodePtr node, gpointer entry_pdata)
533 struct entry_pdata *pdata = entry_pdata;
534 return set_boolean (node, pdata->entry, gncEntrySetBillable);
538 entry_billto_handler (xmlNodePtr node, gpointer entry_pdata)
540 struct entry_pdata *pdata = entry_pdata;
544 ret = gnc_dom_tree_to_owner (node, &billto, pdata->book);
546 gncEntrySetBillTo (pdata->entry, &billto);
553 entry_billpayment_handler (xmlNodePtr node, gpointer entry_pdata)
555 struct entry_pdata *pdata = entry_pdata;
556 GncEntryPaymentType type;
560 str = dom_tree_to_text (node);
561 g_return_val_if_fail (str, FALSE);
563 ret = gncEntryPaymentStringToType (str, &type);
567 gncEntrySetBillPayment(pdata->entry, type);
575 entry_order_handler (xmlNodePtr node, gpointer entry_pdata)
577 struct entry_pdata *pdata = entry_pdata;
581 guid = dom_tree_to_guid (node);
582 g_return_val_if_fail (guid, FALSE);
583 order = gncOrderLookup (pdata->book, guid);
586 order = gncOrderCreate (pdata->book);
587 gncOrderBeginEdit (order);
588 gncOrderSetGUID (order, guid);
589 gncOrderCommitEdit (order);
591 gncOrderBeginEdit (order);
592 gncOrderAddEntry (order, pdata->entry);
593 gncOrderCommitEdit (order);
600 entry_invoice_handler (xmlNodePtr node, gpointer entry_pdata)
602 struct entry_pdata *pdata = entry_pdata;
606 guid = dom_tree_to_guid (node);
607 g_return_val_if_fail (guid, FALSE);
608 invoice = gncInvoiceLookup (pdata->book, guid);
611 invoice = gncInvoiceCreate (pdata->book);
612 gncInvoiceBeginEdit (invoice);
613 gncInvoiceSetGUID (invoice, guid);
614 gncInvoiceCommitEdit (invoice);
616 gncInvoiceBeginEdit (invoice);
617 gncInvoiceAddEntry (invoice, pdata->entry);
618 gncInvoiceCommitEdit (invoice);
625 entry_bill_handler (xmlNodePtr node, gpointer entry_pdata)
627 struct entry_pdata *pdata = entry_pdata;
631 guid = dom_tree_to_guid (node);
632 g_return_val_if_fail (guid, FALSE);
633 invoice = gncInvoiceLookup (pdata->book, guid);
636 invoice = gncInvoiceCreate (pdata->book);
637 gncInvoiceBeginEdit (invoice);
638 gncInvoiceSetGUID (invoice, guid);
639 gncInvoiceCommitEdit (invoice);
641 gncInvoiceBeginEdit (invoice);
643 gncInvoiceCommitEdit (invoice);
652 entry_acct_handler (xmlNodePtr node, gpointer entry_pdata)
654 struct entry_pdata *pdata = entry_pdata;
659 return set_account (node, pdata, NULL);
663 entry_price_handler (xmlNodePtr node, gpointer entry_pdata)
665 struct entry_pdata *pdata = entry_pdata;
669 res = set_numeric(node, pdata->entry, gncEntrySetInvPrice);
671 gncEntrySetBillPrice (pdata->entry, gncEntryGetInvPrice (pdata->entry));
676 entry_slots_handler (xmlNodePtr node, gpointer entry_pdata)
678 struct entry_pdata *pdata = entry_pdata;
680 return dom_tree_to_kvp_frame_given
681 (node, qof_instance_get_slots (QOF_INSTANCE (pdata->entry)));
686 { entry_guid_string, entry_guid_handler, 1, 0 },
687 { entry_date_string, entry_date_handler, 1, 0 },
688 { entry_dateentered_string, entry_dateentered_handler, 1, 0 },
689 { entry_description_string, entry_description_handler, 0, 0 },
690 { entry_action_string, entry_action_handler, 0, 0 },
691 { entry_notes_string, entry_notes_handler, 0, 0 },
692 { entry_qty_string, entry_qty_handler, 0, 0 },
695 { entry_invacct_string, entry_invacct_handler, 0, 0 },
696 { entry_iprice_string, entry_iprice_handler, 0, 0 },
697 { entry_idiscount_string, entry_idiscount_handler, 0, 0 },
698 { entry_idisctype_string, entry_idisctype_handler, 0, 0 },
699 { entry_idischow_string, entry_idischow_handler, 0, 0 },
700 { entry_itaxable_string, entry_itaxable_handler, 0, 0 },
701 { entry_itaxincluded_string, entry_itaxincluded_handler, 0, 0 },
702 { entry_itaxtable_string, entry_itaxtable_handler, 0, 0 },
705 { entry_billacct_string, entry_billacct_handler, 0, 0 },
706 { entry_bprice_string, entry_bprice_handler, 0, 0 },
707 { entry_btaxable_string, entry_btaxable_handler, 0, 0 },
708 { entry_btaxincluded_string, entry_btaxincluded_handler, 0, 0 },
709 { entry_btaxtable_string, entry_btaxtable_handler, 0, 0 },
710 { entry_billable_string, entry_billable_handler, 0, 0 },
711 { entry_billto_string, entry_billto_handler, 0, 0 },
714 { entry_billpayment_string, entry_billpayment_handler, 0, 0 },
717 { entry_order_string, entry_order_handler, 0, 0 },
718 { entry_invoice_string, entry_invoice_handler, 0, 0 },
719 { entry_bill_string, entry_bill_handler, 0, 0 },
720 { entry_slots_string, entry_slots_handler, 0, 0 },
723 {
"entry:acct", entry_acct_handler, 0, 0 },
724 {
"entry:price", entry_price_handler, 0, 0 },
725 {
"entry:discount", entry_idiscount_handler, 0, 0 },
726 {
"entry:disc-type", entry_idisctype_handler, 0, 0 },
727 {
"entry:disc-how", entry_idischow_handler, 0, 0 },
728 {
"entry:taxable", entry_itaxable_handler, 0, 0 },
729 {
"entry:taxincluded", entry_itaxincluded_handler, 0, 0 },
730 {
"entry:taxtable", entry_itaxtable_handler, 0, 0 },
735 dom_tree_to_entry (xmlNodePtr node,
QofBook *book)
737 struct entry_pdata entry_pdata;
740 entry_pdata.entry = gncEntryCreate(book);
741 entry_pdata.book = book;
742 entry_pdata.acc = NULL;
743 gncEntryBeginEdit (entry_pdata.entry);
745 successful = dom_tree_generic_parse (node, entry_handlers_v2,
747 if (entry_pdata.acc != NULL)
749 if (gncEntryGetBill (entry_pdata.entry))
750 gncEntrySetBillAccount (entry_pdata.entry, entry_pdata.acc);
752 gncEntrySetInvAccount (entry_pdata.entry, entry_pdata.acc);
756 gncEntryCommitEdit (entry_pdata.entry);
759 PERR (
"failed to parse entry tree");
760 gncEntryDestroy (entry_pdata.entry);
761 entry_pdata.entry = NULL;
764 return entry_pdata.entry;
768 gnc_entry_end_handler(gpointer data_for_children,
769 GSList* data_from_children, GSList* sibling_data,
770 gpointer parent_data, gpointer global_data,
771 gpointer *result,
const gchar *tag)
774 xmlNodePtr tree = (xmlNodePtr)data_for_children;
776 QofBook *book = gdata->bookdata;
791 g_return_val_if_fail(tree, FALSE);
793 entry = dom_tree_to_entry(tree, book);
796 gdata->cb(tag, gdata->parsedata, entry);
801 return entry != NULL;
805 entry_sixtp_parser_create(
void)
807 return sixtp_dom_parser_new(gnc_entry_end_handler, NULL, NULL);
813 int *count = count_p;
818 entry_get_count (
QofBook *book)
826 xml_add_entry (
QofInstance * entry_p, gpointer out_p)
836 if (!(gncEntryGetOrder (entry) || gncEntryGetInvoice (entry) ||
837 gncEntryGetBill (entry)))
840 node = entry_dom_tree_create (entry);
841 xmlElemDump(out, NULL, node);
843 if (ferror(out) || fprintf(out,
"\n") < 0)
848 entry_write (FILE *out,
QofBook *book)
851 return ferror(out) == 0;
857 g_return_val_if_fail(out, FALSE);
862 gnc_entry_xml_initialize (
void)
866 GNC_FILE_BACKEND_VERS,
868 entry_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)
void gncEntrySetQuantity(GncEntry *entry, gnc_numeric quantity)
void gncEntrySetDate(GncEntry *entry, Timespec date)
Use a 64-bit unsigned int timespec.
gboolean gnc_numeric_zero_p(gnc_numeric a)
Timespec gncEntryGetDate(const GncEntry *entry)
#define PERR(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
void gncBillAddEntry(GncInvoice *bill, GncEntry *entry)
void qof_object_foreach(QofIdTypeConst type_name, QofBook *book, QofInstanceForeachCB cb, gpointer user_data)
const char * gncEntryDiscountHowToString(GncDiscountHow how)
gboolean gnc_xml2_write_namespace_decl(FILE *out, const char *name_space)
struct KvpFrameImpl KvpFrame
gnc_numeric gncEntryGetQuantity(const GncEntry *entry)
const gchar * QofLogModule
Account * xaccAccountLookup(const GncGUID *guid, QofBook *book)