/* Either sets the value and amount for split and returns TRUE, or does nothing and returns FALSE. */ static gboolean gtu_sr_handle_exchange_rate (GncTreeViewSplitReg *view, gnc_numeric amount, Transaction *trans, Split *split, gboolean force) { GncTreeModelSplitReg *model; XferDialog *xfer; gboolean rate_split_ok, rate_reg_ok; gnc_numeric rate_split, rate_reg, value; Account *reg_acc; gnc_commodity *xfer_comm = xaccAccountGetCommodity (xaccSplitGetAccount (split)); gnc_commodity *reg_comm = gnc_tree_view_split_reg_get_reg_commodity (view); gnc_commodity *trans_curr = xaccTransGetCurrency (trans); gboolean expanded; gboolean have_rate = TRUE; ENTER("handle_exchange_rate amount %s, trans %p and split %p force %d", gnc_numeric_to_string (amount), trans, split, force); model = gnc_tree_view_split_reg_get_model_from_view (view); reg_acc = gnc_tree_model_split_reg_get_anchor (model); /* Rate from trans-curr to split-comm */ rate_split_ok = xaccTransGetRateForCommodity (trans, xfer_comm, split, &rate_split); DEBUG("rate_split_ok %d and xfer_comm %s", rate_split_ok, gnc_commodity_get_fullname (xfer_comm)); /* Rate from trans-curr to reg-comm */ rate_reg_ok = xaccTransGetRateForCommodity (trans, reg_comm, split, &rate_reg); DEBUG("rate_reg_ok %d and reg_comm %s", rate_reg_ok, gnc_commodity_get_fullname (reg_comm)); /* Are we expanded */ expanded = gnc_tree_view_split_reg_trans_expanded (view, trans); if (gnc_commodity_equal (trans_curr, xfer_comm) && rate_split_ok) { xaccSplitSetAmount (split, amount); xaccSplitSetValue (split, amount); return TRUE; } if (rate_reg_ok && rate_split_ok && !force) { value = gnc_numeric_div (amount, rate_reg, gnc_commodity_get_fraction (trans_curr), GNC_HOW_DENOM_REDUCE); amount = gnc_numeric_mul (value, rate_split, GNC_DENOM_AUTO, GNC_HOW_RND_ROUND); } else { if (!rate_split_ok) rate_split = gtu_sr_get_rate_from_db (reg_comm, xfer_comm); /* create the exchange-rate dialog */ xfer = gnc_xfer_dialog (NULL, NULL); gnc_xfer_dialog_is_exchange_dialog (xfer, &rate_split); /* fill in the dialog entries */ gnc_xfer_dialog_set_description (xfer, xaccTransGetDescription (trans)); gnc_xfer_dialog_set_memo (xfer, xaccSplitGetMemo (split)); /* Get per book option */ gnc_xfer_dialog_set_num (xfer, gnc_get_num_action (trans, split)); gnc_xfer_dialog_set_date (xfer, timespecToTime64 (xaccTransRetDatePostedTS (trans))); value = amount; if (gnc_xfer_dialog_run_exchange_dialog (xfer, &rate_split, value, reg_acc, trans, xfer_comm, expanded)) { if (!rate_split_ok) rate_split = gnc_numeric_create (1, 1); have_rate = FALSE; } else have_rate = TRUE; amount = gnc_numeric_mul (value, rate_split, GNC_DENOM_AUTO, GNC_HOW_RND_ROUND); } xaccSplitSetAmount (split, amount); xaccSplitSetValue (split, value); LEAVE("handle_exchange_rate set split %p amt=%s; and val=%s", split, gnc_numeric_to_string (amount), gnc_numeric_to_string (value)); return have_rate; }
void gnc_payment_ok_cb (GtkWidget *widget, gpointer data) { PaymentWindow *pw = data; const char *text = NULL; if (!pw) return; /* The gnc_payment_window_check_payment function * ensures we have valid owner, post account, transfer account * and amount so we can proceed with the payment. * Note: make sure it's called before all entry points to this function ! */ gnc_suspend_gui_refresh (); { const char *memo, *num; Timespec date; gnc_numeric exch = gnc_numeric_create(1, 1); //default to "one to one" rate GList *selected_lots = NULL; GtkTreeSelection *selection; gboolean auto_pay; /* Obtain all our ancillary information */ memo = gtk_entry_get_text (GTK_ENTRY (pw->memo_entry)); num = gtk_entry_get_text (GTK_ENTRY (pw->num_entry)); date = gnc_date_edit_get_date_ts (GNC_DATE_EDIT (pw->date_edit)); /* Obtain the list of selected lots (documents/payments) from the dialog */ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(pw->docs_list_tree_view)); gtk_tree_selection_selected_foreach (selection, get_selected_lots, &selected_lots); /* When the payment amount is 0, the selected documents cancel each other out * so no money is actually transferred. * For non-zero payments money will be transferred between the post account * and the transfer account. In that case if these two accounts don't have * the same currency the user is asked to enter the exchange rate. */ if (!gnc_numeric_zero_p (pw->amount_tot) && !gnc_commodity_equal(xaccAccountGetCommodity(pw->xfer_acct), xaccAccountGetCommodity(pw->post_acct))) { XferDialog* xfer; text = _("The transfer and post accounts are associated with different currencies. Please specify the conversion rate."); xfer = gnc_xfer_dialog(pw->dialog, pw->xfer_acct); gnc_info_dialog(pw->dialog, "%s", text); gnc_xfer_dialog_select_to_account(xfer, pw->post_acct); gnc_xfer_dialog_set_amount(xfer, pw->amount_tot); /* All we want is the exchange rate so prevent the user from thinking it makes sense to mess with other stuff */ gnc_xfer_dialog_set_from_show_button_active(xfer, FALSE); gnc_xfer_dialog_set_to_show_button_active(xfer, FALSE); gnc_xfer_dialog_hide_from_account_tree(xfer); gnc_xfer_dialog_hide_to_account_tree(xfer); gnc_xfer_dialog_is_exchange_dialog(xfer, &exch); gnc_xfer_dialog_run_until_done(xfer); } /* Perform the payment */ if (gncOwnerGetType (&(pw->owner)) == GNC_OWNER_CUSTOMER) auto_pay = gnc_prefs_get_bool (GNC_PREFS_GROUP_INVOICE, GNC_PREF_AUTO_PAY); else auto_pay = gnc_prefs_get_bool (GNC_PREFS_GROUP_BILL, GNC_PREF_AUTO_PAY); gncOwnerApplyPayment (&pw->owner, pw->pre_existing_txn, selected_lots, pw->post_acct, pw->xfer_acct, pw->amount_tot, exch, date, memo, num, auto_pay); } gnc_resume_gui_refresh (); /* Save the transfer account, xfer_acct */ gnc_payment_dialog_remember_account(pw, pw->xfer_acct); gnc_ui_payment_window_destroy (pw); }