static void add_groups_for_each (Account *toadd, gpointer data) { struct add_group_data_struct *dadata = data; Account *foundact; foundact = gnc_account_lookup_by_name(dadata->to, xaccAccountGetName(toadd)); if (!foundact) { foundact = clone_account (toadd, dadata->com); if (dadata->to) gnc_account_append_child (dadata->to, foundact); else if (dadata->parent) gnc_account_append_child (dadata->parent, foundact); else { g_warning ("add_groups_for_each: no valid parent"); } } { if (gnc_account_n_children(toadd) > 0) { struct add_group_data_struct downdata; downdata.to = foundact; downdata.parent = foundact; downdata.com = dadata->com; gnc_account_foreach_child (toadd, add_groups_for_each, &downdata); } } }
void account_trees_merge(Account *existing_root, Account *new_accts_root) { GList *accounts, *node; g_return_if_fail(new_accts_root != NULL); g_return_if_fail(existing_root != NULL); /* since we're have a chance of mutating the list (via * gnc_account_add_child) while we're iterating over it, iterate * over a copy. */ accounts = gnc_account_get_children(new_accts_root); for (node = accounts; node; node = g_list_next(node)) { Account *existing_named, *new_acct; const char *name; new_acct = (Account*)node->data; name = xaccAccountGetName(new_acct); existing_named = gnc_account_lookup_by_name(existing_root, name); switch (determine_account_merge_disposition(existing_named, new_acct)) { case GNC_ACCOUNT_MERGE_DISPOSITION_USE_EXISTING: /* recurse */ account_trees_merge(existing_named, new_acct); break; case GNC_ACCOUNT_MERGE_DISPOSITION_CREATE_NEW: /* merge this one in. */ gnc_account_append_child(existing_root, new_acct); break; } } g_list_free(accounts); }
Account* gnc_sx_get_template_transaction_account(SchedXaction *sx) { Account *template_root, *sx_template_acct; char sx_guid_str[GUID_ENCODING_LENGTH+1]; template_root = gnc_book_get_template_root(gnc_get_current_book()); guid_to_string_buff(xaccSchedXactionGetGUID(sx), sx_guid_str); sx_template_acct = gnc_account_lookup_by_name(template_root, sx_guid_str); return sx_template_acct; }
/* Find the trading split for a commodity, but don't create any splits or accounts if they don't already exist. */ static Split * find_trading_split (Transaction *trans, Account *root, gnc_commodity *commodity) { Account *trading_account; Account *ns_account; Account *account; if (!root) { root = gnc_book_get_root_account (xaccTransGetBook (trans)); if (NULL == root) { /* This can't occur, things should be in books */ PERR ("Bad data corruption, no root account in book"); return NULL; } } trading_account = gnc_account_lookup_by_name (root, _("Trading")); if (!trading_account) { return NULL; } ns_account = gnc_account_lookup_by_name (trading_account, gnc_commodity_get_namespace(commodity)); if (!ns_account) { return NULL; } account = gnc_account_lookup_by_name (ns_account, gnc_commodity_get_mnemonic(commodity)); if (!account) { return NULL; } return xaccTransFindSplitByAccount(trans, account); }
/** * @param id: The string version of the GncGUID of the context of template * transaction being edited in this template GL. As used by scheduled * transactions, this is the GncGUID of the SX itself which is magically the * *name* of the (template) account which contains the transactions for this * scheduled transaction. That's right. The stringified GncGUID of the SX is * the name of the SX'es template account. **/ GNCLedgerDisplay2 * gnc_ledger_display2_template_gl (char *id) { QofBook *book; Query *q; GNCLedgerDisplay2 *ld; GncTreeModelSplitReg *model; Account *root, *acct; gboolean isTemplateModeTrue; ENTER("id=%s", id ? id : "(null)"); acct = NULL; isTemplateModeTrue = TRUE; q = qof_query_create_for(GNC_ID_SPLIT); book = gnc_get_current_book (); qof_query_set_book (q, book); if ( id != NULL ) { root = gnc_book_get_template_root (book); acct = gnc_account_lookup_by_name(root, id); g_assert( acct ); xaccQueryAddSingleAccountMatch (q, acct, QOF_QUERY_AND); } ld = gnc_ledger_display2_internal (NULL, q, LD2_GL, SEARCH_LEDGER2, REG2_STYLE_JOURNAL, FALSE, isTemplateModeTrue); model = gnc_ledger_display2_get_split_model_register (ld); if ( acct ) { gnc_tree_model_split_reg_set_template_account (model, acct); } LEAVE("%p", ld); return ld; }
Account * xaccScrubUtilityGetOrMakeAccount (Account *root, gnc_commodity * currency, const char *accname, GNCAccountType acctype, gboolean placeholder) { Account * acc; g_return_val_if_fail (root, NULL); /* build the account name */ if (!currency) { PERR ("No currency specified!"); return NULL; } /* See if we've got one of these going already ... */ acc = gnc_account_lookup_by_name(root, accname); if (acc == NULL) { /* Guess not. We'll have to build one. */ acc = xaccMallocAccount(gnc_account_get_book (root)); xaccAccountBeginEdit (acc); xaccAccountSetName (acc, accname); xaccAccountSetCommodity (acc, currency); xaccAccountSetType (acc, acctype); xaccAccountSetPlaceholder (acc, placeholder); /* Hang the account off the root. */ gnc_account_append_child (root, acc); xaccAccountCommitEdit (acc); } return acc; }
/* Get the trading split for a given commodity, creating it (and the necessary accounts) if it doesn't exist. */ static Split * get_trading_split (Transaction *trans, Account *root, gnc_commodity *commodity) { Split *balance_split; Account *trading_account; Account *ns_account; Account *account; gnc_commodity *default_currency = NULL; if (!root) { root = gnc_book_get_root_account (xaccTransGetBook (trans)); if (NULL == root) { /* This can't occur, things should be in books */ PERR ("Bad data corruption, no root account in book"); return NULL; } } /* Get the default currency. This is harder than it seems. It's not possible to call gnc_default_currency() since it's a UI function. One might think that the currency of the root account would do, but the root account has no currency. Instead look for the Income placeholder account and use its currency. */ default_currency = xaccAccountGetCommodity(gnc_account_lookup_by_name(root, _("Income"))); if (! default_currency) { default_currency = commodity; } trading_account = xaccScrubUtilityGetOrMakeAccount (root, default_currency, _("Trading"), ACCT_TYPE_TRADING, TRUE); if (!trading_account) { PERR ("Can't get trading account"); return NULL; } ns_account = xaccScrubUtilityGetOrMakeAccount (trading_account, default_currency, gnc_commodity_get_namespace(commodity), ACCT_TYPE_TRADING, TRUE); if (!ns_account) { PERR ("Can't get namespace account"); return NULL; } account = xaccScrubUtilityGetOrMakeAccount (ns_account, commodity, gnc_commodity_get_mnemonic(commodity), ACCT_TYPE_TRADING, FALSE); if (!account) { PERR ("Can't get commodity account"); return NULL; } balance_split = xaccTransFindSplitByAccount(trans, account); /* Put split into account before setting split value */ if (!balance_split) { balance_split = xaccMallocSplit (qof_instance_get_book(trans)); xaccTransBeginEdit (trans); xaccSplitSetParent(balance_split, trans); xaccSplitSetAccount(balance_split, account); xaccTransCommitEdit (trans); } return balance_split; }
static gboolean gnc_schedXaction_end_handler(gpointer data_for_children, GSList* data_from_children, GSList* sibling_data, gpointer parent_data, gpointer global_data, gpointer *result, const gchar *tag) { SchedXaction *sx; gboolean successful = FALSE; xmlNodePtr tree = (xmlNodePtr)data_for_children; gxpf_data *gdata = (gxpf_data*)global_data; struct sx_pdata sx_pdata; if ( parent_data ) { return TRUE; } if ( !tag ) { return TRUE; } g_return_val_if_fail( tree, FALSE ); sx = xaccSchedXactionMalloc( gdata->bookdata ); memset(&sx_pdata, 0, sizeof(sx_pdata)); sx_pdata.sx = sx; sx_pdata.book = gdata->bookdata; g_assert( sx_dom_handlers != NULL ); successful = dom_tree_generic_parse( tree, sx_dom_handlers, &sx_pdata ); if (!successful) { g_critical("failed to parse scheduled xaction"); xmlElemDump( stdout, NULL, tree ); gnc_sx_begin_edit( sx ); xaccSchedXactionDestroy( sx ); goto done; } if (tree->properties) { gchar *sx_name = xaccSchedXactionGetName(sx); xmlAttr *attr; for (attr = tree->properties; attr != NULL; attr = attr->next) { xmlChar *attr_value = attr->children->content; g_debug("sx attribute name[%s] value[%s]", attr->name, attr_value); if (strcmp((const char *)attr->name, "version") != 0) { g_warning("unknown sx attribute [%s]", attr->name); continue; } // if version == 1.0.0: ensure freqspec, no recurrence // if version == 2.0.0: ensure recurrence, no freqspec. if (strcmp((const char *)attr_value, schedxaction_version_string) == 0) { if (!sx_pdata.saw_freqspec) g_critical("did not see freqspec in version 1 sx [%s]", sx_name); if (sx_pdata.saw_recurrence) g_warning("saw recurrence in supposedly version 1 sx [%s]", sx_name); } if (strcmp((const char *)attr_value, schedxaction_version2_string) == 0) { if (sx_pdata.saw_freqspec) g_warning("saw freqspec in version 2 sx [%s]", sx_name); if (!sx_pdata.saw_recurrence) g_critical("did not find recurrence in version 2 sx [%s]", sx_name); } } } // generic_callback -> book_callback: insert the SX in the book gdata->cb( tag, gdata->parsedata, sx ); /* FIXME: this should be removed somewhere near 1.8 release time. */ if ( sx->template_acct == NULL ) { Account *ra = NULL; const char *id = NULL; Account *acct = NULL; sixtp_gdv2 *sixdata = gdata->parsedata; QofBook *book; book = sixdata->book; /* We're dealing with a pre-200107<near-end-of-month> rgmerk change re: storing template accounts. */ /* Fix: get account with name of our GncGUID from the template accounts. Make that our template_acct pointer. */ /* THREAD-UNSAFE */ id = guid_to_string( xaccSchedXactionGetGUID( sx ) ); ra = gnc_book_get_template_root(book); if ( ra == NULL ) { g_warning( "Error getting template root account from being-parsed Book." ); xmlFreeNode( tree ); return FALSE; } acct = gnc_account_lookup_by_name( ra, id ); if ( acct == NULL ) { g_warning("no template account with name [%s]", id); xmlFreeNode( tree ); return FALSE; } g_debug("template account name [%s] for SX with GncGUID [%s]", xaccAccountGetName( acct ), id ); /* FIXME: free existing template account. * HUH????? We only execute this if there isn't * currently an existing template account, don't we? * <rgmerk> */ sx->template_acct = acct; } done: xmlFreeNode( tree ); return successful; }