From 2cd69e8d85f8f1538409deeb657a379a0bc36c92 Mon Sep 17 00:00:00 2001 From: Christopher Lam Date: Sat, 19 Oct 2019 16:19:11 +0800 Subject: [PATCH] [budgets.c] handle both natural & reversed signs budgets introduce new API * gnc_using_unreversed_budgets - queries book's unreversed feature * gnc_reverse_budget_balance - check if book unreversal status matches 2nd argument. if so, return account's reversal status. else, return FALSE. * gnome-budget-view can now show both natural and reversed budgets * gnome-plugin-page-budget will now read&write both natural and reversed budgets. --- gnucash/gnome/gnc-budget-view.c | 29 +++++++++++++++++++------- gnucash/gnome/gnc-plugin-page-budget.c | 14 +++++++------ libgnucash/app-utils/app-utils.i | 2 ++ libgnucash/app-utils/gnc-ui-util.c | 17 +++++++++++++++ libgnucash/app-utils/gnc-ui-util.h | 10 +++++++++ 5 files changed, 59 insertions(+), 13 deletions(-) diff --git a/gnucash/gnome/gnc-budget-view.c b/gnucash/gnome/gnc-budget-view.c index 9846e5e3f8..f8972910a3 100644 --- a/gnucash/gnome/gnc-budget-view.c +++ b/gnucash/gnome/gnc-budget-view.c @@ -901,6 +901,10 @@ gbv_get_accumulated_budget_amount(GncBudget* budget, Account* account, guint per { info.total = gnc_budget_get_account_period_value(budget, account, period_num); } + + if (gnc_reverse_budget_balance (account, TRUE)) + info.total = gnc_numeric_neg (info.total); + return info.total; } @@ -979,6 +983,9 @@ budget_col_source(Account *account, GtkTreeViewColumn *col, } else { + if (gnc_reverse_budget_balance (account, TRUE)) + numeric = gnc_numeric_neg (numeric); + xaccSPrintAmount(amtbuff, numeric, gnc_account_print_info(account, FALSE)); g_object_set(cell, "foreground", @@ -1019,6 +1026,9 @@ bgv_get_total_for_account(Account* account, GncBudget* budget, gnc_commodity *ne { numeric = gbv_get_accumulated_budget_amount(budget, account, period_num); + if (gnc_reverse_budget_balance (account, TRUE)) + numeric = gnc_numeric_neg (numeric); + if (new_currency) { numeric = gnc_pricedb_convert_balance_nearest_price_t64( @@ -1043,6 +1053,10 @@ bgv_get_total_for_account(Account* account, GncBudget* budget, gnc_commodity *ne } } } + + if (gnc_reverse_budget_balance (account, TRUE)) + total = gnc_numeric_neg(total); + return total; } @@ -1093,8 +1107,12 @@ budget_col_edited(Account *account, GtkTreeViewColumn *col, if (new_text && *new_text == '\0') gnc_budget_unset_account_period_value(budget, account, period_num); else + { + if (gnc_reverse_budget_balance (account, TRUE)) + numeric = gnc_numeric_neg(numeric); gnc_budget_set_account_period_value(budget, account, period_num, numeric); + } } /** \brief Function to find the total in a column of budget provided and @@ -1124,7 +1142,7 @@ totals_col_source(GtkTreeViewColumn *col, GtkCellRenderer *cell, gchar amtbuff[100]; //FIXME: overkill, where's the #define? gint i; gint num_top_accounts; - gboolean neg, red; + gboolean red; GNCPriceDB *pdb; gnc_commodity *total_currency, *currency; @@ -1150,7 +1168,6 @@ totals_col_source(GtkTreeViewColumn *col, GtkCellRenderer *cell, { account = gnc_account_nth_child(priv->rootAcct, i); currency = gnc_account_get_currency_or_parent(account); - neg = FALSE; switch (xaccAccountGetType(account)) { @@ -1166,16 +1183,14 @@ totals_col_source(GtkTreeViewColumn *col, GtkCellRenderer *cell, continue; break; case ACCT_TYPE_EXPENSE: - if (row_type == TOTALS_TYPE_TOTAL) - neg = TRUE; - else if (row_type != TOTALS_TYPE_EXPENSES) + if ((row_type != TOTALS_TYPE_EXPENSES) && + (row_type != TOTALS_TYPE_TOTAL)) continue; break; case ACCT_TYPE_ASSET: if (row_type != TOTALS_TYPE_TRANSFERS && row_type != TOTALS_TYPE_TOTAL) continue; - neg = TRUE; break; default: continue; @@ -1196,7 +1211,7 @@ totals_col_source(GtkTreeViewColumn *col, GtkCellRenderer *cell, gnc_budget_get_period_start_date(budget, period_num)); } - if (neg) + if (gnc_reverse_budget_balance (account, TRUE)) total = gnc_numeric_sub(total, value, GNC_DENOM_AUTO, GNC_HOW_DENOM_LCD); else diff --git a/gnucash/gnome/gnc-plugin-page-budget.c b/gnucash/gnome/gnc-plugin-page-budget.c index ca77b48937..d7ae5352d8 100644 --- a/gnucash/gnome/gnc-plugin-page-budget.c +++ b/gnucash/gnome/gnc-plugin-page-budget.c @@ -902,7 +902,7 @@ estimate_budget_helper(GtkTreeModel *model, GtkTreePath *path, GNC_HOW_DENOM_SIGFIGS(priv->sigFigs) | GNC_HOW_RND_ROUND_HALF_UP); - if (gnc_reverse_balance(acct)) + if (gnc_reverse_budget_balance(acct, FALSE)) num = gnc_numeric_neg(num); for (i = 0; i < num_periods; i++) @@ -920,7 +920,7 @@ estimate_budget_helper(GtkTreeModel *model, GtkTreePath *path, if (!gnc_numeric_check(num)) { - if (gnc_reverse_balance(acct)) + if (gnc_reverse_budget_balance(acct, FALSE)) num = gnc_numeric_neg(num); num = gnc_numeric_convert(num, GNC_DENOM_AUTO, @@ -1020,7 +1020,7 @@ allperiods_budget_helper(GtkTreeModel *model, GtkTreePath *path, { Account *acct; guint num_periods, i; - gnc_numeric num; + gnc_numeric num, allvalue; GncPluginPageBudgetPrivate *priv; GncPluginPageBudget *page = data; @@ -1028,7 +1028,9 @@ allperiods_budget_helper(GtkTreeModel *model, GtkTreePath *path, priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(page); acct = gnc_budget_view_get_account_from_path(priv->budget_view, path); num_periods = gnc_budget_get_num_periods(priv->budget); - num = priv->allValue; + allvalue = priv->allValue; + if (gnc_reverse_budget_balance(acct, TRUE)) + allvalue = gnc_numeric_neg(allvalue); for (i = 0; i < num_periods; i++) { @@ -1036,7 +1038,7 @@ allperiods_budget_helper(GtkTreeModel *model, GtkTreePath *path, { case ADD: num = gnc_budget_get_account_period_value(priv->budget, acct, i); - num = gnc_numeric_add(num, priv->allValue, GNC_DENOM_AUTO, + num = gnc_numeric_add(num, allvalue, GNC_DENOM_AUTO, GNC_HOW_DENOM_SIGFIGS(priv->sigFigs) | GNC_HOW_RND_ROUND_HALF_UP); gnc_budget_set_account_period_value(priv->budget, acct, i, num); @@ -1053,7 +1055,7 @@ allperiods_budget_helper(GtkTreeModel *model, GtkTreePath *path, break; default: gnc_budget_set_account_period_value(priv->budget, acct, i, - priv->allValue); + allvalue); break; } } diff --git a/libgnucash/app-utils/app-utils.i b/libgnucash/app-utils/app-utils.i index 7ded4efa82..2da48b375b 100644 --- a/libgnucash/app-utils/app-utils.i +++ b/libgnucash/app-utils/app-utils.i @@ -116,6 +116,8 @@ const char * xaccPrintAmount (gnc_numeric val, GNCPrintAmountInfo info); gchar *number_to_words(gdouble val, gint64 denom); const gchar *printable_value (gdouble val, gint denom); +gboolean gnc_using_unreversed_budgets (QofBook* book); +gboolean gnc_reverse_budget_balance (const Account *account, gboolean unreversed); gboolean gnc_reverse_balance (const Account *account); gboolean gnc_is_euro_currency(const gnc_commodity * currency); diff --git a/libgnucash/app-utils/gnc-ui-util.c b/libgnucash/app-utils/gnc-ui-util.c index bae5f388bc..3ff97e105c 100644 --- a/libgnucash/app-utils/gnc-ui-util.c +++ b/libgnucash/app-utils/gnc-ui-util.c @@ -179,6 +179,23 @@ gnc_reverse_balance (const Account *account) return reverse_type[type]; } +gboolean gnc_using_unreversed_budgets (QofBook* book) +{ + return gnc_features_check_used (book, GNC_FEATURE_BUDGET_UNREVERSED); +} + +/* similar to gnc_reverse_balance but also accepts a gboolean + unreversed which specifies the reversal strategy - FALSE = pre-4.x + always-assume-credit-accounts, TRUE = all amounts unreversed */ +gboolean +gnc_reverse_budget_balance (const Account *account, gboolean unreversed) +{ + if (unreversed == gnc_using_unreversed_budgets(gnc_account_get_book(account))) + return gnc_reverse_balance (account); + + return FALSE; +} + gchar * gnc_get_default_directory (const gchar *section) diff --git a/libgnucash/app-utils/gnc-ui-util.h b/libgnucash/app-utils/gnc-ui-util.h index 4601f3b8b7..472ee4dbc0 100644 --- a/libgnucash/app-utils/gnc-ui-util.h +++ b/libgnucash/app-utils/gnc-ui-util.h @@ -46,6 +46,16 @@ typedef QofSession * (*QofSessionCB) (void); gchar *gnc_normalize_account_separator (const gchar* separator); gboolean gnc_reverse_balance(const Account *account); +/* Backward compatibility ******************************************* + * Return book's UNREVERSED_BUDGET feature check. */ +gboolean gnc_using_unreversed_budgets (QofBook* book); + +/* Backward compatibility ******************************************* + * Compare book's UNREVERSED_BUDGET with unreverse_check. If they + * match, return account reversal according to global pref. If they + * don't match, return FALSE. */ +gboolean gnc_reverse_budget_balance (const Account *account, gboolean unreversed); + /* Default directory sections ***************************************/ #define GNC_PREFS_GROUP_OPEN_SAVE "dialogs.open-save" #define GNC_PREFS_GROUP_EXPORT "dialogs.export-accounts"