From f2c2caa5b08d8b384d42705c2bab6f5669b7213b Mon Sep 17 00:00:00 2001 From: Derek Atkins Date: Sun, 12 Feb 2006 20:03:46 +0000 Subject: [PATCH] Mike Alexander's Currency Scrub patch. * src/engine/Scrub.c: * src/engine/Scrub.h: Try to fix transactions that have no currency, perhaps because of a log replay. Workaround for bug #143720. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@13241 57a11ea4-9604-0410-9ed3-97b8803252fd --- ChangeLog | 8 +++++- src/engine/Scrub.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++ src/engine/Scrub.h | 9 +++++++ 3 files changed, 79 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5bd4cb9e67..5783c29337 100644 --- a/ChangeLog +++ b/ChangeLog @@ -35,7 +35,13 @@ * src/report/stylesheets/stylesheet-fancy.scm: Des Dougan's patch to let the user choose the fancy-stylesheet image alignment. Fixes #314048. - + + Mike Alexander's Currency Scrub patch. + * src/engine/Scrub.c: + * src/engine/Scrub.h: + Try to fix transactions that have no currency, perhaps because + of a log replay. Workaround for bug #143720. + 2006-02-11 Derek Atkins * src/report/report-gnome/gnc-plugin-page-report.c: diff --git a/src/engine/Scrub.c b/src/engine/Scrub.c index 965af35d82..e745510a36 100644 --- a/src/engine/Scrub.c +++ b/src/engine/Scrub.c @@ -352,10 +352,73 @@ xaccAccountScrubImbalance (Account *acc) Split *split = node->data; Transaction *trans = xaccSplitGetParent(split); + xaccTransScrubCurrencyFromSplits(trans); + xaccTransScrubImbalance (trans, xaccAccountGetRoot (acc), NULL); } } +void +xaccTransScrubCurrencyFromSplits(Transaction *trans) +{ + GList *node; + gnc_commodity *common_currency = NULL; + + if (!trans) return; + + for (node = xaccTransGetSplitList (trans); node; node = node->next) { + Split *split = node->data; + if (gnc_numeric_equal(xaccSplitGetAmount (split), + xaccSplitGetValue (split))) { + + Account *s_account = xaccSplitGetAccount (split); + gnc_commodity *s_commodity = xaccAccountGetCommodity (s_account); + + if (s_commodity) { + const char * namespace = gnc_commodity_get_namespace (s_commodity); + if (!safe_strcmp (namespace, GNC_COMMODITY_NS_ISO) || + !safe_strcmp (namespace, GNC_COMMODITY_NS_LEGACY)) { + + /* Found a split where the amount is the same as the value and + the commodity is a currency. If all splits in the transaction + that fit this description are in the same currency then the + transaction should be in that currency too. */ + + if (common_currency == NULL) + /* First one we've found, save the currency */ + common_currency = s_commodity; + else if ( !gnc_commodity_equiv (common_currency, s_commodity)) { + /* Splits are inconsistent, more than one has a value equal to + the amount, but they aren't all in the same currency. */ + common_currency = NULL; + break; + } + } + } + } + } + + if (common_currency && + !gnc_commodity_equiv (common_currency, xaccTransGetCurrency (trans))) { + + /* Found a common currency for the splits, and the transaction is not + in that currency */ + gboolean trans_was_open; + + PINFO ("transaction in wrong currency"); + + trans_was_open = xaccTransIsOpen (trans); + + if (!trans_was_open) + xaccTransBeginEdit (trans); + + xaccTransSetCurrency (trans, common_currency); + + if (!trans_was_open) + xaccTransCommitEdit (trans); + } +} + void xaccTransScrubImbalance (Transaction *trans, AccountGroup *root, Account *parent) diff --git a/src/engine/Scrub.h b/src/engine/Scrub.h index b53cf46ba2..e1ce2138d8 100644 --- a/src/engine/Scrub.h +++ b/src/engine/Scrub.h @@ -124,6 +124,15 @@ void xaccGroupScrubImbalance (AccountGroup *grp); * fields of the parent accounts of the transaction's splits. */ void xaccTransScrubCurrency (Transaction *trans); +/** The xaccTransScrubCurrencyFromSplits method fixes transactions + * where the currency doesn't match the currency used in the splits + * in the transaction. If all splits where the amount equals the + * value and where the commodity is a currency have the same + * currency, it sets the transaction's currency to that if it is + * anything else. If the splits don't match that description the + * transaction currency is not changed. */ +void xaccTransScrubCurrencyFromSplits(Transaction *trans); + /** The xaccAccountScrubCommodity method fixed accounts without * a commodity by using the old account currency and security. */ void xaccAccountScrubCommodity (Account *account);