GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gnc-transaction-xml-v2.c
1 /********************************************************************
2  * gnc-transactions-xml-v2.c -- xml routines for transactions *
3  * Copyright (C) 2001 Rob Browning *
4  * Copyright (C) 2002 Linas Vepstas <[email protected]> *
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 [email protected] *
22  * *
23  *******************************************************************/
24 
25 #include "config.h"
26 
27 #include <glib.h>
28 #include <string.h>
29 
30 #include "gnc-xml-helper.h"
31 
32 #include "sixtp.h"
33 #include "sixtp-utils.h"
34 #include "sixtp-parsers.h"
35 #include "sixtp-utils.h"
36 #include "sixtp-dom-parsers.h"
37 #include "sixtp-dom-generators.h"
38 
39 #include "gnc-xml.h"
40 
41 #include "io-gncxml-gen.h"
42 
43 #include "sixtp-dom-parsers.h"
44 #include "AccountP.h"
45 #include "Transaction.h"
46 #include "TransactionP.h"
47 #include "gnc-lot.h"
48 #include "gnc-lot-p.h"
49 
50 const gchar *transaction_version_string = "2.0.0";
51 
52 /* EFFECTIVE FRIEND FUNCTION */
53 extern KvpFrame *qof_instance_get_slots (const QofInstance *);
54 
55 static void
56 add_gnc_num(xmlNodePtr node, const gchar *tag, gnc_numeric num)
57 {
58  xmlAddChild(node, gnc_numeric_to_dom_tree(tag, &num));
59 }
60 
61 static void
62 add_timespec(xmlNodePtr node, const gchar *tag, Timespec tms, gboolean always)
63 {
64  if (always || !((tms.tv_sec == 0) && (tms.tv_nsec == 0)))
65  {
66  xmlAddChild(node, timespec_to_dom_tree(tag, &tms));
67  }
68 }
69 
70 static xmlNodePtr
71 split_to_dom_tree(const gchar *tag, Split *spl)
72 {
73  xmlNodePtr ret;
74 
75  ret = xmlNewNode(NULL, BAD_CAST tag);
76 
77  xmlAddChild(ret, guid_to_dom_tree("split:id", xaccSplitGetGUID(spl)));
78 
79  {
80  char *memo = g_strdup (xaccSplitGetMemo(spl));
81 
82  if (memo && g_strcmp0(memo, "") != 0)
83  {
84  xmlNewTextChild(ret, NULL, BAD_CAST "split:memo",
85  checked_char_cast (memo));
86  }
87  g_free (memo);
88  }
89 
90  {
91  char *action = g_strdup (xaccSplitGetAction(spl));
92 
93  if (action && g_strcmp0(action, "") != 0)
94  {
95  xmlNewTextChild(ret, NULL, BAD_CAST "split:action",
96  checked_char_cast (action));
97  }
98  g_free (action);
99  }
100 
101  {
102  char tmp[2];
103 
104  tmp[0] = xaccSplitGetReconcile(spl);
105  tmp[1] = '\0';
106 
107  xmlNewTextChild(ret, NULL, BAD_CAST "split:reconciled-state",
108  BAD_CAST tmp);
109  }
110 
111  add_timespec(ret, "split:reconcile-date",
112  xaccSplitRetDateReconciledTS(spl), FALSE);
113 
114  add_gnc_num(ret, "split:value", xaccSplitGetValue(spl));
115 
116  add_gnc_num(ret, "split:quantity", xaccSplitGetAmount(spl));
117 
118  {
119  Account * account = xaccSplitGetAccount (spl);
120 
121  xmlAddChild (ret, guid_to_dom_tree("split:account",
122  xaccAccountGetGUID (account)));
123  }
124  {
125  GNCLot * lot = xaccSplitGetLot (spl);
126 
127  if (lot)
128  {
129  xmlAddChild (ret, guid_to_dom_tree("split:lot",
130  gnc_lot_get_guid(lot)));
131  }
132  }
133  {
134  xmlNodePtr kvpnode = kvp_frame_to_dom_tree("split:slots",
135  qof_instance_get_slots (QOF_INSTANCE (spl)));
136  if (kvpnode)
137  {
138  xmlAddChild(ret, kvpnode);
139  }
140  }
141 
142  return ret;
143 }
144 
145 static void
146 add_trans_splits(xmlNodePtr node, Transaction *trn)
147 {
148  GList *n;
149  xmlNodePtr toaddto;
150 
151  toaddto = xmlNewChild(node, NULL, BAD_CAST "trn:splits", NULL);
152 
153  for (n = xaccTransGetSplitList(trn); n; n = n->next)
154  {
155  Split *s = n->data;
156  xmlAddChild(toaddto, split_to_dom_tree("trn:split", s));
157  }
158 }
159 
160 xmlNodePtr
161 gnc_transaction_dom_tree_create(Transaction *trn)
162 {
163  xmlNodePtr ret;
164  gchar *str = NULL;
165 
166  ret = xmlNewNode(NULL, BAD_CAST "gnc:transaction");
167 
168  xmlSetProp(ret, BAD_CAST "version",
169  BAD_CAST transaction_version_string);
170 
171  xmlAddChild(ret, guid_to_dom_tree("trn:id", xaccTransGetGUID(trn)));
172 
173  xmlAddChild(ret, commodity_ref_to_dom_tree("trn:currency",
174  xaccTransGetCurrency(trn)));
175  str = g_strdup (xaccTransGetNum(trn));
176  if (str && (g_strcmp0(str, "") != 0))
177  {
178  xmlNewTextChild(ret, NULL, BAD_CAST "trn:num",
179  checked_char_cast (str));
180  }
181  g_free (str);
182 
183  add_timespec(ret, "trn:date-posted", xaccTransRetDatePostedTS(trn), TRUE);
184 
185  add_timespec(ret, "trn:date-entered",
186  xaccTransRetDateEnteredTS(trn), TRUE);
187 
188  str = g_strdup (xaccTransGetDescription(trn));
189  if (str)
190  {
191  xmlNewTextChild(ret, NULL, BAD_CAST "trn:description",
192  checked_char_cast (str));
193  }
194  g_free (str);
195 
196  {
197  xmlNodePtr kvpnode = kvp_frame_to_dom_tree("trn:slots",
198  qof_instance_get_slots (QOF_INSTANCE (trn)));
199  if (kvpnode)
200  {
201  xmlAddChild(ret, kvpnode);
202  }
203  }
204 
205  add_trans_splits(ret, trn);
206 
207  return ret;
208 }
209 
210 /***********************************************************************/
211 
213 {
214  Split *split;
215  QofBook *book;
216 };
217 
218 static inline gboolean
219 set_spl_string(xmlNodePtr node, Split *spl,
220  void (*func)(Split *spl, const char *txt))
221 {
222  gchar *tmp = dom_tree_to_text(node);
223  g_return_val_if_fail(tmp, FALSE);
224 
225  func(spl, tmp);
226 
227  g_free(tmp);
228 
229  return TRUE;
230 }
231 
232 static inline gboolean
233 set_spl_gnc_num(xmlNodePtr node, Split* spl,
234  void (*func)(Split *spl, gnc_numeric gn))
235 {
236  gnc_numeric *num = dom_tree_to_gnc_numeric(node);
237  g_return_val_if_fail(num, FALSE);
238 
239  func(spl, *num);
240 
241  g_free(num);
242 
243  return FALSE;
244 }
245 
246 static gboolean
247 spl_id_handler(xmlNodePtr node, gpointer data)
248 {
249  struct split_pdata *pdata = data;
250  GncGUID *tmp = dom_tree_to_guid(node);
251  g_return_val_if_fail(tmp, FALSE);
252 
253  xaccSplitSetGUID(pdata->split, tmp);
254 
255  g_free(tmp);
256  return TRUE;
257 }
258 
259 static gboolean
260 spl_memo_handler(xmlNodePtr node, gpointer data)
261 {
262  struct split_pdata *pdata = data;
263  return set_spl_string(node, pdata->split, xaccSplitSetMemo);
264 }
265 
266 static gboolean
267 spl_action_handler(xmlNodePtr node, gpointer data)
268 {
269  struct split_pdata *pdata = data;
270  return set_spl_string(node, pdata->split, xaccSplitSetAction);
271 }
272 
273 static gboolean
274 spl_reconciled_state_handler(xmlNodePtr node, gpointer data)
275 {
276  struct split_pdata *pdata = data;
277  gchar *tmp = dom_tree_to_text(node);
278  g_return_val_if_fail(tmp, FALSE);
279 
280  xaccSplitSetReconcile(pdata->split, tmp[0]);
281 
282  g_free(tmp);
283 
284  return TRUE;
285 }
286 
287 static gboolean
288 spl_reconcile_date_handler(xmlNodePtr node, gpointer data)
289 {
290  struct split_pdata *pdata = data;
291  Timespec ts;
292 
293  ts = dom_tree_to_timespec(node);
294  if (!dom_tree_valid_timespec(&ts, node->name)) return FALSE;
295 
296  xaccSplitSetDateReconciledTS(pdata->split, &ts);
297 
298  return TRUE;
299 }
300 
301 static gboolean
302 spl_value_handler(xmlNodePtr node, gpointer data)
303 {
304  struct split_pdata *pdata = data;
305  return set_spl_gnc_num(node, pdata->split, xaccSplitSetValue);
306 }
307 
308 static gboolean
309 spl_quantity_handler(xmlNodePtr node, gpointer data)
310 {
311  struct split_pdata *pdata = data;
312  return set_spl_gnc_num(node, pdata->split, xaccSplitSetAmount);
313 }
314 
315 gboolean gnc_transaction_xml_v2_testing = FALSE;
316 
317 static gboolean
318 spl_account_handler(xmlNodePtr node, gpointer data)
319 {
320  struct split_pdata *pdata = data;
321  GncGUID *id = dom_tree_to_guid(node);
322  Account *account;
323 
324  g_return_val_if_fail(id, FALSE);
325 
326  account = xaccAccountLookup (id, pdata->book);
327  if (!account && gnc_transaction_xml_v2_testing &&
328  !guid_equal (id, guid_null ()))
329  {
330  account = xaccMallocAccount (pdata->book);
331  xaccAccountSetGUID (account, id);
333  xaccSplitGetAmount (pdata->split).denom);
334  }
335 
336  xaccAccountInsertSplit (account, pdata->split);
337 
338  g_free(id);
339 
340  return TRUE;
341 }
342 
343 static gboolean
344 spl_lot_handler(xmlNodePtr node, gpointer data)
345 {
346  struct split_pdata *pdata = data;
347  GncGUID *id = dom_tree_to_guid(node);
348  GNCLot *lot;
349 
350  g_return_val_if_fail(id, FALSE);
351 
352  lot = gnc_lot_lookup (id, pdata->book);
353  if (!lot && gnc_transaction_xml_v2_testing &&
354  !guid_equal (id, guid_null ()))
355  {
356  lot = gnc_lot_new (pdata->book);
357  gnc_lot_set_guid (lot, *id);
358  }
359 
360  gnc_lot_add_split (lot, pdata->split);
361 
362  g_free(id);
363 
364  return TRUE;
365 }
366 
367 static gboolean
368 spl_slots_handler(xmlNodePtr node, gpointer data)
369 {
370  struct split_pdata *pdata = data;
371  gboolean successful;
372 
373  successful = dom_tree_to_kvp_frame_given(node,
374  qof_instance_get_slots (QOF_INSTANCE (pdata->split)));
375  g_return_val_if_fail(successful, FALSE);
376 
377  return TRUE;
378 }
379 
380 struct dom_tree_handler spl_dom_handlers[] =
381 {
382  { "split:id", spl_id_handler, 1, 0 },
383  { "split:memo", spl_memo_handler, 0, 0 },
384  { "split:action", spl_action_handler, 0, 0 },
385  { "split:reconciled-state", spl_reconciled_state_handler, 1, 0 },
386  { "split:reconcile-date", spl_reconcile_date_handler, 0, 0 },
387  { "split:value", spl_value_handler, 1, 0 },
388  { "split:quantity", spl_quantity_handler, 1, 0 },
389  { "split:account", spl_account_handler, 1, 0 },
390  { "split:lot", spl_lot_handler, 0, 0 },
391  { "split:slots", spl_slots_handler, 0, 0 },
392  { NULL, NULL, 0, 0 },
393 };
394 
395 static Split*
396 dom_tree_to_split(xmlNodePtr node, QofBook *book)
397 {
398  struct split_pdata pdata;
399  Split *ret;
400 
401  g_return_val_if_fail (book, NULL);
402 
403  ret = xaccMallocSplit(book);
404  g_return_val_if_fail(ret, NULL);
405 
406  pdata.split = ret;
407  pdata.book = book;
408 
409  /* this isn't going to work in a testing setup */
410  if (dom_tree_generic_parse(node, spl_dom_handlers, &pdata))
411  {
412  return ret;
413  }
414  else
415  {
416  xaccSplitDestroy(ret);
417  return NULL;
418  }
419 }
420 
421 /***********************************************************************/
422 
424 {
425  Transaction *trans;
426  QofBook *book;
427 };
428 
429 static inline gboolean
430 set_tran_string(xmlNodePtr node, Transaction *trn,
431  void (*func)(Transaction *trn, const char *txt))
432 {
433  gchar *tmp;
434 
435  tmp = dom_tree_to_text(node);
436 
437  g_return_val_if_fail(tmp, FALSE);
438 
439  func(trn, tmp);
440 
441  g_free(tmp);
442 
443  return TRUE;
444 }
445 
446 static inline gboolean
447 set_tran_date(xmlNodePtr node, Transaction *trn,
448  void (*func)(Transaction *trn, const Timespec *tm))
449 {
450  Timespec tm;
451 
452  tm = dom_tree_to_timespec(node);
453 
454  if (!dom_tree_valid_timespec(&tm, node->name)) return FALSE;
455 
456  func(trn, &tm);
457 
458  return TRUE;
459 }
460 
461 static gboolean
462 trn_id_handler(xmlNodePtr node, gpointer trans_pdata)
463 {
464  struct trans_pdata *pdata = trans_pdata;
465  Transaction *trn = pdata->trans;
466  GncGUID *tmp = dom_tree_to_guid(node);
467 
468  g_return_val_if_fail(tmp, FALSE);
469 
470  xaccTransSetGUID((Transaction*)trn, tmp);
471 
472  g_free(tmp);
473 
474  return TRUE;
475 }
476 
477 static gboolean
478 trn_currency_handler(xmlNodePtr node, gpointer trans_pdata)
479 {
480  struct trans_pdata *pdata = trans_pdata;
481  Transaction *trn = pdata->trans;
482  gnc_commodity *ref;
483 
484  ref = dom_tree_to_commodity_ref(node, pdata->book);
485  xaccTransSetCurrency(trn, ref);
486 
487  return TRUE;
488 }
489 
490 static gboolean
491 trn_num_handler(xmlNodePtr node, gpointer trans_pdata)
492 {
493  struct trans_pdata *pdata = trans_pdata;
494  Transaction *trn = pdata->trans;
495 
496  return set_tran_string(node, trn, xaccTransSetNum);
497 }
498 
499 static gboolean
500 trn_date_posted_handler(xmlNodePtr node, gpointer trans_pdata)
501 {
502  struct trans_pdata *pdata = trans_pdata;
503  Transaction *trn = pdata->trans;
504 
505  return set_tran_date(node, trn, xaccTransSetDatePostedTS);
506 }
507 
508 static gboolean
509 trn_date_entered_handler(xmlNodePtr node, gpointer trans_pdata)
510 {
511  struct trans_pdata *pdata = trans_pdata;
512  Transaction *trn = pdata->trans;
513 
514  return set_tran_date(node, trn, xaccTransSetDateEnteredTS);
515 }
516 
517 static gboolean
518 trn_description_handler(xmlNodePtr node, gpointer trans_pdata)
519 {
520  struct trans_pdata *pdata = trans_pdata;
521  Transaction *trn = pdata->trans;
522 
523  return set_tran_string(node, trn, xaccTransSetDescription);
524 }
525 
526 static gboolean
527 trn_slots_handler(xmlNodePtr node, gpointer trans_pdata)
528 {
529  struct trans_pdata *pdata = trans_pdata;
530  Transaction *trn = pdata->trans;
531  gboolean successful;
532 
533  successful = dom_tree_to_kvp_frame_given(node, qof_instance_get_slots (QOF_INSTANCE (trn)));
534 
535  g_return_val_if_fail(successful, FALSE);
536 
537  return TRUE;
538 }
539 
540 static gboolean
541 trn_splits_handler(xmlNodePtr node, gpointer trans_pdata)
542 {
543  struct trans_pdata *pdata = trans_pdata;
544  Transaction *trn = pdata->trans;
545  xmlNodePtr mark;
546 
547  g_return_val_if_fail(node, FALSE);
548  g_return_val_if_fail(node->xmlChildrenNode, FALSE);
549 
550  for (mark = node->xmlChildrenNode; mark; mark = mark->next)
551  {
552  Split *spl;
553 
554  if (g_strcmp0("text", (char*)mark->name) == 0)
555  continue;
556 
557  if (g_strcmp0("trn:split", (char*)mark->name))
558  {
559  return FALSE;
560  }
561 
562  spl = dom_tree_to_split(mark, pdata->book);
563 
564  if (spl)
565  {
566  xaccTransAppendSplit(trn, spl);
567  }
568  else
569  {
570  return FALSE;
571  }
572  }
573  return TRUE;
574 }
575 
576 struct dom_tree_handler trn_dom_handlers[] =
577 {
578  { "trn:id", trn_id_handler, 1, 0 },
579  { "trn:currency", trn_currency_handler, 0, 0},
580  { "trn:num", trn_num_handler, 0, 0 },
581  { "trn:date-posted", trn_date_posted_handler, 1, 0 },
582  { "trn:date-entered", trn_date_entered_handler, 1, 0 },
583  { "trn:description", trn_description_handler, 0, 0 },
584  { "trn:slots", trn_slots_handler, 0, 0 },
585  { "trn:splits", trn_splits_handler, 1, 0 },
586  { NULL, NULL, 0, 0 },
587 };
588 
589 static gboolean
590 gnc_transaction_end_handler(gpointer data_for_children,
591  GSList* data_from_children, GSList* sibling_data,
592  gpointer parent_data, gpointer global_data,
593  gpointer *result, const gchar *tag)
594 {
595  Transaction *trn = NULL;
596  xmlNodePtr tree = (xmlNodePtr)data_for_children;
597  gxpf_data *gdata = (gxpf_data*)global_data;
598 
599  if (parent_data)
600  {
601  return TRUE;
602  }
603 
604  /* OK. For some messed up reason this is getting called again with a
605  NULL tag. So we ignore those cases */
606  if (!tag)
607  {
608  return TRUE;
609  }
610 
611  g_return_val_if_fail(tree, FALSE);
612 
613  trn = dom_tree_to_transaction(tree, gdata->bookdata);
614  if (trn != NULL)
615  {
616  gdata->cb(tag, gdata->parsedata, trn);
617  }
618 
619  xmlFreeNode(tree);
620 
621  return trn != NULL;
622 }
623 
624 Transaction *
625 dom_tree_to_transaction( xmlNodePtr node, QofBook *book )
626 {
627  Transaction *trn;
628  gboolean successful;
629  struct trans_pdata pdata;
630 
631  g_return_val_if_fail(node, NULL);
632  g_return_val_if_fail(book, NULL);
633 
634  trn = xaccMallocTransaction(book);
635  g_return_val_if_fail(trn, NULL);
636  xaccTransBeginEdit(trn);
637 
638  pdata.trans = trn;
639  pdata.book = book;
640 
641  successful = dom_tree_generic_parse(node, trn_dom_handlers, &pdata);
642 
643  xaccTransCommitEdit(trn);
644 
645  if ( !successful )
646  {
647  xmlElemDump(stdout, NULL, node);
648  xaccTransBeginEdit(trn);
649  xaccTransDestroy(trn);
650  xaccTransCommitEdit(trn);
651  trn = NULL;
652  }
653 
654  return trn;
655 }
656 
657 sixtp*
658 gnc_transaction_sixtp_parser_create(void)
659 {
660  return sixtp_dom_parser_new(gnc_transaction_end_handler, NULL, NULL);
661 }
void xaccSplitSetValue(Split *s, gnc_numeric amt)
Definition: Split.c:1294
#define xaccTransAppendSplit(t, s)
Definition: Transaction.h:357
Transaction * xaccMallocTransaction(QofBook *book)
Definition: Transaction.c:513
Definition: sixtp.h:93
void xaccSplitSetAction(Split *split, const char *actn)
Definition: Split.c:1793
gboolean xaccSplitDestroy(Split *split)
Definition: Split.c:1492
Timespec xaccSplitRetDateReconciledTS(const Split *split)
Definition: Split.c:1884
char xaccSplitGetReconcile(const Split *split)
Definition: Split.c:1980
void gnc_lot_add_split(GNCLot *lot, Split *split)
Definition: gnc-lot.c:569
void xaccTransSetDescription(Transaction *trans, const char *desc)
Definition: Transaction.c:2085
void xaccTransSetNum(Transaction *trans, const char *xnum)
Definition: Transaction.c:2065
Use a 64-bit unsigned int timespec.
Definition: gnc-date.h:299
void xaccSplitSetReconcile(Split *split, char recn)
Definition: Split.c:1826
const char * xaccTransGetNum(const Transaction *trans)
Definition: Transaction.c:2178
void xaccTransSetDateEnteredTS(Transaction *trans, const Timespec *ts)
Definition: Transaction.c:1988
Definition: guid.h:65
void xaccTransSetCurrency(Transaction *trans, gnc_commodity *curr)
Definition: Transaction.c:1354
void xaccTransDestroy(Transaction *trans)
Definition: Transaction.c:1402
#define xaccAccountGetGUID(X)
Definition: Account.h:239
void xaccSplitSetAmount(Split *s, gnc_numeric amt)
Definition: Split.c:1258
gboolean guid_equal(const GncGUID *guid_1, const GncGUID *guid_2)
void xaccSplitSetMemo(Split *split, const char *memo)
Definition: Split.c:1774
Timespec xaccTransRetDateEnteredTS(const Transaction *trans)
Definition: Transaction.c:2273
const char * xaccTransGetDescription(const Transaction *trans)
Definition: Transaction.c:2184
void xaccTransCommitEdit(Transaction *trans)
Definition: Transaction.c:1579
#define xaccSplitGetGUID(X)
Definition: Split.h:521
void xaccTransBeginEdit(Transaction *trans)
Definition: Transaction.c:1380
void xaccAccountSetCommoditySCU(Account *acc, int scu)
Definition: Account.c:2435
Split * xaccMallocSplit(QofBook *book)
Definition: Split.c:582
#define xaccTransGetGUID(X)
Definition: Transaction.h:755
Definition: SplitP.h:71
gnc_numeric xaccSplitGetValue(const Split *split)
Definition: Split.c:1993
Account * xaccSplitGetAccount(const Split *s)
Definition: Split.c:968
const GncGUID * guid_null(void)
gnc_commodity * xaccTransGetCurrency(const Transaction *trans)
Definition: Transaction.c:1348
#define xaccAccountInsertSplit(acc, s)
Definition: Account.h:972
struct KvpFrameImpl KvpFrame
Definition: kvp_frame.h:76
Timespec xaccTransRetDatePostedTS(const Transaction *trans)
Definition: Transaction.c:2243
Account * xaccMallocAccount(QofBook *book)
Definition: Account.c:1083
void xaccSplitSetDateReconciledTS(Split *split, Timespec *ts)
Definition: Split.c:1865
const char * xaccSplitGetMemo(const Split *split)
Definition: Split.c:1968
const char * xaccSplitGetAction(const Split *split)
Definition: Split.c:1974
API for Transactions and Splits (journal entries)
SplitList * xaccTransGetSplitList(const Transaction *trans)
Definition: Transaction.c:2164
GNCLot * xaccSplitGetLot(const Split *split)
Definition: Split.c:1953
void xaccTransSetDatePostedTS(Transaction *trans, const Timespec *ts)
Definition: Transaction.c:1970
gnc_numeric xaccSplitGetAmount(const Split *split)
Definition: Split.c:1987
Account * xaccAccountLookup(const GncGUID *guid, QofBook *book)
Definition: Account.c:1827