Factor out and create new function: gnc_xfer_dialog_run_exchange_dialog()

This isolates the amount-to-value conversion algorithm from the register.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@13576 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Chris Shoemaker 2006-03-10 04:23:48 +00:00
parent 3b3075dc8b
commit bb93d652e2
3 changed files with 100 additions and 66 deletions

View File

@ -1198,7 +1198,8 @@ gnc_xfer_dialog_hide_to_account_tree(XferDialog *xferData)
* Return: none * * Return: none *
\********************************************************************/ \********************************************************************/
void void
gnc_xfer_dialog_is_exchange_dialog (XferDialog *xferData, gnc_numeric *exch_rate) gnc_xfer_dialog_is_exchange_dialog (XferDialog *xferData,
gnc_numeric *exch_rate)
{ {
GNCAmountEdit *gae; GNCAmountEdit *gae;
@ -1233,9 +1234,11 @@ gnc_xfer_dialog_set_amount(XferDialog *xferData, gnc_numeric amount)
if (xferData == NULL) if (xferData == NULL)
return; return;
account = gnc_transfer_dialog_get_selected_account (xferData, XFER_DIALOG_FROM); account = gnc_transfer_dialog_get_selected_account (xferData,
XFER_DIALOG_FROM);
if (account == NULL) if (account == NULL)
account = gnc_transfer_dialog_get_selected_account (xferData, XFER_DIALOG_TO); account = gnc_transfer_dialog_get_selected_account (xferData,
XFER_DIALOG_TO);
gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT (xferData->amount_edit), amount); gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT (xferData->amount_edit), amount);
} }
@ -2159,3 +2162,81 @@ void gnc_xfer_dialog_set_txn_cb(XferDialog *xferData,
xferData->transaction_cb = handler; xferData->transaction_cb = handler;
xferData->transaction_user_data = user_data; xferData->transaction_user_data = user_data;
} }
gboolean gnc_xfer_dialog_run_exchange_dialog(
XferDialog *xfer, gnc_numeric *exch_rate, gnc_numeric amount,
Account *reg_acc, Transaction *txn, gnc_commodity *xfer_com)
{
gboolean swap_amounts = FALSE;
gnc_commodity *txn_cur = xaccTransGetCurrency(txn);
gnc_commodity *reg_com = xaccAccountGetCommodity(reg_acc);
/* We know that "amount" is always in the reg_com currency.
* Unfortunately it is possible that neither xfer_com or txn_cur are
* the same as reg_com, in which case we need to convert to the txn
* currency... Or, if the register commodity is the xfer_com, then we
* need to flip-flop the commodities and the exchange rates.
*/
if (gnc_commodity_equal(reg_com, txn_cur)) {
/* we're working in the txn currency. Great. Nothing to do! */
swap_amounts = FALSE;
} else if (gnc_commodity_equal(reg_com, xfer_com)) {
/* We're working in the xfer commodity. Great. Just swap the
amounts. */
swap_amounts = TRUE;
/* XXX: Do we need to check for expanded v. non-expanded
accounts here? */
} else {
/* UGGH -- we're not in either. That means we need to convert
* 'amount' from the register commodity to the txn currency.
*/
gnc_numeric rate = xaccTransGetAccountConvRate(txn, reg_acc);
/* XXX: should we tell the user we've done the conversion? */
amount = gnc_numeric_div(
amount, rate,
gnc_commodity_get_fraction(txn_cur), GNC_DENOM_REDUCE);
}
/* enter the accounts */
if (swap_amounts) {
gnc_xfer_dialog_select_to_currency(xfer, txn_cur);
gnc_xfer_dialog_select_from_currency(xfer, xfer_com);
if (!gnc_numeric_zero_p(*exch_rate))
*exch_rate = gnc_numeric_div(gnc_numeric_create(1, 1), *exch_rate,
GNC_DENOM_AUTO, GNC_DENOM_REDUCE);
} else {
gnc_xfer_dialog_select_to_currency(xfer, xfer_com);
gnc_xfer_dialog_select_from_currency(xfer, txn_cur);
}
gnc_xfer_dialog_hide_to_account_tree(xfer);
gnc_xfer_dialog_hide_from_account_tree(xfer);
gnc_xfer_dialog_set_amount(xfer, amount);
/*
* When we flip, we should tell the dialog so it can deal with the
* pricedb properly.
*/
/* Set the exchange rate */
gnc_xfer_dialog_set_exchange_rate(xfer, *exch_rate);
/* and run it... */
if (gnc_xfer_dialog_run_until_done(xfer) == FALSE)
return TRUE;
/* If we swapped the amounts for the dialog, then make sure we swap
* it back now...
*/
if (swap_amounts)
*exch_rate = gnc_numeric_div(gnc_numeric_create(1, 1), *exch_rate,
GNC_DENOM_AUTO, GNC_DENOM_REDUCE);
return FALSE;
}

