From 01cdcca694a0c0570e63a2530230207d00cba541 Mon Sep 17 00:00:00 2001 From: jean Date: Thu, 2 Apr 2020 10:06:25 -0700 Subject: [PATCH] Bug 797006 - Balance is misleading in open subaccounts when different currencies are involved --- gnucash/gnome/gnc-plugin-page-register.c | 22 +++++++++++++++- .../register/ledger-core/gnc-ledger-display.c | 24 ++++++++++------- .../register/ledger-core/gnc-ledger-display.h | 2 +- .../ledger-core/split-register-layout.c | 26 +++++++++++++++---- .../ledger-core/split-register-model.c | 23 +++++++--------- gnucash/register/ledger-core/split-register.c | 10 ++++--- gnucash/register/ledger-core/split-register.h | 5 +++- 7 files changed, 78 insertions(+), 34 deletions(-) diff --git a/gnucash/gnome/gnc-plugin-page-register.c b/gnucash/gnome/gnc-plugin-page-register.c index a2376fe2b4..238f881789 100644 --- a/gnucash/gnome/gnc-plugin-page-register.c +++ b/gnucash/gnome/gnc-plugin-page-register.c @@ -675,12 +675,23 @@ gnc_plugin_page_register_new_common (GNCLedgerDisplay *ledger) return plugin_page; } +static gpointer +gnc_plug_page_register_check_commodity(Account *account, void* usr_data) +{ + // Check that account's commodity matches the commodity in usr_data + gnc_commodity* com0 = (gnc_commodity*) usr_data; + gnc_commodity* com1 = xaccAccountGetCommodity(account); + return gnc_commodity_equal(com1, com0) ? NULL : com1; +} + GncPluginPage * gnc_plugin_page_register_new (Account *account, gboolean subaccounts) { GNCLedgerDisplay *ledger; GncPluginPage *page; GncPluginPageRegisterPrivate *priv; + gnc_commodity* com0; + gnc_commodity* com1; /*################## Added for Reg2 #################*/ const GList *item; @@ -708,9 +719,18 @@ gnc_plugin_page_register_new (Account *account, gboolean subaccounts) } } /*################## Added for Reg2 #################*/ + com0 = gnc_account_get_currency_or_parent(account); + com1 = gnc_account_foreach_descendant_until(account,gnc_plug_page_register_check_commodity,com0); + if(0 && com1 != NULL) + { + const gchar* com0_str = gnc_commodity_get_fullname(com0); + const gchar* com1_str = gnc_commodity_get_fullname(com1); + gnc_info_dialog(NULL,_("Cannot open sub-accounts because sub-accounts and parent account have different commodities or currencies\nFound:\n%s\n%s\n(There may be more mismatches)"),com0_str,com1_str); + return NULL; + } if (subaccounts) - ledger = gnc_ledger_display_subaccounts (account); + ledger = gnc_ledger_display_subaccounts (account,com1 != NULL); else ledger = gnc_ledger_display_simple (account); diff --git a/gnucash/register/ledger-core/gnc-ledger-display.c b/gnucash/register/ledger-core/gnc-ledger-display.c index 456048f1b4..9d0008f4b1 100644 --- a/gnucash/register/ledger-core/gnc-ledger-display.c +++ b/gnucash/register/ledger-core/gnc-ledger-display.c @@ -88,7 +88,8 @@ gnc_ledger_display_internal (Account *lead_account, Query *q, SplitRegisterType reg_type, SplitRegisterStyle style, gboolean use_double_line, - gboolean is_template); + gboolean is_template, + gboolean mismatched_commodities); static void gnc_ledger_display_refresh_internal (GNCLedgerDisplay *ld, GList *splits); @@ -370,7 +371,7 @@ gnc_ledger_display_simple (Account *account) ld = gnc_ledger_display_internal (account, NULL, LD_SINGLE, reg_type, gnc_get_default_register_style(acc_type), - use_double_line, FALSE); + use_double_line, FALSE, FALSE); LEAVE("%p", ld); return ld; } @@ -378,7 +379,7 @@ gnc_ledger_display_simple (Account *account) /* Opens up a register window to display an account, and all of its * children, in the same window */ GNCLedgerDisplay * -gnc_ledger_display_subaccounts (Account *account) +gnc_ledger_display_subaccounts (Account *account,gboolean mismatched_commodities) { SplitRegisterType reg_type; GNCLedgerDisplay *ld; @@ -389,7 +390,7 @@ gnc_ledger_display_subaccounts (Account *account) ld = gnc_ledger_display_internal (account, NULL, LD_SUBACCOUNT, reg_type, REG_STYLE_JOURNAL, FALSE, - FALSE); + FALSE,mismatched_commodities); LEAVE("%p", ld); return ld; } @@ -439,7 +440,7 @@ gnc_ledger_display_gl (void) QOF_QUERY_AND); ld = gnc_ledger_display_internal (NULL, query, LD_GL, GENERAL_JOURNAL, - REG_STYLE_JOURNAL, FALSE, FALSE); + REG_STYLE_JOURNAL, FALSE, FALSE, FALSE); LEAVE("%p", ld); return ld; } @@ -484,7 +485,8 @@ gnc_ledger_display_template_gl (char *id) SEARCH_LEDGER, REG_STYLE_JOURNAL, FALSE, - isTemplateModeTrue); + isTemplateModeTrue, + FALSE); sr = gnc_ledger_display_get_split_register (ld); if ( acct ) @@ -526,7 +528,7 @@ gnc_ledger_display_set_watches (GNCLedgerDisplay *ld, GList *splits) GNC_ID_ACCOUNT, QOF_EVENT_MODIFY | QOF_EVENT_DESTROY | GNC_EVENT_ITEM_CHANGED); - + for (node = splits; node; node = node->next) { Split *split = node->data; @@ -697,7 +699,7 @@ gnc_ledger_display_query (Query *query, SplitRegisterType type, ENTER("query=%p", query); ld = gnc_ledger_display_internal (NULL, query, LD_GL, type, style, - FALSE, FALSE); + FALSE, FALSE, FALSE); LEAVE("%p", ld); return ld; } @@ -708,7 +710,8 @@ gnc_ledger_display_internal (Account *lead_account, Query *q, SplitRegisterType reg_type, SplitRegisterStyle style, gboolean use_double_line, - gboolean is_template ) + gboolean is_template, + gboolean mismatched_commodities) { GNCLedgerDisplay *ld; gint limit; @@ -808,8 +811,9 @@ gnc_ledger_display_internal (Account *lead_account, Query *q, \******************************************************************/ ld->use_double_line_default = use_double_line; + ld->reg = gnc_split_register_new (reg_type, style, use_double_line, - is_template); + is_template,mismatched_commodities); gnc_split_register_set_data (ld->reg, ld, gnc_ledger_display_parent); diff --git a/gnucash/register/ledger-core/gnc-ledger-display.h b/gnucash/register/ledger-core/gnc-ledger-display.h index 743df081de..f8d3f78b88 100644 --- a/gnucash/register/ledger-core/gnc-ledger-display.h +++ b/gnucash/register/ledger-core/gnc-ledger-display.h @@ -85,7 +85,7 @@ GNCLedgerDisplay * gnc_ledger_display_simple (Account *account); /** opens up a register window to display the parent account and all of * its children. */ -GNCLedgerDisplay * gnc_ledger_display_subaccounts (Account *account); +GNCLedgerDisplay * gnc_ledger_display_subaccounts (Account *account, gboolean mismatched_commodities); /** opens up a general ledger window */ GNCLedgerDisplay * gnc_ledger_display_gl (void); diff --git a/gnucash/register/ledger-core/split-register-layout.c b/gnucash/register/ledger-core/split-register-layout.c index d960cc7f81..eb4ce227d3 100644 --- a/gnucash/register/ledger-core/split-register-layout.c +++ b/gnucash/register/ledger-core/split-register-layout.c @@ -291,8 +291,16 @@ gnc_split_register_set_cells (SplitRegister *reg, TableLayout *layout) { gnc_table_layout_set_cell (layout, curs, DEBT_CELL, 0, 5); gnc_table_layout_set_cell (layout, curs, CRED_CELL, 0, 6); - gnc_table_layout_set_cell (layout, curs, RBALN_CELL, 0, 7); - gnc_table_layout_set_cell (layout, curs, RATE_CELL, 0, 8); + if(!reg->mismatched_commodities) + { + gnc_table_layout_set_cell (layout, curs, RBALN_CELL, 0, 7); + gnc_table_layout_set_cell (layout, curs, RATE_CELL, 0, 8); + } + else + { + // Don't display the balance if there are mismatched commodities + gnc_table_layout_set_cell (layout, curs, RATE_CELL, 0, 7); + } } curs_last = curs; @@ -328,8 +336,16 @@ gnc_split_register_set_cells (SplitRegister *reg, TableLayout *layout) gnc_table_layout_set_cell (layout, curs, RATE_CELL, 0, 7); else { - gnc_table_layout_set_cell (layout, curs, RBALN_CELL, 0, 7); - gnc_table_layout_set_cell (layout, curs, RATE_CELL, 0, 8); + if(!reg->mismatched_commodities) + { + gnc_table_layout_set_cell (layout, curs, RBALN_CELL, 0, 7); + gnc_table_layout_set_cell (layout, curs, RATE_CELL, 0, 8); + } + else + { + // Don't display the balance if there are mismatched commodities + gnc_table_layout_set_cell (layout, curs, RATE_CELL, 0, 7); + } } curs_last = curs; @@ -577,7 +593,7 @@ gnc_split_register_layout_add_cursors (SplitRegister *reg, case INCOME_LEDGER: case GENERAL_JOURNAL: case SEARCH_LEDGER: - if (reg->is_template) + if (reg->is_template || reg->mismatched_commodities) num_cols = 8; else num_cols = 9; diff --git a/gnucash/register/ledger-core/split-register-model.c b/gnucash/register/ledger-core/split-register-model.c index a8e9640dfe..8ddb8c3a73 100644 --- a/gnucash/register/ledger-core/split-register-model.c +++ b/gnucash/register/ledger-core/split-register-model.c @@ -1352,7 +1352,6 @@ gnc_split_register_get_balance_entry (VirtualLocation virt_loc, Account *account; split = gnc_split_register_get_split (reg, virt_loc.vcell_loc); - if (split == xaccSplitLookup (&info->blank_split_guid, gnc_get_current_book ())) return NULL; @@ -1372,7 +1371,7 @@ gnc_split_register_get_balance_entry (VirtualLocation virt_loc, if (gnc_reverse_balance (account)) balance = gnc_numeric_neg (balance); - return xaccPrintAmount (balance, gnc_account_print_info (account, FALSE)); + return xaccPrintAmount (balance, gnc_account_print_info (account, reg->mismatched_commodities)); } static const char * @@ -1655,7 +1654,7 @@ gnc_split_register_get_tdebcred_entry (VirtualLocation virt_loc, total = gnc_numeric_abs (total); - return xaccPrintAmount (total, gnc_split_amount_print_info (split, FALSE)); + return xaccPrintAmount (total, gnc_split_amount_print_info (split, reg->mismatched_commodities)); } /* return TRUE if we have a RATE_CELL; return FALSE if we do not. @@ -1811,7 +1810,7 @@ gnc_split_register_get_debcred_entry (VirtualLocation virt_loc, GNC_HOW_RND_ROUND_HALF_UP); } - return xaccPrintAmount (imbalance, gnc_account_print_info (acc, FALSE)); + return xaccPrintAmount (imbalance, gnc_account_print_info (acc, reg->mismatched_commodities)); } { @@ -1874,22 +1873,20 @@ gnc_split_register_get_debcred_entry (VirtualLocation virt_loc, * currency != the account commodity, then use the SplitAmount * instead of the SplitValue. */ + gboolean currency_match; switch (reg->type) { case STOCK_REGISTER: case CURRENCY_REGISTER: case PORTFOLIO_LEDGER: amount = xaccSplitGetValue (split); - print_info = gnc_commodity_print_info (currency, FALSE); + print_info = gnc_commodity_print_info (currency, reg->mismatched_commodities); break; default: - if (commodity && !gnc_commodity_equal (commodity, currency)) - /* Convert this to the "local" value */ - amount = xaccSplitConvertAmount(split, account); - else - amount = xaccSplitGetValue (split); - print_info = gnc_account_print_info (account, FALSE); + amount = xaccSplitGetValue (split); + print_info = gnc_account_print_info (account, reg->mismatched_commodities); + print_info.commodity = currency; break; } } @@ -1929,7 +1926,7 @@ gnc_split_register_get_rbaln_entry (VirtualLocation virt_loc, if (split == xaccSplitLookup (&info->blank_split_guid, gnc_get_current_book ())) return NULL; - + trans = xaccSplitGetParent (split); if (!trans) return NULL; @@ -2421,7 +2418,7 @@ gnc_template_register_get_debcred_entry (VirtualLocation virt_loc, amount2 = gnc_numeric_abs (*amount); g_free (amount); - return xaccPrintAmount (amount2, gnc_default_print_info (FALSE)); + return xaccPrintAmount (amount2, gnc_default_print_info (reg->mismatched_commodities)); } static void diff --git a/gnucash/register/ledger-core/split-register.c b/gnucash/register/ledger-core/split-register.c index f4ae8770a2..4ffe9eaabf 100644 --- a/gnucash/register/ledger-core/split-register.c +++ b/gnucash/register/ledger-core/split-register.c @@ -2816,7 +2816,8 @@ gnc_split_register_init (SplitRegister *reg, SplitRegisterStyle style, gboolean use_double_line, gboolean do_auto_complete, - gboolean is_template) + gboolean is_template, + gboolean mismatched_commodities) { TableLayout *layout; TableModel *model; @@ -2857,6 +2858,7 @@ gnc_split_register_init (SplitRegister *reg, reg->use_double_line = use_double_line; reg->do_auto_complete = do_auto_complete; reg->is_template = is_template; + reg->mismatched_commodities = mismatched_commodities; reg->use_tran_num_for_num_field = (qof_book_use_split_action_for_num_field(gnc_get_current_book()) ? FALSE : TRUE); @@ -2914,7 +2916,8 @@ SplitRegister * gnc_split_register_new (SplitRegisterType type, SplitRegisterStyle style, gboolean use_double_line, - gboolean is_template) + gboolean is_template, + gboolean mismatched_commodities) { SplitRegister * reg; gboolean default_do_auto_complete = TRUE; @@ -2929,7 +2932,8 @@ gnc_split_register_new (SplitRegisterType type, style, use_double_line, default_do_auto_complete, - is_template); + is_template, + mismatched_commodities); return reg; } diff --git a/gnucash/register/ledger-core/split-register.h b/gnucash/register/ledger-core/split-register.h index 76cb5abfd1..e7c90c5c4a 100644 --- a/gnucash/register/ledger-core/split-register.h +++ b/gnucash/register/ledger-core/split-register.h @@ -254,6 +254,8 @@ struct split_register gboolean is_template; gboolean do_auto_complete; /**< whether to use auto-completion */ + gboolean mismatched_commodities; /**< indicates the register includes transactions in + mismatched commodities */ SplitList *unrecn_splits; /**< list of splits to unreconcile after transaction edit */ @@ -282,7 +284,8 @@ typedef GtkWidget *(*SRGetParentCallback) (gpointer user_data); SplitRegister * gnc_split_register_new (SplitRegisterType type, SplitRegisterStyle style, gboolean use_double_line, - gboolean is_template); + gboolean is_template, + gboolean mismatched_commodities); /** Destroys a split register. *