Merge branch 'maint-stock-assistant-stock-split' into maint #1414

pull/919/merge
Christopher Lam 4 years ago
commit 8dd063b84d

@ -113,6 +113,7 @@ FieldMask operator ^(FieldMask lhs, FieldMask rhs)
struct TxnTypeInfo
{
FieldMask stock_amount;
bool input_new_balance;
FieldMask stock_value;
FieldMask cash_value;
FieldMask fees_value;
@ -131,6 +132,7 @@ static const TxnTypeVec starting_types
{
{
FieldMask::ENABLED_DEBIT, // stock_amt
false, // input_new_balance
FieldMask::ENABLED_DEBIT, // stock_val
FieldMask::ENABLED_CREDIT, // cash_amt
FieldMask::ENABLED_DEBIT | FieldMask::ALLOW_ZERO, // fees_amt
@ -144,6 +146,7 @@ static const TxnTypeVec starting_types
},
{
FieldMask::ENABLED_CREDIT, // stock_amt
false, // input_new_balance
FieldMask::ENABLED_CREDIT, // stock_val
FieldMask::ENABLED_DEBIT, // cash_amt
FieldMask::ENABLED_DEBIT | FieldMask::ALLOW_ZERO, // fees_amt
@ -161,6 +164,7 @@ static const TxnTypeVec long_types
{
{
FieldMask::ENABLED_DEBIT, // stock_amt
false, // input_new_balance
FieldMask::ENABLED_DEBIT, // stock_val
FieldMask::ENABLED_CREDIT, // cash_amt
FieldMask::ENABLED_DEBIT | FieldMask::ALLOW_ZERO, // fees_amt
@ -174,6 +178,7 @@ static const TxnTypeVec long_types
},
{
FieldMask::ENABLED_CREDIT, // stock_amt
false, // input_new_balance
FieldMask::ENABLED_CREDIT, // stock_val
FieldMask::ENABLED_DEBIT, // cash_amt
FieldMask::ENABLED_DEBIT | FieldMask::ALLOW_ZERO, // fees_amt
@ -187,6 +192,7 @@ static const TxnTypeVec long_types
},
{
FieldMask::DISABLED, // stock_amt
false, // input_new_balance
FieldMask::DISABLED, // stock_val
FieldMask::ENABLED_DEBIT, // cash_amt
FieldMask::ENABLED_DEBIT | FieldMask::ALLOW_ZERO, // fees_amt
@ -201,6 +207,7 @@ reinvested must be subsequently recorded as a regular stock purchase.")
},
{
FieldMask::DISABLED, // stock_amt
false, // input_new_balance
FieldMask::ENABLED_CREDIT, // stock_val
FieldMask::ENABLED_DEBIT, // cash_amt
FieldMask::ENABLED_DEBIT | FieldMask::ALLOW_ZERO, // fees_amt
@ -214,6 +221,7 @@ reinvested must be subsequently recorded as a regular stock purchase.")
},
{
FieldMask::DISABLED, // stock_amt
false, // input_new_balance
FieldMask::ENABLED_DEBIT, // stock_val
FieldMask::DISABLED, // cash_amt
FieldMask::ENABLED_DEBIT | FieldMask::ALLOW_ZERO, // fees_amt
@ -227,6 +235,7 @@ reinvested must be subsequently recorded as a regular stock purchase.")
},
{
FieldMask::ENABLED_DEBIT, // stock_amt
true, // input_new_balance
FieldMask::DISABLED, // stock_val
FieldMask::DISABLED, // cash_amt
FieldMask::ENABLED_DEBIT | FieldMask::ALLOW_ZERO, // fees_amt
@ -240,6 +249,7 @@ reinvested must be subsequently recorded as a regular stock purchase.")
},
{
FieldMask::ENABLED_CREDIT, // stock_amt
true, // input_new_balance
FieldMask::DISABLED, // stock_val
FieldMask::DISABLED, // cash_amt
FieldMask::ENABLED_DEBIT | FieldMask::ALLOW_ZERO, // fees_amt
@ -260,6 +270,7 @@ static const TxnTypeVec short_types
{
{
FieldMask::ENABLED_CREDIT, // stock_amt
false, // input_new_balance
FieldMask::ENABLED_CREDIT, // stock_val
FieldMask::ENABLED_DEBIT, // cash_amt
FieldMask::ENABLED_DEBIT | FieldMask::ALLOW_ZERO, // fees_amt
@ -273,6 +284,7 @@ static const TxnTypeVec short_types
},
{
FieldMask::ENABLED_DEBIT, // stock_amt
false, // input_new_balance
FieldMask::ENABLED_DEBIT, // stock_val
FieldMask::ENABLED_CREDIT, // cash_amt
FieldMask::ENABLED_DEBIT | FieldMask::ALLOW_ZERO, // fees_amt
@ -286,6 +298,7 @@ static const TxnTypeVec short_types
},
{
FieldMask::DISABLED, // stock_amt
false, // input_new_balance
FieldMask::DISABLED, // stock_val
FieldMask::ENABLED_CREDIT, // cash_amt
FieldMask::ENABLED_DEBIT | FieldMask::ALLOW_ZERO, // fees_amt
@ -299,6 +312,7 @@ static const TxnTypeVec short_types
},
{
FieldMask::DISABLED, // stock_amt
false, // input_new_balance
FieldMask::ENABLED_DEBIT, // stock_val
FieldMask::ENABLED_CREDIT, // cash_amt
FieldMask::ENABLED_DEBIT | FieldMask::ALLOW_ZERO, // fees_amt
@ -312,6 +326,7 @@ static const TxnTypeVec short_types
},
{
FieldMask::DISABLED, // stock_amt
false, // input_new_balance
FieldMask::ENABLED_CREDIT, // stock_val
FieldMask::DISABLED, // cash_amt
FieldMask::ENABLED_DEBIT | FieldMask::ALLOW_ZERO, // fees_amt
@ -325,6 +340,7 @@ static const TxnTypeVec short_types
},
{
FieldMask::ENABLED_CREDIT, // stock_amt
true, // input_new_balance
FieldMask::DISABLED, // stock_val
FieldMask::DISABLED, // cash_amt
FieldMask::ENABLED_DEBIT | FieldMask::ALLOW_ZERO, // fees_amt
@ -338,6 +354,7 @@ static const TxnTypeVec short_types
},
{
FieldMask::ENABLED_DEBIT, // stock_amt
true, // input_new_balance
FieldMask::DISABLED, // stock_val
FieldMask::DISABLED, // cash_amt
FieldMask::ENABLED_DEBIT | FieldMask::ALLOW_ZERO, // fees_amt
@ -382,9 +399,12 @@ typedef struct
// stock amount page
gnc_numeric balance_at_date;
GtkWidget * stock_amount_page;
GtkWidget * stock_amount_title;
GtkWidget * prev_amount;
GtkWidget * next_amount;
GtkWidget * next_amount_label;
GtkWidget * stock_amount_edit;
GtkWidget * stock_amount_label;
// stock value page
GtkWidget * stock_value_page;
@ -484,6 +504,24 @@ refresh_page_stock_amount (GtkWidget *widget, gpointer user_data)
if (gnc_amount_edit_expr_is_valid (GNC_AMOUNT_EDIT (info->stock_amount_edit),
&stock_amount, true, nullptr))
gtk_label_set_text (GTK_LABEL(info->next_amount), nullptr);
else if (info->txn_type->input_new_balance)
{
gnc_numeric ratio = gnc_numeric_div (stock_amount, bal,
GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE);
if (gnc_numeric_check (ratio) || gnc_numeric_negative_p (ratio))
gtk_label_set_text (GTK_LABEL(info->next_amount), nullptr);
else
{
auto str = gnc_numeric_to_string (ratio);
auto p = str ? strchr (str, '/') : nullptr;
if (p)
*p = ':';
auto lbl = g_strdup_printf (_("%s Split"), str);
gtk_label_set_text (GTK_LABEL(info->next_amount), lbl);
g_free (lbl);
g_free (str);
}
}
else
{
if (info->txn_type->stock_amount == FieldMask::ENABLED_CREDIT)
@ -704,7 +742,30 @@ to ensure proper recording."), new_date_str, last_split_date_str);
NC_ ("Stock Assistant: Page name", "stock value"), errors);
if (info->txn_type->stock_amount != FieldMask::DISABLED)
if (info->txn_type->stock_amount == FieldMask::DISABLED)
;
else if (info->txn_type->input_new_balance)
{
auto stock_amount = gnc_amount_edit_get_amount
(GNC_AMOUNT_EDIT(info->stock_amount_edit));
auto credit_side = (info->txn_type->stock_amount & FieldMask::ENABLED_CREDIT);
auto delta = gnc_numeric_sub_fixed (stock_amount, info->balance_at_date);
auto ratio = gnc_numeric_div (stock_amount, info->balance_at_date,
GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE);
auto stock_pinfo = gnc_commodity_print_info
(xaccAccountGetCommodity (info->acct), true);
stock_amount = gnc_numeric_sub_fixed (stock_amount, info->balance_at_date);
line.units = xaccPrintAmount (stock_amount, stock_pinfo);
if (gnc_numeric_check (ratio))
add_error_str (errors, N_("Invalid stock new balance"));
else if (gnc_numeric_negative_p (ratio))
add_error_str (errors, N_("New and old balance must have same signs"));
else if (gnc_numeric_negative_p (delta) && !credit_side)
add_error_str (errors, N_("New balance must be higher than old balance"));
else if (gnc_numeric_positive_p (delta) && credit_side)
add_error_str (errors, N_("New balance must be lower than old balance"));
}
else
{
auto stock_amount = gnc_amount_edit_get_amount
(GNC_AMOUNT_EDIT(info->stock_amount_edit));
@ -863,6 +924,17 @@ stock_assistant_prepare (GtkAssistant *assistant, GtkWidget *page,
case PAGE_STOCK_AMOUNT:
info->balance_at_date = xaccAccountGetBalanceAsOfDate
(info->acct, gnc_date_edit_get_date_end (GNC_DATE_EDIT (info->date_edit)));
gtk_label_set_text_with_mnemonic
(GTK_LABEL (info->stock_amount_label),
info->txn_type->input_new_balance ? _("Ne_w Balance") : _("_Shares"));
gtk_label_set_text
(GTK_LABEL (info->next_amount_label),
info->txn_type->input_new_balance ? _("Ratio") : _("Next Balance"));
gtk_label_set_text
(GTK_LABEL (info->stock_amount_title),
info->txn_type->input_new_balance ?
_("Enter the new balance of shares after the stock split.") :
_("Enter the number of shares you gained or lost in the transaction."));
refresh_page_stock_amount (info->stock_amount_edit, info);
// fixme: the following doesn't work???
gtk_widget_grab_focus (gnc_amount_edit_gtk_entry
@ -922,16 +994,15 @@ static void
create_split (Transaction *trans, FieldMask splitfield,
const gchar *action, Account *account,
AccountVec& account_commits, GtkWidget *memo_entry,
GtkWidget *amount, GtkWidget *value,
bool skip_if_zero)
gnc_numeric amount_numeric, gnc_numeric value_numeric,
bool skip_if_zero, StockTransactionInfo *info)
{
auto amount_numeric = amount ? gnc_amount_edit_get_amount (GNC_AMOUNT_EDIT (amount)) : gnc_numeric_zero ();
auto value_numeric = value ? gnc_amount_edit_get_amount (GNC_AMOUNT_EDIT (value)) : gnc_numeric_zero ();
if (skip_if_zero && gnc_numeric_zero_p (value_numeric))
return;
if (splitfield & FieldMask::ENABLED_CREDIT)
if (info->txn_type->input_new_balance)
amount_numeric = gnc_numeric_sub_fixed (amount_numeric, info->balance_at_date);
else if (splitfield & FieldMask::ENABLED_CREDIT)
{
amount_numeric = gnc_numeric_neg (amount_numeric);
value_numeric = gnc_numeric_neg (value_numeric);
@ -982,6 +1053,11 @@ add_price (GtkWidget *amount, GtkWidget *value,
gnc_price_unref (price);
}
static gnc_numeric gae_amount (GtkWidget *widget)
{
return gnc_amount_edit_get_amount (GNC_AMOUNT_EDIT (widget));
}
void
stock_assistant_finish (GtkAssistant *assistant, gpointer user_data)
{
@ -1001,52 +1077,61 @@ stock_assistant_finish (GtkAssistant *assistant, gpointer user_data)
auto date = gnc_date_edit_get_date (GNC_DATE_EDIT (info->date_edit));
xaccTransSetDatePostedSecsNormalized (trans, date);
auto stock_amount = info->txn_type->stock_amount != FieldMask::DISABLED ?
gae_amount (info->stock_amount_edit) : gnc_numeric_zero ();
auto stock_value = info->txn_type->stock_value != FieldMask::DISABLED ?
gae_amount (info->stock_value_edit) : gnc_numeric_zero ();
if (info->txn_type->input_new_balance)
stock_amount = gnc_numeric_sub_fixed (stock_amount, info->balance_at_date);
create_split (trans, info->txn_type->stock_amount | info->txn_type->stock_value,
NC_ ("Stock Assistant: Action field", "Stock"),
info->acct, account_commits, info->stock_memo_edit,
info->txn_type->stock_amount != FieldMask::DISABLED ? info->stock_amount_edit : nullptr,
info->txn_type->stock_value != FieldMask::DISABLED ? info->stock_value_edit : nullptr,
false);
stock_amount, stock_value, false, info);
if (info->txn_type->cash_value != FieldMask::DISABLED)
{
auto cash = gae_amount (info->cash_value);
create_split (trans, info->txn_type->cash_value,
NC_ ("Stock Assistant: Action field", "Cash"),
gas_account (info->cash_account),
account_commits, info->cash_memo_edit, info->cash_value,
info->cash_value, false);
gas_account (info->cash_account), account_commits,
info->cash_memo_edit, cash, cash, false, info);
}
if (info->txn_type->fees_value != FieldMask::DISABLED)
{
auto fees = gae_amount (info->fees_value);
auto capitalize = gtk_toggle_button_get_active
(GTK_TOGGLE_BUTTON (info->capitalize_fees_checkbox));
create_split (trans, info->txn_type->fees_value,
NC_ ("Stock Assistant: Action field", "Fees"),
capitalize ? info->acct : gas_account (info->fees_account),
account_commits, info->fees_memo_edit,
capitalize ? nullptr : info->fees_value,
info->fees_value, true);
capitalize ? gnc_numeric_zero () : fees, fees, true, info);
}
if (info->txn_type->dividend_value != FieldMask::DISABLED)
{
auto dividend = gae_amount (info->dividend_value);
create_split (trans, info->txn_type->dividend_value,
NC_ ("Stock Assistant: Action field", "Dividend"),
gas_account (info->dividend_account),
account_commits, info->dividend_memo_edit,
info->dividend_value, info->dividend_value, false);
gas_account (info->dividend_account), account_commits,
info->dividend_memo_edit, dividend, dividend, false, info);
}
if (info->txn_type->capgains_value != FieldMask::DISABLED)
{
auto capgains = gae_amount (info->capgains_value);
create_split (trans, info->txn_type->capgains_value,
NC_ ("Stock Assistant: Action field", "Capital Gain"),
gas_account (info->capgains_account),
account_commits, info->capgains_memo_edit,
info->capgains_value, info->capgains_value, false);
capgains, capgains, false, info);
create_split (trans,
info->txn_type->capgains_value ^ (FieldMask::ENABLED_CREDIT | FieldMask::ENABLED_DEBIT),
NC_ ("Stock Assistant: Action field", "Capital Gain"),
info->acct, account_commits, info->capgains_memo_edit,
nullptr, info->capgains_value, false);
gnc_numeric_zero (), capgains, false, info);
}
if (info->txn_type->stock_amount != FieldMask::DISABLED &&
@ -1206,9 +1291,12 @@ stock_assistant_create (StockTransactionInfo *info)
/* Stock Amount Page Widgets */
info->stock_amount_page = get_widget (builder, "stock_amount_page");
info->stock_amount_title = get_widget (builder, "stock_amount_title");
info->prev_amount = get_widget (builder, "prev_balance_amount");
info->stock_amount_label = get_widget (builder, "stock_amount_label");
info->stock_amount_edit = create_gae (builder, 1, xaccAccountGetCommodity (info->acct), "stock_amount_table", "stock_amount_label");
info->next_amount = get_widget (builder, "next_balance_amount");
info->next_amount_label = get_widget (builder, "next_balance_label");
g_signal_connect (info->stock_amount_edit, "changed",
G_CALLBACK (refresh_page_stock_amount), info);

Loading…
Cancel
Save