Skip to content

Commit

Permalink
[assistant-stock-transaction] refactor: centralize price calculator
Browse files Browse the repository at this point in the history
Price was being computed in 3 places: the stock_value page, the
summary-table info list, and the final pricedb creation function. This
commit centralizes it into 1 function which returns std::nullopt if
the price is not computable.

Also fixes price display to follow global pref general/force-price-decimal
  • Loading branch information
christopherlam committed Sep 17, 2022
1 parent 9a8bc8f commit 6ba0f84
Showing 1 changed file with 34 additions and 28 deletions.
62 changes: 34 additions & 28 deletions gnucash/gnome/assistant-stock-transaction.cpp
Expand Up @@ -490,6 +490,22 @@ refresh_page_transaction_type (GtkWidget *widget, gpointer user_data)
info->txn_type->fees_capitalize);
}

static std::optional<gnc_numeric>
calculate_price (StockTransactionInfo* info)
{
gnc_numeric amount, value;

if (info->txn_type->stock_amount == FieldMask::DISABLED ||
info->txn_type->stock_value == FieldMask::DISABLED ||
gnc_amount_edit_expr_is_valid (GNC_AMOUNT_EDIT (info->stock_amount_edit), &amount, true, nullptr) ||
gnc_amount_edit_expr_is_valid (GNC_AMOUNT_EDIT (info->stock_value_edit), &value, true, nullptr))
return std::nullopt;

if (gnc_numeric_zero_p (amount) || gnc_numeric_zero_p (value))
return std::nullopt;

return gnc_numeric_div (value, amount, GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT);
}

static void
refresh_page_stock_amount (GtkWidget *widget, gpointer user_data)
Expand Down Expand Up @@ -540,24 +556,19 @@ static void
refresh_page_stock_value (GtkWidget *widget, gpointer user_data)
{
auto info = static_cast<StockTransactionInfo*>(user_data);
gnc_numeric amount, value;
g_return_if_fail (info->txn_type);

if (info->txn_type->stock_amount == FieldMask::DISABLED ||
info->txn_type->stock_value == FieldMask::DISABLED ||
gnc_amount_edit_expr_is_valid (GNC_AMOUNT_EDIT (info->stock_amount_edit), &amount, true, nullptr) ||
gnc_amount_edit_expr_is_valid (GNC_AMOUNT_EDIT (info->stock_value_edit), &value, true, nullptr) ||
gnc_numeric_zero_p (value))
auto price = calculate_price (info);
if (!price.has_value())
{
// Translators: StockAssistant: N/A denotes stock price is not computable
const char* na_label = N_("N/A");
gtk_label_set_text (GTK_LABEL (info->price_value), _(na_label));
return;
}

auto price = gnc_numeric_div (value, amount, GNC_DENOM_AUTO, GNC_HOW_RND_ROUND);
auto pinfo = gnc_commodity_print_info (info->currency, true);
gtk_label_set_text (GTK_LABEL (info->price_value), xaccPrintAmount (price, pinfo));
auto pinfo = gnc_price_print_info (info->currency, true);
gtk_label_set_text (GTK_LABEL (info->price_value), xaccPrintAmount (*price, pinfo));
}

static void
Expand Down Expand Up @@ -796,21 +807,18 @@ to ensure proper recording."), new_date_str, last_split_date_str);

add_to_summary_table (list, line);

if (info->txn_type->stock_amount != FieldMask::DISABLED &&
info->txn_type->stock_value != FieldMask::DISABLED)
auto price = calculate_price (info);
if (price.has_value())
{
auto amt = gnc_amount_edit_get_amount (GNC_AMOUNT_EDIT(info->stock_amount_edit));
auto val = gnc_amount_edit_get_amount (GNC_AMOUNT_EDIT(info->stock_value_edit));
auto p = gnc_numeric_div (val, amt, GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT);
auto curr_pinfo = gnc_commodity_print_info (info->currency, true);
auto curr_pinfo = gnc_price_print_info (info->currency, true);
// Translators: %s refer to: stock mnemonic, broker currency,
// date of transaction.
auto tmpl = N_("A price of 1 %s = %s on %s will be recorded.");
auto date_str = qof_print_date (new_date);
auto price_str = g_strdup_printf
(_(tmpl),
gnc_commodity_get_mnemonic (xaccAccountGetCommodity (info->acct)),
xaccPrintAmount (p, curr_pinfo), date_str);
xaccPrintAmount (*price, curr_pinfo), date_str);
infos.emplace_back (price_str);
g_free (price_str);
g_free (date_str);
Expand Down Expand Up @@ -1036,21 +1044,22 @@ create_split (Transaction *trans, FieldMask splitfield,
}

static void
add_price (GtkWidget *amount, GtkWidget *value,
gnc_commodity *commodity, gnc_commodity *currency, time64 date)
add_price (StockTransactionInfo* info, time64 date)
{
auto amt = gnc_amount_edit_get_amount (GNC_AMOUNT_EDIT (amount));
auto val = gnc_amount_edit_get_amount (GNC_AMOUNT_EDIT (value));
auto p = gnc_numeric_div (val, amt, GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT);
auto p = calculate_price (info);

if (!p.has_value())
return;

auto price = gnc_price_create (gnc_get_current_book ());

gnc_price_begin_edit (price);
gnc_price_set_commodity (price, commodity);
gnc_price_set_currency (price, currency);
gnc_price_set_commodity (price, xaccAccountGetCommodity (info->acct));
gnc_price_set_currency (price, info->currency);
gnc_price_set_time64 (price, date);
gnc_price_set_source (price, PRICE_SOURCE_STOCK_TRANSACTION);
gnc_price_set_typestr (price, PRICE_TYPE_UNK);
gnc_price_set_value (price, p);
gnc_price_set_value (price, *p);
gnc_price_commit_edit (price);

auto book = gnc_get_current_book ();
Expand Down Expand Up @@ -1143,10 +1152,7 @@ stock_assistant_finish (GtkAssistant *assistant, gpointer user_data)
gnc_numeric_zero (), capgains, false, info);
}

if (info->txn_type->stock_amount != FieldMask::DISABLED &&
info->txn_type->stock_value != FieldMask::DISABLED)
add_price (info->stock_amount_edit, info->stock_value_edit,
xaccAccountGetCommodity (info->acct), info->currency, date);
add_price (info, date);

xaccTransCommitEdit (trans);

Expand Down

0 comments on commit 6ba0f84

Please sign in to comment.