Bug 798093 - Changing the symbol/abbreviation of a security after...

the trading account was created breaks GnuCash.

Introduces a new function, gnc_account_lookup_by_type_and_commodity
that does that, though it also looks at name for the one special case
of finding/creating the Namespace placeholder account. Adds a parameter
checkname to xaccScrubUtilityGetOrMakeAccount to flag whether to look
for the name.

Namespaces aside this makes it possible for the user to rename trading
accounts or securities independent of each other.
This commit is contained in:
John Ralls 2021-01-26 16:16:25 -08:00
parent bcbebe62b1
commit 0f8d9f6d7c
3 changed files with 56 additions and 8 deletions

View File

@ -3120,6 +3120,28 @@ gnc_account_lookup_by_full_name (const Account *any_acc,
return found;
}
Account*
gnc_account_lookup_by_type_and_commodity (Account* root,
const char* name,
GNCAccountType acctype,
gnc_commodity* commodity)
{
auto rpriv{GET_PRIVATE(root)};
for (auto node = rpriv->children; node; node = node->next)
{
auto account{static_cast<Account*>(node->data)};
if (xaccAccountGetType (account) == acctype &&
gnc_commodity_equiv(xaccAccountGetCommodity (account), commodity))
{
if (name && strcmp(name, xaccAccountGetName(account)))
continue; //name doesn't match so skip this one
return account;
}
}
return nullptr;
}
void
gnc_account_foreach_child (const Account *acc,
AccountCb thunk,

View File

@ -938,6 +938,24 @@ Account *gnc_account_lookup_by_code (const Account *parent,
*/
Account *gnc_account_lookup_by_opening_balance (Account *account, gnc_commodity *commodity);
/** Find a direct child account matching name, GNCAccountType, and commodity.
*
* Note that commodity matching is by equivalence: If the
* mnemonic/symbol and namespace are the same, it matches.
*
* @param root The account among whose children one expects to find
* the account.
* @param name The name of the account to look for. If nullptr the
* returned account will match only on acctype and commodity.
* @param acctype The GNCAccountType to match.
* @param commodity The commodity in which the account should be denominated.
* @return The book's trading account for the given commodity if
* trading accounts are enabled and one exists; NULL otherwise.
*/
Account *gnc_account_lookup_by_type_and_commodity (Account* root,
const char* name,
GNCAccountType acctype,
gnc_commodity* commodity);
/** @} */
/* ------------------ */

View File

@ -64,7 +64,8 @@ static Account* xaccScrubUtilityGetOrMakeAccount (Account *root,
gnc_commodity* currency,
const char* accname,
GNCAccountType acctype,
gboolean placeholder);
gboolean placeholder,
gboolean checkname);
void
gnc_set_abort_scrub (gboolean abort)
@ -124,7 +125,8 @@ TransScrubOrphansFast (Transaction *trans, Account *root)
gnc_commodity_get_mnemonic (trans->common_currency),
NULL);
orph = xaccScrubUtilityGetOrMakeAccount (root, trans->common_currency,
accname, ACCT_TYPE_BANK, FALSE);
accname, ACCT_TYPE_BANK,
FALSE, TRUE);
g_free (accname);
if (!orph) continue;
@ -413,7 +415,8 @@ get_balance_split (Transaction *trans, Account *root, Account *account,
accname = g_strconcat (_("Imbalance"), "-",
gnc_commodity_get_mnemonic (commodity), NULL);
account = xaccScrubUtilityGetOrMakeAccount (root, commodity,
accname, ACCT_TYPE_BANK, FALSE);
accname, ACCT_TYPE_BANK,
FALSE, TRUE);
g_free (accname);
if (!account)
{
@ -476,7 +479,8 @@ get_trading_split (Transaction *trans, Account *root,
trading_account = xaccScrubUtilityGetOrMakeAccount (root,
default_currency,
_("Trading"),
ACCT_TYPE_TRADING, TRUE);
ACCT_TYPE_TRADING,
TRUE, FALSE);
if (!trading_account)
{
PERR ("Can't get trading account");
@ -486,7 +490,8 @@ get_trading_split (Transaction *trans, Account *root,
ns_account = xaccScrubUtilityGetOrMakeAccount (trading_account,
default_currency,
gnc_commodity_get_namespace(commodity),
ACCT_TYPE_TRADING, TRUE);
ACCT_TYPE_TRADING,
TRUE, TRUE);
if (!ns_account)
{
PERR ("Can't get namespace account");
@ -495,7 +500,8 @@ get_trading_split (Transaction *trans, Account *root,
account = xaccScrubUtilityGetOrMakeAccount (ns_account, commodity,
gnc_commodity_get_mnemonic(commodity),
ACCT_TYPE_TRADING, FALSE);
ACCT_TYPE_TRADING,
FALSE, FALSE);
if (!account)
{
PERR ("Can't get commodity account");
@ -1447,7 +1453,7 @@ xaccAccountScrubColorNotSet (QofBook *book)
Account *
xaccScrubUtilityGetOrMakeAccount (Account *root, gnc_commodity * currency,
const char *accname, GNCAccountType acctype,
gboolean placeholder)
gboolean placeholder, gboolean checkname)
{
Account * acc;
@ -1461,7 +1467,9 @@ xaccScrubUtilityGetOrMakeAccount (Account *root, gnc_commodity * currency,
}
/* See if we've got one of these going already ... */
acc = gnc_account_lookup_by_name(root, accname);
acc = gnc_account_lookup_by_type_and_commodity (root,
checkname ? accname : NULL,
acctype, currency);
if (acc == NULL)
{