mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Remove trading splits instead of trying to adjust them.
This commit is contained in:
@@ -530,50 +530,6 @@ get_trading_split (Transaction *trans, Account *base,
|
||||
return balance_split;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
static void
|
||||
add_balance_split (Transaction *trans, gnc_numeric imbalance,
|
||||
Account *root, Account *account)
|
||||
@@ -631,71 +587,6 @@ gnc_transaction_balance_no_trading (Transaction *trans, Account *root,
|
||||
}
|
||||
|
||||
}
|
||||
/** If there are existing trading splits, adjust the price or exchange
|
||||
rate in each of them to agree with the non-trading splits for the
|
||||
same commodity. If there are multiple non-trading splits for the
|
||||
same commodity in the transaction this will use the exchange rate in
|
||||
the last such split. This shouldn't happen, and if it does then there's
|
||||
not much we can do about it anyway.
|
||||
|
||||
While we're at it, compute the value imbalance ignoring existing
|
||||
trading splits. */
|
||||
|
||||
static gnc_numeric
|
||||
gnc_transaction_adjust_trading_splits (Transaction* trans, Account *root)
|
||||
{
|
||||
GList* splits;
|
||||
gnc_numeric imbalance = gnc_numeric_zero();
|
||||
for (splits = trans->splits; splits; splits = splits->next)
|
||||
{
|
||||
Split *split = splits->data;
|
||||
Split *balance_split = NULL;
|
||||
gnc_numeric value, amount;
|
||||
gnc_commodity *commodity, *txn_curr = xaccTransGetCurrency (trans);
|
||||
|
||||
if (! xaccTransStillHasSplit (trans, split)) continue;
|
||||
|
||||
commodity = xaccAccountGetCommodity (xaccSplitGetAccount(split));
|
||||
if (!commodity)
|
||||
{
|
||||
PERR("Split has no commodity");
|
||||
continue;
|
||||
}
|
||||
|
||||
balance_split = find_trading_split (trans, root, commodity);
|
||||
|
||||
if (balance_split != split)
|
||||
/* this is not a trading split */
|
||||
imbalance = gnc_numeric_add(imbalance, xaccSplitGetValue (split),
|
||||
GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT);
|
||||
|
||||
/* Ignore splits where value or amount is zero */
|
||||
value = xaccSplitGetValue (split);
|
||||
amount = xaccSplitGetAmount (split);
|
||||
if (gnc_numeric_zero_p(amount) || gnc_numeric_zero_p(value))
|
||||
continue;
|
||||
|
||||
if (balance_split && balance_split != split)
|
||||
{
|
||||
gnc_numeric convrate = gnc_numeric_div (amount, value,
|
||||
GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE);
|
||||
gnc_numeric old_value, new_value;
|
||||
old_value = xaccSplitGetValue(balance_split);
|
||||
new_value = gnc_numeric_div (xaccSplitGetAmount(balance_split),
|
||||
convrate,
|
||||
gnc_commodity_get_fraction(txn_curr),
|
||||
GNC_HOW_RND_ROUND_HALF_UP);
|
||||
if (! gnc_numeric_equal (old_value, new_value))
|
||||
{
|
||||
xaccTransBeginEdit (trans);
|
||||
xaccSplitSetValue (balance_split, new_value);
|
||||
xaccSplitScrub (balance_split);
|
||||
xaccTransCommitEdit (trans);
|
||||
}
|
||||
}
|
||||
}
|
||||
return imbalance;
|
||||
}
|
||||
|
||||
static gnc_numeric
|
||||
gnc_transaction_get_commodity_imbalance (Transaction *trans,
|
||||
@@ -719,6 +610,42 @@ gnc_transaction_get_commodity_imbalance (Transaction *trans,
|
||||
return val_imbalance;
|
||||
}
|
||||
|
||||
/* GFunc wrapper for xaccSplitDestroy */
|
||||
static void
|
||||
destroy_split (void* ptr, void* data)
|
||||
{
|
||||
Split *split = GNC_SPLIT (ptr);
|
||||
if (split)
|
||||
xaccSplitDestroy (split);
|
||||
}
|
||||
|
||||
/* Balancing transactions with trading accounts works best when
|
||||
* starting with no trading splits.
|
||||
*/
|
||||
static void
|
||||
xaccTransClearTradingSplits (Transaction *trans)
|
||||
{
|
||||
GList *trading_splits = NULL;
|
||||
|
||||
for (GList* node = trans->splits; node; node = node->next)
|
||||
{
|
||||
Split* split = GNC_SPLIT(node->data);
|
||||
Account* acc = NULL;
|
||||
if (!split)
|
||||
continue;
|
||||
acc = xaccSplitGetAccount(split);
|
||||
if (acc && xaccAccountGetType(acc) == ACCT_TYPE_TRADING)
|
||||
trading_splits = g_list_prepend (trading_splits, node->data);
|
||||
}
|
||||
|
||||
if (!trading_splits)
|
||||
return;
|
||||
|
||||
xaccTransBeginEdit (trans);
|
||||
g_list_foreach (trading_splits, destroy_split, NULL);
|
||||
xaccTransCommitEdit (trans);
|
||||
}
|
||||
|
||||
static void
|
||||
gnc_transaction_balance_trading (Transaction *trans, Account *root)
|
||||
{
|
||||
@@ -859,8 +786,11 @@ xaccTransScrubImbalance (Transaction *trans, Account *root,
|
||||
|
||||
ENTER ("()");
|
||||
|
||||
/* Must look for orphan splits even if there is no imbalance. */
|
||||
/* Must look for orphan splits and remove trading splits even if
|
||||
* there is no imbalance and we're not using trading accounts.
|
||||
*/
|
||||
xaccTransScrubSplits (trans);
|
||||
xaccTransClearTradingSplits (trans);
|
||||
|
||||
/* Return immediately if things are balanced. */
|
||||
if (xaccTransIsBalanced (trans))
|
||||
@@ -876,9 +806,7 @@ xaccTransScrubImbalance (Transaction *trans, Account *root,
|
||||
return;
|
||||
}
|
||||
|
||||
imbalance = gnc_transaction_adjust_trading_splits (trans, root);
|
||||
|
||||
/* Balance the value, ignoring existing trading splits */
|
||||
imbalance = xaccTransGetImbalanceValue (trans);
|
||||
if (! gnc_numeric_zero_p (imbalance))
|
||||
{
|
||||
PINFO ("Value unbalanced transaction");
|
||||
|
||||
Reference in New Issue
Block a user