View File

@ -198,6 +198,19 @@ void gnc_xfer_dialog_set_txn_cb(XferDialog *xferData,
gnc_xfer_dialog_cb handler, gnc_xfer_dialog_cb handler,
gpointer user_data); gpointer user_data);
/* Uses the XferDialog to obtain from the user an explicit exchange
rate. This exchange rate will then be uses to converting 'amount',
which is given in the commodity of the register Account, reg_acc,
into a split value for a split whose Account is the commodity
specified by xfer_com.
The 'exch_rate' argument is used to set the initial value of the
rate. If the dialog completes sucessfully 'FALSE' is returned and
'exch_rate' is also used to store the converted value. Otherwise,
TRUE is returned and the 'exch_rate' argument is undefined.
*/
gboolean gnc_xfer_dialog_run_exchange_dialog(
XferDialog *xfer, gnc_numeric *exch_rate, gnc_numeric amount,
Account *reg_acc, Transaction *txn, gnc_commodity *xfer_com);
#endif #endif

View File

@ -1008,7 +1008,6 @@ gnc_split_register_handle_exchange (SplitRegister *reg, gboolean force_dialog)
gnc_commodity *txn_cur, *xfer_com, *reg_com; gnc_commodity *txn_cur, *xfer_com, *reg_com;
gnc_numeric amount, exch_rate; gnc_numeric amount, exch_rate;
XferDialog *xfer; XferDialog *xfer;
gboolean swap_amounts = FALSE;
gboolean expanded = FALSE; gboolean expanded = FALSE;
PriceCell *rate_cell; PriceCell *rate_cell;
const char *message; const char *message;
@ -1145,68 +1144,9 @@ gnc_split_register_handle_exchange (SplitRegister *reg, gboolean force_dialog)
xfer, timespecToTime_t( xfer, timespecToTime_t(
gnc_split_register_get_cell_date(reg, DATE_CELL))); gnc_split_register_get_cell_date(reg, DATE_CELL)));
/* We know that "amount" is always in the reg_com currency. if (gnc_xfer_dialog_run_exchange_dialog(
* Unfortunately it is possible that neither xfer_com or txn_cur are xfer, &exch_rate, amount, reg_acc, txn, xfer_com))
* the same as reg_com, in which case we need to convert to the txn return TRUE;
* currency... Or, if the register commodity is the xfer_com, then we
* need to flip-flop the commodities and the exchange rates.
*/
if (gnc_commodity_equal (reg_com, txn_cur)) {
/* we're working in the txn currency. Great. Nothing to do! */
swap_amounts = FALSE;
} else if (gnc_commodity_equal (reg_com, xfer_com)) {
/* We're working in the xfer commodity. Great. Just swap the amounts. */
swap_amounts = TRUE;
/* XXX: Do we need to check for expanded v. non-expanded accounts here? */
} else {
/* UGGH -- we're not in either. That means we need to convert 'amount'
* from the register commodity to the txn currency.
*/
gnc_numeric rate = xaccTransGetAccountConvRate(txn, reg_acc);
/* XXX: should we tell the user we've done the conversion? */
amount = gnc_numeric_div(
amount, rate, gnc_commodity_get_fraction (txn_cur), GNC_DENOM_REDUCE);
}
/* enter the accounts */
if (swap_amounts) {
gnc_xfer_dialog_select_to_currency (xfer, txn_cur);
gnc_xfer_dialog_select_from_currency (xfer, xfer_com);
if (!gnc_numeric_zero_p (exch_rate))
exch_rate = gnc_numeric_div (gnc_numeric_create (1, 1), exch_rate,
GNC_DENOM_AUTO, GNC_DENOM_REDUCE);
} else {
gnc_xfer_dialog_select_to_currency (xfer, xfer_com);
gnc_xfer_dialog_select_from_currency (xfer, txn_cur);
}
gnc_xfer_dialog_hide_to_account_tree (xfer);
gnc_xfer_dialog_hide_from_account_tree (xfer);
gnc_xfer_dialog_set_amount (xfer, amount);
/*
* When we flip, we should tell the dialog so it can deal with the
* pricedb properly.
*/
/* Set the exchange rate */
gnc_xfer_dialog_set_exchange_rate (xfer, exch_rate);
/* and run it... */
if (gnc_xfer_dialog_run_until_done (xfer) == FALSE)
return TRUE;
/* If we swapped the amounts for the dialog, then make sure we swap
* it back now...
*/
if (swap_amounts)
exch_rate = gnc_numeric_div (gnc_numeric_create (1, 1), exch_rate,
GNC_DENOM_AUTO, GNC_DENOM_REDUCE);
/* Set the RATE_CELL on this cursor and mark it changed */ /* Set the RATE_CELL on this cursor and mark it changed */
gnc_price_cell_set_value (rate_cell, exch_rate); gnc_price_cell_set_value (rate_cell, exch_rate);