Bug 794755 - Commodity Register displays fractional prices

When printing numbers convert them to a new decimal denominator with
rounding if the passed-in print info specifies that they should be
forced and rounded.

Make the default price settings forced and rounded.

Pass the price currency to gnc_default_price_print_info and
use the currency's fraction * 100 to determine the round-to
denominator and the number of decimal places to display.
This commit is contained in:
John Ralls 2018-07-15 13:20:21 -07:00
parent 374477c360
commit 1fffbaf856
8 changed files with 56 additions and 22 deletions

View File

@ -1805,12 +1805,9 @@ gtv_sr_cdf0 (GtkTreeViewColumn *col, GtkCellRenderer *cell, GtkTreeModel *s_mode
}
else
{
GNCPrintAmountInfo print_info;
print_info = gnc_default_price_print_info();
print_info.min_decimal_places = 2;
num = gnc_numeric_convert (gnc_tree_util_get_rate_for (view, trans, split, is_blank), 1000000, GNC_HOW_RND_ROUND_HALF_UP);
GNCPrintAmountInfo print_info =
gnc_default_price_print_info(xaccTransGetCurrency(trans));
num = gnc_tree_util_get_rate_for (view, trans, split, is_blank);
if (gnc_numeric_check (num) == GNC_ERROR_OK)
s = xaccPrintAmount (num, print_info);

View File

@ -2213,7 +2213,7 @@ loan_rev_update_view( LoanAssistantData *ldd, GDate *start, GDate *end )
GtkListStore *store;
GtkTreeIter iter;
pai = gnc_default_price_print_info();
pai = gnc_default_price_print_info(NULL);
pai.min_decimal_places = 2;
store = GTK_LIST_STORE(gtk_tree_view_get_model( ldd->revView ));
@ -2522,7 +2522,7 @@ ld_setup_repayment_sx( LoanAssistantData *ldd,
TTSplitInfo *fromSplit = NULL;
TTSplitInfo *ttsi;
TTInfo *toTxn = NULL;
GNCPrintAmountInfo pricePAI = gnc_default_price_print_info();
GNCPrintAmountInfo pricePAI = gnc_default_price_print_info(NULL);
#define AMTBUF_LEN 64
gchar amtBuf[AMTBUF_LEN];
gint GNCN_HOW = (GNC_HOW_DENOM_SIGFIGS(2) | GNC_HOW_RND_ROUND_HALF_UP);

View File

@ -630,7 +630,7 @@ gnc_stock_split_assistant_create (StockSplitInfo *info)
amount = gnc_amount_edit_new ();
gnc_amount_edit_set_print_info (GNC_AMOUNT_EDIT (amount),
gnc_default_price_print_info ());
gnc_default_price_print_info (gnc_default_currency()));
g_signal_connect (amount, "changed",
G_CALLBACK (gnc_stock_split_details_valid_cb), info);
gnc_amount_edit_set_evaluate_on_enter (GNC_AMOUNT_EDIT (amount), TRUE);

View File

@ -461,7 +461,7 @@ gnc_price_pedit_dialog_create (GtkWidget *parent,
pedit_dialog->price_edit = w;
gtk_box_pack_start (GTK_BOX (box), w, TRUE, TRUE, 0);
gnc_amount_edit_set_evaluate_on_enter (GNC_AMOUNT_EDIT (w), TRUE);
print_info = gnc_default_price_print_info ();
print_info = gnc_default_price_print_info (gnc_currency_edit_get_currency (GNC_CURRENCY_EDIT (pedit_dialog->currency_edit)));
gnc_amount_edit_set_print_info (GNC_AMOUNT_EDIT (w), print_info);
gtk_entry_set_activates_default(GTK_ENTRY(w), TRUE);
gtk_widget_show (w);

View File

@ -1201,6 +1201,7 @@ gnc_split_register_get_rate_entry (VirtualLocation virt_loc,
Split *split, *osplit;
Transaction *txn;
gnc_numeric amount, value, convrate;
gnc_commodity *curr;
SRInfo *info = gnc_split_register_get_info (reg);
if (info->rate_reset == RATE_RESET_REQD && info->auto_complete)
@ -1216,7 +1217,7 @@ gnc_split_register_get_rate_entry (VirtualLocation virt_loc,
*/
osplit = xaccSplitGetOtherSplit (split);
txn = gnc_split_register_get_trans (reg, virt_loc.vcell_loc);
curr = xaccTransGetCurrency (xaccSplitGetParent (split));
if (!gnc_split_register_current_trans_expanded (reg) && osplit &&
!gnc_split_register_needs_conv_rate(reg, txn,
xaccSplitGetAccount(split)))
@ -1232,7 +1233,7 @@ gnc_split_register_get_rate_entry (VirtualLocation virt_loc,
convrate = gnc_numeric_div (amount, value, GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE);
return xaccPrintAmount (convrate, gnc_default_price_print_info ());
return xaccPrintAmount (convrate, gnc_default_price_print_info (curr));
}
static const char *
@ -1361,6 +1362,7 @@ gnc_split_register_get_price_entry (VirtualLocation virt_loc,
{
SplitRegister *reg = user_data;
gnc_numeric price;
gnc_commodity *curr;
Split *split;
if (!gnc_split_register_use_security_cells (reg, virt_loc))
@ -1369,10 +1371,11 @@ gnc_split_register_get_price_entry (VirtualLocation virt_loc,
split = gnc_split_register_get_split (reg, virt_loc.vcell_loc);
price = xaccSplitGetSharePrice (split);
curr = xaccTransGetCurrency (xaccSplitGetParent (split));
if (gnc_numeric_zero_p (price))
return NULL;
return xaccPrintAmount (price, gnc_default_price_print_info ());
return xaccPrintAmount (price, gnc_default_price_print_info (curr));
}
static char *

View File

@ -2648,7 +2648,7 @@ gnc_split_register_config_cells (SplitRegister *reg)
gnc_price_cell_set_print_info
((PriceCell *)
gnc_table_layout_get_cell (reg->table->layout, PRIC_CELL),
gnc_default_price_print_info ());
gnc_default_price_print_info (gnc_default_currency ()));
break;
default:

View File

@ -80,6 +80,11 @@ static gboolean reverse_type[NUM_ACCOUNT_TYPES];
* as that will change any time the book changes. */
static gchar *user_default_currency = NULL;
static gchar *user_report_currency = NULL;
const static int maximum_decimals = 15;
static const gint64 pow10[] = {1, 10, 100, 1000, 10000, 100000, 1000000,
10000000, 100000000, 1000000000, 10000000000,
100000000000, 1000000000000, 10000000000000,
100000000000000, 1000000000000000};
gchar *gnc_normalize_account_separator (const gchar* separator)
{
@ -1317,17 +1322,31 @@ gnc_share_print_info_places (int decplaces)
}
GNCPrintAmountInfo
gnc_default_price_print_info (void)
gnc_default_price_print_info (const gnc_commodity *curr)
{
static GNCPrintAmountInfo info;
static gboolean got_it = FALSE;
GNCPrintAmountInfo info;
info.commodity = curr;
if (!got_it)
if (info.commodity)
{
info = gnc_default_print_info_helper (6);
got_it = TRUE;
int frac = gnc_commodity_get_fraction (curr);
guint8 decplaces = 2;
while (frac != 1 && (frac % 10) == 0 && (frac /= 10)) ++decplaces;
info.max_decimal_places = decplaces;
info.min_decimal_places = decplaces;
}
else
{
info.max_decimal_places = 6;
info.min_decimal_places = 0;
}
info.use_separators = 1;
info.use_symbol = 0;
info.use_locale = 1;
info.monetary = 1;
info.force_fit = TRUE;
info.round = TRUE;
return info;
}
@ -1373,7 +1392,22 @@ PrintAmountInternal(char *buf, gnc_numeric val, const GNCPrintAmountInfo *info)
/* Try to print as decimal. */
value_is_decimal = gnc_numeric_to_decimal(&val, NULL);
if (!value_is_decimal && info->force_fit && info->round)
{
gint64 denom = pow10[maximum_decimals];
/* if there's a commodity use 100x the commodity's fraction. N.B. This
* assumes that commodity fractions are multiples of 10, a reasonable
* assumption in 2018. Otherwise, if there's a reasonable
* max_decimal_places, use that.
*/
if (info->commodity)
denom = gnc_commodity_get_fraction(info->commodity) * 100;
else if (info->max_decimal_places &&
info->max_decimal_places <= maximum_decimals)
denom = pow10[info->max_decimal_places];
val = gnc_numeric_convert(val, denom, GNC_HOW_RND_ROUND_HALF_UP);
value_is_decimal = gnc_numeric_to_decimal(&val, NULL);
}
/* Force at least auto_decimal_places zeros */
if (auto_decimal_enabled)
{

View File

@ -293,7 +293,7 @@ GNCPrintAmountInfo gnc_split_amount_print_info (Split *split,
GNCPrintAmountInfo gnc_share_print_info_places (int decplaces);
GNCPrintAmountInfo gnc_default_share_print_info (void);
GNCPrintAmountInfo gnc_default_price_print_info (void);
GNCPrintAmountInfo gnc_default_price_print_info (const gnc_commodity *curr);
GNCPrintAmountInfo gnc_integral_print_info (void);