Branch data Line data Source code
1 : : /********************************************************************\
2 : : * gnc-invoice-xml-v2.c -- invoice xml i/o implementation *
3 : : * *
4 : : * Copyright (C) 2002 Derek Atkins <warlord@MIT.EDU> *
5 : : * *
6 : : * This program is free software; you can redistribute it and/or *
7 : : * modify it under the terms of the GNU General Public License as *
8 : : * published by the Free Software Foundation; either version 2 of *
9 : : * the License, or (at your option) any later version. *
10 : : * *
11 : : * This program is distributed in the hope that it will be useful, *
12 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 : : * GNU General Public License for more details. *
15 : : * *
16 : : * You should have received a copy of the GNU General Public License*
17 : : * along with this program; if not, contact: *
18 : : * *
19 : : * Free Software Foundation Voice: +1-617-542-5942 *
20 : : * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
21 : : * Boston, MA 02110-1301, USA gnu@gnu.org *
22 : : * *
23 : : \********************************************************************/
24 : : #include <glib.h>
25 : :
26 : : #include <config.h>
27 : : #include <stdlib.h>
28 : : #include <string.h>
29 : :
30 : : #include "gncBillTermP.h"
31 : : #include "gncInvoiceP.h"
32 : :
33 : : #include "gnc-xml-helper.h"
34 : : #include "sixtp.h"
35 : : #include "sixtp-utils.h"
36 : : #include "sixtp-parsers.h"
37 : : #include "sixtp-utils.h"
38 : : #include "sixtp-dom-parsers.h"
39 : : #include "sixtp-dom-generators.h"
40 : : #include "gnc-invoice-xml-v2.h"
41 : : #include "gnc-owner-xml-v2.h"
42 : : #include "gnc-bill-term-xml-v2.h"
43 : :
44 : : #include "gnc-xml.h"
45 : : #include "io-gncxml-gen.h"
46 : : #include "io-gncxml-v2.h"
47 : :
48 : : #define _GNC_MOD_NAME GNC_ID_INVOICE
49 : :
50 : : static QofLogModule log_module = GNC_MOD_IO;
51 : :
52 : : const gchar* invoice_version_string = "2.0.0";
53 : :
54 : : /* ids */
55 : : #define gnc_invoice_string "gnc:GncInvoice"
56 : : #define invoice_guid_string "invoice:guid"
57 : : #define invoice_id_string "invoice:id"
58 : : #define invoice_owner_string "invoice:owner"
59 : : #define invoice_opened_string "invoice:opened"
60 : : #define invoice_posted_string "invoice:posted"
61 : : #define invoice_terms_string "invoice:terms"
62 : : #define invoice_billing_id_string "invoice:billing_id"
63 : : #define invoice_notes_string "invoice:notes"
64 : : #define invoice_active_string "invoice:active"
65 : : #define invoice_posttxn_string "invoice:posttxn"
66 : : #define invoice_postlot_string "invoice:postlot"
67 : : #define invoice_postacc_string "invoice:postacc"
68 : : #define invoice_currency_string "invoice:currency"
69 : : #define invoice_billto_string "invoice:billto"
70 : : #define invoice_tochargeamt_string "invoice:charge-amt"
71 : : #define invoice_slots_string "invoice:slots"
72 : :
73 : : static void
74 : 4 : maybe_add_string (xmlNodePtr ptr, const char* tag, const char* str)
75 : : {
76 : 4 : if (str && *str)
77 : 2 : xmlAddChild (ptr, text_to_dom_tree (tag, str));
78 : 4 : }
79 : :
80 : : static void
81 : 2 : maybe_add_time64 (xmlNodePtr ptr, const char* tag, time64 time)
82 : : {
83 : 2 : if (time != INT64_MAX)
84 : 2 : xmlAddChild (ptr, time64_to_dom_tree (tag, time));
85 : 2 : }
86 : :
87 : : static xmlNodePtr
88 : 2 : invoice_dom_tree_create (GncInvoice* invoice)
89 : : {
90 : : xmlNodePtr ret;
91 : : time64 time;
92 : : Transaction* txn;
93 : : GNCLot* lot;
94 : : Account* acc;
95 : : GncBillTerm* term;
96 : : GncOwner* billto;
97 : : gnc_numeric amt;
98 : :
99 : 2 : ret = xmlNewNode (NULL, BAD_CAST gnc_invoice_string);
100 : 2 : xmlSetProp (ret, BAD_CAST "version", BAD_CAST invoice_version_string);
101 : :
102 : 2 : xmlAddChild (ret, guid_to_dom_tree (invoice_guid_string,
103 : 2 : qof_instance_get_guid (QOF_INSTANCE (invoice))));
104 : :
105 : 2 : xmlAddChild (ret, text_to_dom_tree (invoice_id_string,
106 : : gncInvoiceGetID (invoice)));
107 : :
108 : 2 : xmlAddChild (ret, gnc_owner_to_dom_tree (invoice_owner_string,
109 : : gncInvoiceGetOwner (invoice)));
110 : :
111 : 2 : time = gncInvoiceGetDateOpened (invoice);
112 : 2 : xmlAddChild (ret, time64_to_dom_tree (invoice_opened_string, time));
113 : :
114 : 2 : maybe_add_time64 (ret, invoice_posted_string, gncInvoiceGetDatePosted (invoice));
115 : :
116 : 2 : term = gncInvoiceGetTerms (invoice);
117 : 2 : if (term)
118 : 0 : xmlAddChild (ret, guid_to_dom_tree (invoice_terms_string,
119 : 0 : qof_instance_get_guid (QOF_INSTANCE (term))));
120 : :
121 : 2 : maybe_add_string (ret, invoice_billing_id_string,
122 : : gncInvoiceGetBillingID (invoice));
123 : 2 : maybe_add_string (ret, invoice_notes_string, gncInvoiceGetNotes (invoice));
124 : :
125 : 2 : xmlAddChild (ret, int_to_dom_tree (invoice_active_string,
126 : 2 : gncInvoiceGetActive (invoice)));
127 : :
128 : 2 : txn = gncInvoiceGetPostedTxn (invoice);
129 : 2 : if (txn)
130 : 2 : xmlAddChild (ret, guid_to_dom_tree (invoice_posttxn_string,
131 : 2 : xaccTransGetGUID (txn)));
132 : :
133 : 2 : lot = gncInvoiceGetPostedLot (invoice);
134 : 2 : if (lot)
135 : 2 : xmlAddChild (ret, guid_to_dom_tree (invoice_postlot_string,
136 : 2 : gnc_lot_get_guid (lot)));
137 : :
138 : 2 : acc = gncInvoiceGetPostedAcc (invoice);
139 : 2 : if (acc)
140 : 2 : xmlAddChild (ret, guid_to_dom_tree (invoice_postacc_string,
141 : 2 : qof_instance_get_guid (QOF_INSTANCE (acc))));
142 : :
143 : : xmlAddChild
144 : 2 : (ret,
145 : : commodity_ref_to_dom_tree (invoice_currency_string,
146 : 2 : gncInvoiceGetCurrency (invoice)));
147 : :
148 : 2 : billto = gncInvoiceGetBillTo (invoice);
149 : 2 : if (billto && billto->owner.undefined != NULL)
150 : 0 : xmlAddChild (ret, gnc_owner_to_dom_tree (invoice_billto_string, billto));
151 : :
152 : 2 : amt = gncInvoiceGetToChargeAmount (invoice);
153 : 2 : if (! gnc_numeric_zero_p (amt))
154 : 0 : xmlAddChild (ret, gnc_numeric_to_dom_tree (invoice_tochargeamt_string, &amt));
155 : :
156 : : /* xmlAddChild won't do anything with a NULL, so tests are superfluous. */
157 : 2 : xmlAddChild (ret, qof_instance_slots_to_dom_tree (invoice_slots_string,
158 : 2 : QOF_INSTANCE (invoice)));
159 : 2 : return ret;
160 : : }
161 : :
162 : : /***********************************************************************/
163 : :
164 : : struct invoice_pdata
165 : : {
166 : : GncInvoice* invoice;
167 : : QofBook* book;
168 : : };
169 : :
170 : : static inline gboolean
171 : 5 : set_string (xmlNodePtr node, GncInvoice* invoice,
172 : : void (*func) (GncInvoice* invoice, const char* txt))
173 : : {
174 : 5 : char* txt = dom_tree_to_text (node);
175 : 5 : g_return_val_if_fail (txt, FALSE);
176 : :
177 : 5 : func (invoice, txt);
178 : :
179 : 5 : g_free (txt);
180 : 5 : return TRUE;
181 : : }
182 : :
183 : : static inline gboolean
184 : 5 : set_time64 (xmlNodePtr node, GncInvoice* invoice,
185 : : void (*func) (GncInvoice* invoice, time64 time))
186 : : {
187 : 5 : time64 time = dom_tree_to_time64 (node);
188 : 5 : if (!dom_tree_valid_time64 (time, node->name)) time = 0;
189 : 5 : func (invoice, time);
190 : 5 : return TRUE;
191 : : }
192 : :
193 : : static gboolean
194 : 3 : invoice_guid_handler (xmlNodePtr node, gpointer invoice_pdata)
195 : : {
196 : 3 : struct invoice_pdata* pdata = static_cast<decltype (pdata)> (invoice_pdata);
197 : : GncGUID* guid;
198 : : GncInvoice* invoice;
199 : :
200 : 3 : guid = dom_tree_to_guid (node);
201 : 3 : g_return_val_if_fail (guid, FALSE);
202 : 3 : invoice = gncInvoiceLookup (pdata->book, guid);
203 : 3 : if (invoice)
204 : : {
205 : 3 : gncInvoiceDestroy (pdata->invoice);
206 : 3 : pdata->invoice = invoice;
207 : 3 : gncInvoiceBeginEdit (invoice);
208 : : }
209 : : else
210 : : {
211 : 0 : gncInvoiceSetGUID (pdata->invoice, guid);
212 : : }
213 : :
214 : 3 : guid_free (guid);
215 : :
216 : 3 : return TRUE;
217 : : }
218 : :
219 : : static gboolean
220 : 3 : invoice_id_handler (xmlNodePtr node, gpointer invoice_pdata)
221 : : {
222 : 3 : struct invoice_pdata* pdata = static_cast<decltype (pdata)> (invoice_pdata);
223 : :
224 : 3 : return set_string (node, pdata->invoice, gncInvoiceSetID);
225 : : }
226 : :
227 : : static gboolean
228 : 3 : invoice_owner_handler (xmlNodePtr node, gpointer invoice_pdata)
229 : : {
230 : 3 : struct invoice_pdata* pdata = static_cast<decltype (pdata)> (invoice_pdata);
231 : : GncOwner owner;
232 : : gboolean ret;
233 : :
234 : 3 : ret = gnc_dom_tree_to_owner (node, &owner, pdata->book);
235 : 3 : if (ret)
236 : 3 : gncInvoiceSetOwner (pdata->invoice, &owner);
237 : :
238 : 3 : return ret;
239 : : }
240 : :
241 : : static gboolean
242 : 3 : invoice_opened_handler (xmlNodePtr node, gpointer invoice_pdata)
243 : : {
244 : 3 : struct invoice_pdata* pdata = static_cast<decltype (pdata)> (invoice_pdata);
245 : 3 : return set_time64 (node, pdata->invoice, gncInvoiceSetDateOpened);
246 : : }
247 : :
248 : : static gboolean
249 : 2 : invoice_posted_handler (xmlNodePtr node, gpointer invoice_pdata)
250 : : {
251 : 2 : struct invoice_pdata* pdata = static_cast<decltype (pdata)> (invoice_pdata);
252 : 2 : return set_time64 (node, pdata->invoice, gncInvoiceSetDatePosted);
253 : : }
254 : :
255 : : static gboolean
256 : 2 : invoice_billing_id_handler (xmlNodePtr node, gpointer invoice_pdata)
257 : : {
258 : 2 : struct invoice_pdata* pdata = static_cast<decltype (pdata)> (invoice_pdata);
259 : :
260 : 2 : return set_string (node, pdata->invoice, gncInvoiceSetBillingID);
261 : : }
262 : :
263 : : static gboolean
264 : 0 : invoice_notes_handler (xmlNodePtr node, gpointer invoice_pdata)
265 : : {
266 : 0 : struct invoice_pdata* pdata = static_cast<decltype (pdata)> (invoice_pdata);
267 : :
268 : 0 : return set_string (node, pdata->invoice, gncInvoiceSetNotes);
269 : : }
270 : :
271 : : static gboolean
272 : 3 : invoice_active_handler (xmlNodePtr node, gpointer invoice_pdata)
273 : : {
274 : 3 : struct invoice_pdata* pdata = static_cast<decltype (pdata)> (invoice_pdata);
275 : : gint64 val;
276 : : gboolean ret;
277 : :
278 : 3 : ret = dom_tree_to_integer (node, &val);
279 : 3 : if (ret)
280 : 3 : gncInvoiceSetActive (pdata->invoice, (gboolean)val);
281 : :
282 : 3 : return ret;
283 : : }
284 : :
285 : : static gboolean
286 : 0 : invoice_terms_handler (xmlNodePtr node, gpointer invoice_pdata)
287 : : {
288 : 0 : struct invoice_pdata* pdata = static_cast<decltype (pdata)> (invoice_pdata);
289 : : GncGUID* guid;
290 : : GncBillTerm* term;
291 : :
292 : 0 : guid = dom_tree_to_guid (node);
293 : 0 : g_return_val_if_fail (guid, FALSE);
294 : 0 : term = gnc_billterm_xml_find_or_create (pdata->book, guid);
295 : 0 : g_assert (term);
296 : 0 : guid_free (guid);
297 : 0 : gncInvoiceSetTerms (pdata->invoice, term);
298 : :
299 : 0 : return TRUE;
300 : : }
301 : :
302 : : static gboolean
303 : 2 : invoice_posttxn_handler (xmlNodePtr node, gpointer invoice_pdata)
304 : : {
305 : 2 : struct invoice_pdata* pdata = static_cast<decltype (pdata)> (invoice_pdata);
306 : : GncGUID* guid;
307 : : Transaction* txn;
308 : :
309 : 2 : guid = dom_tree_to_guid (node);
310 : 2 : g_return_val_if_fail (guid, FALSE);
311 : 2 : txn = xaccTransLookup (guid, pdata->book);
312 : 2 : guid_free (guid);
313 : 2 : g_return_val_if_fail (txn, FALSE);
314 : :
315 : 2 : gncInvoiceSetPostedTxn (pdata->invoice, txn);
316 : 2 : return TRUE;
317 : : }
318 : :
319 : : static gboolean
320 : 2 : invoice_postlot_handler (xmlNodePtr node, gpointer invoice_pdata)
321 : : {
322 : 2 : struct invoice_pdata* pdata = static_cast<decltype (pdata)> (invoice_pdata);
323 : : GncGUID* guid;
324 : : GNCLot* lot;
325 : :
326 : 2 : guid = dom_tree_to_guid (node);
327 : 2 : g_return_val_if_fail (guid, FALSE);
328 : 2 : lot = gnc_lot_lookup (guid, pdata->book);
329 : 2 : guid_free (guid);
330 : 2 : g_return_val_if_fail (lot, FALSE);
331 : :
332 : 2 : gncInvoiceSetPostedLot (pdata->invoice, lot);
333 : 2 : return TRUE;
334 : : }
335 : :
336 : : static gboolean
337 : 2 : invoice_postacc_handler (xmlNodePtr node, gpointer invoice_pdata)
338 : : {
339 : 2 : struct invoice_pdata* pdata = static_cast<decltype (pdata)> (invoice_pdata);
340 : : GncGUID* guid;
341 : : Account* acc;
342 : :
343 : 2 : guid = dom_tree_to_guid (node);
344 : 2 : g_return_val_if_fail (guid, FALSE);
345 : 2 : acc = xaccAccountLookup (guid, pdata->book);
346 : 2 : guid_free (guid);
347 : 2 : g_return_val_if_fail (acc, FALSE);
348 : :
349 : 2 : gncInvoiceSetPostedAcc (pdata->invoice, acc);
350 : 2 : return TRUE;
351 : : }
352 : :
353 : : static gboolean
354 : 3 : invoice_currency_handler (xmlNodePtr node, gpointer invoice_pdata)
355 : : {
356 : 3 : struct invoice_pdata* pdata = static_cast<decltype (pdata)> (invoice_pdata);
357 : : gnc_commodity* com;
358 : :
359 : 3 : com = dom_tree_to_commodity_ref (node, pdata->book);
360 : 3 : g_return_val_if_fail (com, FALSE);
361 : :
362 : 3 : gncInvoiceSetCurrency (pdata->invoice, com);
363 : :
364 : 3 : return TRUE;
365 : : }
366 : :
367 : : static gboolean
368 : 0 : invoice_billto_handler (xmlNodePtr node, gpointer invoice_pdata)
369 : : {
370 : 0 : struct invoice_pdata* pdata = static_cast<decltype (pdata)> (invoice_pdata);
371 : : GncOwner owner;
372 : : gboolean ret;
373 : :
374 : 0 : ret = gnc_dom_tree_to_owner (node, &owner, pdata->book);
375 : 0 : if (ret)
376 : 0 : gncInvoiceSetBillTo (pdata->invoice, &owner);
377 : :
378 : 0 : return ret;
379 : : }
380 : :
381 : : static gboolean
382 : 0 : invoice_tochargeamt_handler (xmlNodePtr node, gpointer invoice_pdata)
383 : : {
384 : 0 : struct invoice_pdata* pdata = static_cast<decltype (pdata)> (invoice_pdata);
385 : :
386 : 0 : gncInvoiceSetToChargeAmount (pdata->invoice, dom_tree_to_gnc_numeric (node));
387 : 0 : return TRUE;
388 : : }
389 : :
390 : : static gboolean
391 : 2 : invoice_slots_handler (xmlNodePtr node, gpointer invoice_pdata)
392 : : {
393 : 2 : struct invoice_pdata* pdata = static_cast<decltype (pdata)> (invoice_pdata);
394 : 2 : return dom_tree_create_instance_slots (node, QOF_INSTANCE (pdata->invoice));
395 : : }
396 : :
397 : : static struct dom_tree_handler invoice_handlers_v2[] =
398 : : {
399 : : { invoice_guid_string, invoice_guid_handler, 1, 0 },
400 : : { invoice_id_string, invoice_id_handler, 1, 0 },
401 : : { invoice_owner_string, invoice_owner_handler, 1, 0 },
402 : : { invoice_opened_string, invoice_opened_handler, 1, 0 },
403 : : { invoice_posted_string, invoice_posted_handler, 0, 0 },
404 : : { invoice_billing_id_string, invoice_billing_id_handler, 0, 0 },
405 : : { invoice_notes_string, invoice_notes_handler, 0, 0 },
406 : : { invoice_active_string, invoice_active_handler, 1, 0 },
407 : : { invoice_terms_string, invoice_terms_handler, 0, 0 },
408 : : { invoice_posttxn_string, invoice_posttxn_handler, 0, 0 },
409 : : { invoice_postlot_string, invoice_postlot_handler, 0, 0 },
410 : : { invoice_postacc_string, invoice_postacc_handler, 0, 0 },
411 : : { invoice_currency_string, invoice_currency_handler, 0, 0 },
412 : : { "invoice:commodity", invoice_currency_handler, 0, 0 },
413 : : { invoice_billto_string, invoice_billto_handler, 0, 0 },
414 : : { invoice_tochargeamt_string, invoice_tochargeamt_handler, 0, 0},
415 : : { invoice_slots_string, invoice_slots_handler, 0, 0 },
416 : : { NULL, 0, 0, 0 }
417 : : };
418 : :
419 : : static GncInvoice*
420 : 3 : dom_tree_to_invoice (xmlNodePtr node, QofBook* book)
421 : : {
422 : : struct invoice_pdata invoice_pdata;
423 : : gboolean successful;
424 : :
425 : 3 : invoice_pdata.invoice = gncInvoiceCreate (book);
426 : 3 : invoice_pdata.book = book;
427 : 3 : gncInvoiceBeginEdit (invoice_pdata.invoice);
428 : :
429 : 3 : successful = dom_tree_generic_parse (node, invoice_handlers_v2,
430 : : &invoice_pdata);
431 : :
432 : 3 : if (successful)
433 : 3 : gncInvoiceCommitEdit (invoice_pdata.invoice);
434 : : else
435 : : {
436 : 0 : PERR ("failed to parse invoice tree");
437 : 0 : gncInvoiceDestroy (invoice_pdata.invoice);
438 : 0 : invoice_pdata.invoice = NULL;
439 : : }
440 : :
441 : 3 : return invoice_pdata.invoice;
442 : : }
443 : :
444 : : static gboolean
445 : 56 : gnc_invoice_end_handler (gpointer data_for_children,
446 : : GSList* data_from_children, GSList* sibling_data,
447 : : gpointer parent_data, gpointer global_data,
448 : : gpointer* result, const gchar* tag)
449 : : {
450 : : GncInvoice* invoice;
451 : 56 : xmlNodePtr tree = (xmlNodePtr)data_for_children;
452 : 56 : gxpf_data* gdata = (gxpf_data*)global_data;
453 : 56 : QofBook* book = static_cast<decltype (book)> (gdata->bookdata);
454 : :
455 : 56 : if (parent_data)
456 : : {
457 : 53 : return TRUE;
458 : : }
459 : :
460 : : /* OK. For some messed up reason this is getting called again with a
461 : : NULL tag. So we ignore those cases */
462 : 3 : if (!tag)
463 : : {
464 : 0 : return TRUE;
465 : : }
466 : :
467 : 3 : g_return_val_if_fail (tree, FALSE);
468 : :
469 : 3 : invoice = dom_tree_to_invoice (tree, book);
470 : 3 : if (invoice != NULL)
471 : : {
472 : 3 : gdata->cb (tag, gdata->parsedata, invoice);
473 : : }
474 : :
475 : 3 : xmlFreeNode (tree);
476 : :
477 : 3 : return invoice != NULL;
478 : : }
479 : :
480 : : static sixtp*
481 : 21 : invoice_sixtp_parser_create (void)
482 : : {
483 : 21 : return sixtp_dom_parser_new (gnc_invoice_end_handler, NULL, NULL);
484 : : }
485 : :
486 : : static gboolean
487 : 4 : invoice_should_be_saved (GncInvoice* invoice)
488 : : {
489 : : const char* id;
490 : :
491 : : /* make sure this is a valid invoice before we save it -- should have an ID */
492 : 4 : id = gncInvoiceGetID (invoice);
493 : 4 : if (id == NULL || *id == '\0')
494 : 0 : return FALSE;
495 : :
496 : 4 : return TRUE;
497 : : }
498 : :
499 : : static void
500 : 2 : do_count (QofInstance* invoice_p, gpointer count_p)
501 : : {
502 : 2 : int* count = static_cast<decltype (count)> (count_p);
503 : 2 : if (invoice_should_be_saved ((GncInvoice*)invoice_p))
504 : 2 : (*count)++;
505 : 2 : }
506 : :
507 : : static int
508 : 4 : invoice_get_count (QofBook* book)
509 : : {
510 : 4 : int count = 0;
511 : 4 : qof_object_foreach (_GNC_MOD_NAME, book, do_count, (gpointer) &count);
512 : 4 : return count;
513 : : }
514 : :
515 : : static void
516 : 2 : xml_add_invoice (QofInstance* invoice_p, gpointer out_p)
517 : : {
518 : : xmlNodePtr node;
519 : 2 : GncInvoice* invoice = (GncInvoice*) invoice_p;
520 : 2 : FILE* out = static_cast<decltype (out)> (out_p);
521 : :
522 : 2 : if (ferror (out))
523 : 0 : return;
524 : 2 : if (!invoice_should_be_saved (invoice))
525 : 0 : return;
526 : :
527 : 2 : node = invoice_dom_tree_create (invoice);
528 : 2 : xmlElemDump (out, NULL, node);
529 : 2 : xmlFreeNode (node);
530 : 2 : if (ferror (out) || fprintf (out, "\n") < 0)
531 : 0 : return;
532 : : }
533 : :
534 : : static gboolean
535 : 4 : invoice_write (FILE* out, QofBook* book)
536 : : {
537 : 4 : qof_object_foreach_sorted (_GNC_MOD_NAME, book, xml_add_invoice,
538 : : (gpointer) out);
539 : 4 : return ferror (out) == 0;
540 : : }
541 : :
542 : : static gboolean
543 : 4 : invoice_ns (FILE* out)
544 : : {
545 : 4 : g_return_val_if_fail (out, FALSE);
546 : 4 : return gnc_xml2_write_namespace_decl (out, "invoice");
547 : : }
548 : :
549 : : void
550 : 61 : gnc_invoice_xml_initialize (void)
551 : : {
552 : : static GncXmlDataType_t be_data =
553 : : {
554 : : GNC_FILE_BACKEND_VERS,
555 : : gnc_invoice_string,
556 : : invoice_sixtp_parser_create,
557 : : NULL, /* add_item */
558 : : invoice_get_count,
559 : : invoice_write,
560 : : NULL, /* scrub */
561 : : invoice_ns,
562 : : };
563 : :
564 : 61 : gnc_xml_register_backend(be_data);
565 : 61 : }
|