GnuCash  5.6-150-g038405b370+
gnc-account-xml-v2.cpp
1 /********************************************************************\
2  * gnc-account-xml-v2.c -- account xml i/o implementation *
3  * *
4  * Copyright (C) 2001 James LewisMoss <dres@debian.org> *
5  * Copyright (C) 2002 Linas Vepstas <linas@linas.org> *
6  * *
7  * This program is free software; you can redistribute it and/or *
8  * modify it under the terms of the GNU General Public License as *
9  * published by the Free Software Foundation; either version 2 of *
10  * the License, or (at your option) any later version. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License*
18  * along with this program; if not, contact: *
19  * *
20  * Free Software Foundation Voice: +1-617-542-5942 *
21  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
22  * Boston, MA 02110-1301, USA gnu@gnu.org *
23  * *
24 \********************************************************************/
25 #include <glib.h>
26 
27 #include <config.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <AccountP.hpp>
31 #include <Account.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 
41 #include "gnc-xml.h"
42 #include "io-gncxml-gen.h"
43 #include "io-gncxml-v2.h"
44 
45 #include "sixtp-dom-parsers.h"
46 
47 static QofLogModule log_module = GNC_MOD_IO;
48 
49 const gchar* account_version_string = "2.0.0";
50 
51 /* ids */
52 #define gnc_account_string "gnc:account"
53 #define act_name_string "act:name"
54 #define act_id_string "act:id"
55 #define act_type_string "act:type"
56 #define act_commodity_string "act:commodity"
57 #define act_commodity_scu_string "act:commodity-scu"
58 #define act_non_standard_scu_string "act:non-standard-scu"
59 #define act_code_string "act:code"
60 #define act_description_string "act:description"
61 #define act_slots_string "act:slots"
62 #define act_parent_string "act:parent"
63 #define act_lots_string "act:lots"
64 /* The currency and security strings should not appear in newer
65  * xml files (anything post-gnucash-1.6) */
66 #define act_currency_string "act:currency"
67 #define act_currency_scu_string "act:currency-scu"
68 #define act_security_string "act:security"
69 #define act_security_scu_string "act:security-scu"
70 #define act_hidden_string "act:hidden"
71 #define act_placeholder_string "act:placeholder"
72 
73 xmlNodePtr
74 gnc_account_dom_tree_create (Account* act,
75  gboolean exporting,
76  gboolean allow_incompat)
77 {
78  const char* str;
79  xmlNodePtr ret;
80  GList* lots, *n;
81  Account* parent;
82  gnc_commodity* acct_commodity;
83 
84  ENTER ("(account=%p)", act);
85 
86  ret = xmlNewNode (NULL, BAD_CAST gnc_account_string);
87  xmlSetProp (ret, BAD_CAST "version", BAD_CAST account_version_string);
88 
89  xmlAddChild (ret, text_to_dom_tree (act_name_string,
90  xaccAccountGetName (act)));
91 
92  xmlAddChild (ret, guid_to_dom_tree (act_id_string, xaccAccountGetGUID (act)));
93 
94  xmlAddChild (ret, text_to_dom_tree (
95  act_type_string,
97 
98  /* Don't write new XML tags in version 2.3.x and 2.4.x because it
99  would mean 2.2.x cannot read those files again. But we can
100  enable writing these tags in 2.5.x or late in 2.4.x. */
101  /*
102  xmlAddChild(ret, boolean_to_dom_tree(
103  act_hidden_string,
104  xaccAccountGetHidden(act)));
105  xmlAddChild(ret, boolean_to_dom_tree(
106  act_placeholder_string,
107  xaccAccountGetPlaceholder(act)));
108  */
109 
110  acct_commodity = xaccAccountGetCommodity (act);
111  if (acct_commodity != NULL)
112  {
113  xmlAddChild (ret, commodity_ref_to_dom_tree (act_commodity_string,
114  acct_commodity));
115 
116  xmlAddChild (ret, int_to_dom_tree (act_commodity_scu_string,
118 
119  if (xaccAccountGetNonStdSCU (act))
120  xmlNewChild (ret, NULL, BAD_CAST act_non_standard_scu_string, NULL);
121  }
122 
123  str = xaccAccountGetCode (act);
124  if (str && *str)
125  {
126  xmlAddChild (ret, text_to_dom_tree (act_code_string, str));
127  }
128 
129  str = xaccAccountGetDescription (act);
130  if (str && *str)
131  {
132  xmlAddChild (ret, text_to_dom_tree (act_description_string, str));
133  }
134 
135  /* xmlAddChild won't do anything with a NULL, so tests are superfluous. */
136  xmlAddChild (ret, qof_instance_slots_to_dom_tree (act_slots_string,
137  QOF_INSTANCE (act)));
138  parent = gnc_account_get_parent (act);
139  if (parent)
140  {
141  if (!gnc_account_is_root (parent) || allow_incompat)
142  xmlAddChild (ret, guid_to_dom_tree (act_parent_string,
143  xaccAccountGetGUID (parent)));
144  }
145 
146  lots = xaccAccountGetLotList (act);
147  PINFO ("lot list=%p", lots);
148  if (lots && !exporting)
149  {
150  xmlNodePtr toaddto = xmlNewChild (ret, NULL, BAD_CAST act_lots_string, NULL);
151 
152  lots = g_list_sort (lots, qof_instance_guid_compare);
153 
154  for (n = lots; n; n = n->next)
155  {
156  GNCLot* lot = static_cast<decltype (lot)> (n->data);
157  xmlAddChild (toaddto, gnc_lot_dom_tree_create (lot));
158  }
159  }
160  g_list_free (lots);
161 
162  LEAVE ("");
163  return ret;
164 }
165 
166 /***********************************************************************/
167 
169 {
170  Account* account;
171  QofBook* book;
172 };
173 
174 static inline gboolean
175 set_string (xmlNodePtr node, Account* act,
176  void (*func) (Account* act, const gchar* txt))
177 {
178  gchar* txt = dom_tree_to_text (node);
179  g_return_val_if_fail (txt, FALSE);
180 
181  func (act, txt);
182 
183  g_free (txt);
184 
185  return TRUE;
186 }
187 
188 static gboolean
189 account_name_handler (xmlNodePtr node, gpointer act_pdata)
190 {
191  struct account_pdata* pdata = static_cast<decltype (pdata)> (act_pdata);
192 
193  return set_string (node, pdata->account, xaccAccountSetName);
194 }
195 
196 static gboolean
197 account_id_handler (xmlNodePtr node, gpointer act_pdata)
198 {
199  struct account_pdata* pdata = static_cast<decltype (pdata)> (act_pdata);
200  GncGUID* guid;
201 
202  guid = dom_tree_to_guid (node);
203  g_return_val_if_fail (guid, FALSE);
204 
205  xaccAccountSetGUID (pdata->account, guid);
206 
207  guid_free (guid);
208 
209  return TRUE;
210 }
211 
212 static gboolean
213 account_type_handler (xmlNodePtr node, gpointer act_pdata)
214 {
215  struct account_pdata* pdata = static_cast<decltype (pdata)> (act_pdata);
217  char* string;
218 
219  string = (char*) xmlNodeGetContent (node->xmlChildrenNode);
220  xaccAccountStringToType (string, &type);
221  xmlFree (string);
222 
223  xaccAccountSetType (pdata->account, type);
224 
225  return TRUE;
226 }
227 
228 static gboolean
229 account_commodity_handler (xmlNodePtr node, gpointer act_pdata)
230 {
231  struct account_pdata* pdata = static_cast<decltype (pdata)> (act_pdata);
232  gnc_commodity* ref;
233 
234 // ref = dom_tree_to_commodity_ref_no_engine(node, pdata->book);
235  ref = dom_tree_to_commodity_ref (node, pdata->book);
236  xaccAccountSetCommodity (pdata->account, ref);
237 
238  return TRUE;
239 }
240 
241 static gboolean
242 account_commodity_scu_handler (xmlNodePtr node, gpointer act_pdata)
243 {
244  struct account_pdata* pdata = static_cast<decltype (pdata)> (act_pdata);
245  gint64 val;
246 
247  dom_tree_to_integer (node, &val);
248  xaccAccountSetCommoditySCU (pdata->account, val);
249 
250  return TRUE;
251 }
252 
253 static gboolean
254 account_hidden_handler (xmlNodePtr node, gpointer act_pdata)
255 {
256  struct account_pdata* pdata = static_cast<decltype (pdata)> (act_pdata);
257  gboolean val;
258 
259  dom_tree_to_boolean (node, &val);
260  xaccAccountSetHidden (pdata->account, val);
261 
262  return TRUE;
263 }
264 
265 static gboolean
266 account_placeholder_handler (xmlNodePtr node, gpointer act_pdata)
267 {
268  struct account_pdata* pdata = static_cast<decltype (pdata)> (act_pdata);
269  gboolean val;
270 
271  dom_tree_to_boolean (node, &val);
272  xaccAccountSetPlaceholder (pdata->account, val);
273 
274  return TRUE;
275 }
276 
277 static gboolean
278 account_non_standard_scu_handler (xmlNodePtr node, gpointer act_pdata)
279 {
280  struct account_pdata* pdata = static_cast<decltype (pdata)> (act_pdata);
281 
282  xaccAccountSetNonStdSCU (pdata->account, TRUE);
283 
284  return TRUE;
285 }
286 
287 /* ============================================================== */
288 /* The following deprecated routines are here only to service
289  * older XML files. */
290 
291 static gboolean
292 deprecated_account_currency_handler (xmlNodePtr node, gpointer act_pdata)
293 {
294  struct account_pdata* pdata = static_cast<decltype (pdata)> (act_pdata);
295  gnc_commodity* ref;
296 
297  PWARN ("Account %s: Obsolete xml tag 'act:currency' will not be preserved.",
298  xaccAccountGetName (pdata->account));
299  ref = dom_tree_to_commodity_ref_no_engine (node, pdata->book);
300  DxaccAccountSetCurrency (pdata->account, ref);
301 
302  return TRUE;
303 }
304 
305 static gboolean
306 deprecated_account_currency_scu_handler (xmlNodePtr node, gpointer act_pdata)
307 {
308  struct account_pdata* pdata = static_cast<decltype (pdata)> (act_pdata);
309  PWARN ("Account %s: Obsolete xml tag 'act:currency-scu' will not be preserved.",
310  xaccAccountGetName (pdata->account));
311  return TRUE;
312 }
313 
314 static gboolean
315 deprecated_account_security_handler (xmlNodePtr node, gpointer act_pdata)
316 {
317  struct account_pdata* pdata = static_cast<decltype (pdata)> (act_pdata);
318  gnc_commodity* ref, *orig = xaccAccountGetCommodity (pdata->account);
319 
320  PWARN ("Account %s: Obsolete xml tag 'act:security' will not be preserved.",
321  xaccAccountGetName (pdata->account));
322  /* If the account has both a commodity and a security element, and
323  the commodity is a currency, then the commodity is probably
324  wrong. In that case we want to replace it with the
325  security. jralls 2010-11-02 */
326  if (!orig || gnc_commodity_is_currency (orig))
327  {
328  ref = dom_tree_to_commodity_ref_no_engine (node, pdata->book);
329  xaccAccountSetCommodity (pdata->account, ref);
330  /* If the SCU was set, it was probably wrong, so zero it out
331  so that the SCU handler can fix it if there's a
332  security-scu element. jralls 2010-11-02 */
333  xaccAccountSetCommoditySCU (pdata->account, 0);
334  }
335 
336  return TRUE;
337 }
338 
339 static gboolean
340 deprecated_account_security_scu_handler (xmlNodePtr node, gpointer act_pdata)
341 {
342  struct account_pdata* pdata = static_cast<decltype (pdata)> (act_pdata);
343  gint64 val;
344 
345  PWARN ("Account %s: Obsolete xml tag 'act:security-scu' will not be preserved.",
346  xaccAccountGetName (pdata->account));
347  if (!xaccAccountGetCommoditySCU (pdata->account))
348  {
349  dom_tree_to_integer (node, &val);
350  xaccAccountSetCommoditySCU (pdata->account, val);
351  }
352 
353  return TRUE;
354 }
355 
356 /* ============================================================== */
357 
358 static gboolean
359 account_slots_handler (xmlNodePtr node, gpointer act_pdata)
360 {
361  struct account_pdata* pdata = static_cast<decltype (pdata)> (act_pdata);
362  return dom_tree_create_instance_slots (node, QOF_INSTANCE (pdata->account));
363 }
364 
365 static gboolean
366 account_parent_handler (xmlNodePtr node, gpointer act_pdata)
367 {
368  struct account_pdata* pdata = static_cast<decltype (pdata)> (act_pdata);
369  Account* parent;
370  GncGUID* gid;
371 
372  gid = dom_tree_to_guid (node);
373  g_return_val_if_fail (gid, FALSE);
374 
375  parent = xaccAccountLookup (gid, pdata->book);
376  if (!parent)
377  {
378  guid_free (gid);
379  g_return_val_if_fail (parent, FALSE);
380  }
381 
382  gnc_account_append_child (parent, pdata->account);
383 
384  guid_free (gid);
385 
386  return TRUE;
387 }
388 
389 static gboolean
390 account_code_handler (xmlNodePtr node, gpointer act_pdata)
391 {
392  struct account_pdata* pdata = static_cast<decltype (pdata)> (act_pdata);
393 
394  return set_string (node, pdata->account, xaccAccountSetCode);
395 }
396 
397 static gboolean
398 account_description_handler (xmlNodePtr node, gpointer act_pdata)
399 {
400  struct account_pdata* pdata = static_cast<decltype (pdata)> (act_pdata);
401 
402  return set_string (node, pdata->account, xaccAccountSetDescription);
403 }
404 
405 static gboolean
406 account_lots_handler (xmlNodePtr node, gpointer act_pdata)
407 {
408  struct account_pdata* pdata = static_cast<decltype (pdata)> (act_pdata);
409  xmlNodePtr mark;
410 
411  g_return_val_if_fail (node, FALSE);
412  g_return_val_if_fail (node->xmlChildrenNode, FALSE);
413 
414  for (mark = node->xmlChildrenNode; mark; mark = mark->next)
415  {
416  GNCLot* lot;
417 
418  if (g_strcmp0 ("text", (char*) mark->name) == 0)
419  continue;
420 
421  lot = dom_tree_to_lot (mark, pdata->book);
422 
423  if (lot)
424  {
425  xaccAccountInsertLot (pdata->account, lot);
426  }
427  else
428  {
429  return FALSE;
430  }
431  }
432  return TRUE;
433 }
434 
435 static struct dom_tree_handler account_handlers_v2[] =
436 {
437  { act_name_string, account_name_handler, 1, 0 },
438  { act_id_string, account_id_handler, 1, 0 },
439  { act_type_string, account_type_handler, 1, 0 },
440  { act_commodity_string, account_commodity_handler, 0, 0 },
441  { act_commodity_scu_string, account_commodity_scu_handler, 0, 0 },
442  { act_non_standard_scu_string, account_non_standard_scu_handler, 0, 0 },
443  { act_code_string, account_code_handler, 0, 0 },
444  { act_description_string, account_description_handler, 0, 0},
445  { act_slots_string, account_slots_handler, 0, 0 },
446  { act_parent_string, account_parent_handler, 0, 0 },
447  { act_lots_string, account_lots_handler, 0, 0 },
448  { act_hidden_string, account_hidden_handler, 0, 0 },
449  { act_placeholder_string, account_placeholder_handler, 0, 0 },
450 
451  /* These should not appear in newer xml files; only in old
452  * (circa gnucash-1.6) xml files. We maintain them for backward
453  * compatibility. */
454  { act_currency_string, deprecated_account_currency_handler, 0, 0 },
455  { act_currency_scu_string, deprecated_account_currency_scu_handler, 0, 0 },
456  { act_security_string, deprecated_account_security_handler, 0, 0 },
457  { act_security_scu_string, deprecated_account_security_scu_handler, 0, 0 },
458  { NULL, 0, 0, 0 }
459 };
460 
461 static gboolean
462 gnc_account_end_handler (gpointer data_for_children,
463  GSList* data_from_children, GSList* sibling_data,
464  gpointer parent_data, gpointer global_data,
465  gpointer* result, const gchar* tag)
466 {
467  Account* acc, *parent, *root;
468  xmlNodePtr tree = (xmlNodePtr)data_for_children;
469  gxpf_data* gdata = (gxpf_data*)global_data;
470  QofBook* book = static_cast<decltype (book)> (gdata->bookdata);
471  int type;
472 
473 
474  if (parent_data)
475  {
476  return TRUE;
477  }
478 
479  /* OK. For some messed up reason this is getting called again with a
480  NULL tag. So we ignore those cases */
481  if (!tag)
482  {
483  return TRUE;
484  }
485 
486  g_return_val_if_fail (tree, FALSE);
487 
488  acc = dom_tree_to_account (tree, book);
489  if (acc != NULL)
490  {
491  gdata->cb (tag, gdata->parsedata, acc);
492  /*
493  * Now return the account to the "edit" state. At the end of reading
494  * all the transactions, we will Commit. This replaces #splits
495  * rebalances with #accounts rebalances at the end. A BIG win!
496  */
497  xaccAccountBeginEdit (acc);
498 
499  /* Backwards compatibility. If there's no parent, see if this
500  * account is of type ROOT. If not, find or create a ROOT
501  * account and make that the parent. */
502  parent = gnc_account_get_parent (acc);
503  if (parent == NULL)
504  {
505  type = xaccAccountGetType (acc);
506  if (type != ACCT_TYPE_ROOT)
507  {
508  root = gnc_book_get_root_account (book);
509  if (root == NULL)
510  {
511  root = gnc_account_create_root (book);
512  }
513  gnc_account_append_child (root, acc);
514  }
515  }
516  }
517 
518  xmlFreeNode (tree);
519 
520  return acc != NULL;
521 }
522 
523 Account*
524 dom_tree_to_account (xmlNodePtr node, QofBook* book)
525 {
526  struct account_pdata act_pdata;
527  Account* accToRet;
528  gboolean successful;
529 
530  accToRet = xaccMallocAccount (book);
531  xaccAccountBeginEdit (accToRet);
532 
533  act_pdata.account = accToRet;
534  act_pdata.book = book;
535 
536  successful = dom_tree_generic_parse (node, account_handlers_v2,
537  &act_pdata);
538  if (successful)
539  {
540  xaccAccountCommitEdit (accToRet);
541  }
542  else
543  {
544  PERR ("failed to parse account tree");
545  xaccAccountDestroy (accToRet);
546  accToRet = NULL;
547  }
548 
549  return accToRet;
550 }
551 
552 sixtp*
553 gnc_account_sixtp_parser_create (void)
554 {
555  return sixtp_dom_parser_new (gnc_account_end_handler, NULL, NULL);
556 }
557 
558 /* ====================== END OF FILE ===================*/
void xaccAccountSetType(Account *acc, GNCAccountType tip)
Set the account&#39;s type.
Definition: Account.cpp:2422
Account * gnc_account_get_parent(const Account *acc)
This routine returns a pointer to the parent of the specified account.
Definition: Account.cpp:2906
This is the private header for the account structure.
Definition: sixtp.h:129
gboolean gnc_commodity_is_currency(const gnc_commodity *cm)
Checks to see if the specified commodity is an ISO 4217 recognized currency or a legacy currency...
void gnc_account_append_child(Account *new_parent, Account *child)
This function will remove from the child account any pre-existing parent relationship, and will then add the account as a child of the new parent.
Definition: Account.cpp:2807
gboolean gnc_account_is_root(const Account *account)
This routine indicates whether the specified account is the root node of an account tree...
Definition: Account.cpp:2924
gboolean xaccAccountGetNonStdSCU(const Account *acc)
Return boolean, indicating whether this account uses a non-standard SCU.
Definition: Account.cpp:2745
int xaccAccountGetCommoditySCUi(const Account *acc)
Return the &#39;internal&#39; SCU setting.
Definition: Account.cpp:2709
#define PINFO(format, args...)
Print an informational note.
Definition: qoflog.h:256
GNCAccountType xaccAccountGetType(const Account *acc)
Returns the account&#39;s account type.
Definition: Account.cpp:3237
int xaccAccountGetCommoditySCU(const Account *acc)
Return the SCU for the account.
Definition: Account.cpp:2716
const char * xaccAccountGetCode(const Account *acc)
Get the account&#39;s accounting code.
Definition: Account.cpp:3306
STRUCTS.
Account * gnc_account_create_root(QofBook *book)
Create a new root level account.
Definition: Account.cpp:1287
void xaccAccountSetCode(Account *acc, const char *str)
Set the account&#39;s accounting code.
Definition: Account.cpp:2463
const char * xaccAccountTypeEnumAsString(GNCAccountType type)
Conversion routines for the account types to/from strings that are used in persistent storage...
Definition: Account.cpp:4202
void xaccAccountInsertLot(Account *acc, GNCLot *lot)
The xaccAccountInsertLot() method will register the indicated lot with this account.
Definition: Account.cpp:2142
#define PERR(format, args...)
Log a serious error.
Definition: qoflog.h:244
#define ENTER(format, args...)
Print a function entry debugging message.
Definition: qoflog.h:272
void xaccAccountDestroy(Account *acc)
The xaccAccountDestroy() routine can be used to get rid of an account.
Definition: Account.cpp:1592
#define PWARN(format, args...)
Log a warning.
Definition: qoflog.h:250
#define xaccAccountGetGUID(X)
Definition: Account.h:252
Account handling public routines.
void xaccAccountSetPlaceholder(Account *acc, gboolean val)
Set the "placeholder" flag for an account.
Definition: Account.cpp:4080
api for GnuCash version 2 XML-based file format
const char * xaccAccountGetDescription(const Account *acc)
Get the account&#39;s description.
Definition: Account.cpp:3313
LotList * xaccAccountGetLotList(const Account *acc)
The xaccAccountGetLotList() routine returns a list of all lots in this account.
Definition: Account.cpp:3930
gboolean xaccAccountStringToType(const char *str, GNCAccountType *type)
Conversion routines for the account types to/from strings that are used in persistent storage...
Definition: Account.cpp:4239
void xaccAccountSetCommoditySCU(Account *acc, int scu)
Set the SCU for the account.
Definition: Account.cpp:2693
GNCAccountType
The account types are used to determine how the transaction data in the account is displayed...
Definition: Account.h:101
Not a type.
Definition: Account.h:104
void xaccAccountSetHidden(Account *acc, gboolean val)
Set the "hidden" flag for an account.
Definition: Account.cpp:4151
void xaccAccountBeginEdit(Account *acc)
The xaccAccountBeginEdit() subroutine is the first phase of a two-phase-commit wrapper for account up...
Definition: Account.cpp:1477
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account&#39;s commodity.
Definition: Account.cpp:3371
gint qof_instance_guid_compare(gconstpointer ptr1, gconstpointer ptr2)
Compare the GncGUID values of two instances.
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition: qoflog.h:282
Account * xaccMallocAccount(QofBook *book)
Constructor.
Definition: Account.cpp:1273
void xaccAccountSetDescription(Account *acc, const char *str)
Set the account&#39;s description.
Definition: Account.cpp:2482
void DxaccAccountSetCurrency(Account *acc, gnc_commodity *currency)
Definition: Account.cpp:2756
void xaccAccountSetNonStdSCU(Account *acc, gboolean flag)
Set the flag indicating that this account uses a non-standard SCU.
Definition: Account.cpp:2729
const char * xaccAccountGetName(const Account *acc)
Get the account&#39;s name.
Definition: Account.cpp:3259
The type used to store guids in C.
Definition: guid.h:75
void xaccAccountCommitEdit(Account *acc)
ThexaccAccountCommitEdit() subroutine is the second phase of a two-phase-commit wrapper for account u...
Definition: Account.cpp:1518
void xaccAccountSetName(Account *acc, const char *str)
Set the account&#39;s name.
Definition: Account.cpp:2443
The hidden root account of an account tree.
Definition: Account.h:153
void xaccAccountSetCommodity(Account *acc, gnc_commodity *com)
Set the account&#39;s commodity.
Definition: Account.cpp:2649
Account * xaccAccountLookup(const GncGUID *guid, QofBook *book)
The xaccAccountLookup() subroutine will return the account associated with the given id...
Definition: Account.cpp:2052