static void gnc_split_register_save_cells (gpointer save_data, gpointer user_data) { SRSaveData *sd = save_data; SplitRegister *reg = user_data; Split *other_split; gnc_commodity *txn_cur; gnc_numeric rate = gnc_numeric_zero(); g_return_if_fail (sd != NULL); if (!sd->do_scrub) return; other_split = xaccSplitGetOtherSplit (sd->split); txn_cur = xaccTransGetCurrency (sd->trans); xaccSplitScrub (sd->split); rate = gnc_split_register_get_rate_cell (reg, RATE_CELL); if (other_split && !sd->reg_expanded) { gnc_numeric amount, value = xaccSplitGetValue (sd->split); Account *acc; gboolean split_needs_amount; split_needs_amount = gnc_split_register_split_needs_amount(reg, sd->split); /* We are changing the rate on the current split, but it was not * handled in the debcred handler, so we need to do it here. */ if (!sd->handled_dc && split_needs_amount && !gnc_numeric_zero_p (rate)) { gnc_numeric amount = xaccSplitGetAmount (sd->split); value = gnc_numeric_div( amount, rate, gnc_commodity_get_fraction(txn_cur), GNC_HOW_RND_ROUND_HALF_UP); xaccSplitSetValue (sd->split, value); /* XXX: do we need to set the amount on the other split? */ } /* Now reverse the value for the other split */ value = gnc_numeric_neg (value); if (gnc_split_register_split_needs_amount (reg, other_split)) { acc = xaccSplitGetAccount (other_split); /* If we don't have an exchange rate then figure it out. Or, if * BOTH splits require an amount, then most likely we're in the * strange case of having a transaction currency different than * _both_ accounts -- so grab the other exchange rate. */ if (gnc_numeric_zero_p (rate) || split_needs_amount) rate = xaccTransGetAccountConvRate(xaccSplitGetParent (other_split), acc); amount = gnc_numeric_mul (value, rate, xaccAccountGetCommoditySCU (acc), GNC_HOW_RND_ROUND_HALF_UP); xaccSplitSetAmount (other_split, amount); } xaccSplitSetValue (other_split, value); xaccSplitScrub (other_split); } else if (gnc_split_register_split_needs_amount (reg, sd->split) && ! gnc_numeric_zero_p (rate)) { /* this is either a multi-split or expanded transaction, so only * deal with this split... In particular we need to reset the * Value if the conv-rate changed. * * If we handled the debcred then no need to do anything there -- * the debcred handler did all the computation. If NOT, then the * convrate changed -- reset the value from the amount. */ if (!sd->handled_dc) { gnc_split_register_save_amount_values (sd, reg); #if 0 gnc_numeric value, amount; amount = xaccSplitGetAmount (sd->split); value = gnc_numeric_div (amount, rate, gnc_commodity_get_fraction (txn_cur), GNC_HOW_RND_ROUND_HALF_UP); xaccSplitSetValue (sd->split, value); #endif } } }
void gnc_tree_util_split_reg_save_amount_values (GncTreeViewSplitReg *view, Transaction *trans, Split *split, gnc_numeric input) { GncTreeModelSplitReg *model; Account *acc; gnc_numeric new_amount, convrate, amtconv, value; gnc_commodity *curr, *reg_com, *xfer_com; Account *xfer_acc; ENTER("View is %p, trans is %p, split is %p, input is %s", view, trans, split, gnc_numeric_to_string (input)); model = gnc_tree_view_split_reg_get_model_from_view (view); new_amount = input; acc = gnc_tree_model_split_reg_get_anchor (model); xfer_acc = xaccSplitGetAccount (split); xfer_com = xaccAccountGetCommodity (xfer_acc); reg_com = xaccAccountGetCommodity (acc); curr = xaccTransGetCurrency (trans); if (!xaccTransGetRateForCommodity (trans, reg_com, NULL, &convrate)) convrate = gnc_numeric_create (100, 100); amtconv = convrate; if (gnc_tree_util_split_reg_needs_conv_rate (view, trans, acc)) { /* If we are in an expanded register and the xfer_acc->comm != * reg_acc->comm then we need to compute the convrate here. * Otherwise, we _can_ use the rate_cell! */ if (gnc_commodity_equal (reg_com, xfer_com)) amtconv = xaccTransGetAccountConvRate (trans, acc); } if (xaccTransUseTradingAccounts (trans)) { /* Using currency accounts, the amount is probably really the amount and not the value. */ gboolean is_amount; if (model->type == STOCK_REGISTER2 || model->type == CURRENCY_REGISTER2 || model->type == PORTFOLIO_LEDGER2) { if (xaccAccountIsPriced (xfer_acc) || !gnc_commodity_is_iso (xaccAccountGetCommodity (xfer_acc))) is_amount = FALSE; else is_amount = TRUE; } else { is_amount = TRUE; } if (is_amount) { xaccSplitSetAmount (split, new_amount); if (gnc_tree_util_split_reg_needs_amount (view, split)) { value = gnc_numeric_div (new_amount, amtconv, gnc_commodity_get_fraction (curr), GNC_HOW_RND_ROUND_HALF_UP); xaccSplitSetValue (split, value); } else xaccSplitSetValue (split, new_amount); } else { xaccSplitSetValue (split, new_amount); } LEAVE(" "); return; } /* How to interpret new_amount depends on our view of this * transaction. If we're sitting in an account with the same * commodity as the transaction, then we can set the Value and then * compute the amount. Otherwise we are setting the "converted * value". This means we need to convert new_amount to the actual * 'value' by dividing by the convrate in order to set the value. */ /* Now compute/set the split value. Amount is in the register * currency but we need to convert to the txn currency. */ if (gnc_tree_util_split_reg_needs_conv_rate (view, trans, acc)) { /* convert the amount to the Value ... */ value = gnc_numeric_div (new_amount, amtconv, gnc_commodity_get_fraction (curr), GNC_HOW_RND_ROUND_HALF_UP); xaccSplitSetValue (split, value); } else { xaccSplitSetValue (split, new_amount); } /* Now re-compute the Amount from the Value. We may need to convert * from the Value back to the amount here using the convrate from * earlier. */ value = xaccSplitGetValue (split); if (gnc_tree_util_split_reg_needs_amount (view, split)) { acc = xaccSplitGetAccount (split); new_amount = gnc_numeric_mul (value, convrate, xaccAccountGetCommoditySCU (acc), GNC_HOW_RND_ROUND_HALF_UP); xaccSplitSetAmount (split, new_amount); } else { xaccSplitSetAmount (split, value); } LEAVE(" "); }
static void gnc_split_register_save_amount_values (SRSaveData *sd, SplitRegister *reg) { Account *acc; gnc_numeric new_amount, convrate, amtconv, value; gnc_commodity *curr, *reg_com, *xfer_com; Account *xfer_acc; new_amount = gnc_split_register_debcred_cell_value (reg); acc = gnc_split_register_get_default_account (reg); xfer_acc = xaccSplitGetAccount (sd->split); xfer_com = xaccAccountGetCommodity (xfer_acc); reg_com = xaccAccountGetCommodity (acc); curr = xaccTransGetCurrency (sd->trans); /* First, compute the conversion rate to convert the value to the * amount. */ amtconv = convrate = gnc_split_register_get_rate_cell (reg, RATE_CELL); if (acc && gnc_split_register_needs_conv_rate (reg, sd->trans, acc)) { /* If we are in an expanded register and the xfer_acc->comm != * reg_acc->comm then we need to compute the convrate here. * Otherwise, we _can_ use the rate_cell! */ if (sd->reg_expanded && ! gnc_commodity_equal (reg_com, xfer_com)) amtconv = xaccTransGetAccountConvRate(sd->trans, acc); } if (xaccTransUseTradingAccounts (sd->trans)) { /* Using currency accounts, the amount is probably really the amount and not the value. */ gboolean is_amount; if (reg->type == STOCK_REGISTER || reg->type == CURRENCY_REGISTER || reg->type == PORTFOLIO_LEDGER) { if (xaccAccountIsPriced(xfer_acc) || !gnc_commodity_is_iso(xaccAccountGetCommodity(xfer_acc))) is_amount = FALSE; else is_amount = TRUE; } else { is_amount = TRUE; } if (is_amount) { xaccSplitSetAmount(sd->split, new_amount); if (gnc_split_register_split_needs_amount (reg, sd->split)) { value = gnc_numeric_div(new_amount, amtconv, gnc_commodity_get_fraction(curr), GNC_HOW_RND_ROUND_HALF_UP); xaccSplitSetValue(sd->split, value); } else xaccSplitSetValue(sd->split, new_amount); } else { xaccSplitSetValue(sd->split, new_amount); } return; } /* How to interpret new_amount depends on our view of this * transaction. If we're sitting in an account with the same * commodity as the transaction, then we can set the Value and then * compute the amount. Otherwise we are setting the "converted * value". This means we need to convert new_amount to the actual * 'value' by dividing by the convrate in order to set the value. */ /* Now compute/set the split value. Amount is in the register * currency but we need to convert to the txn currency. */ if (gnc_split_register_needs_conv_rate (reg, sd->trans, acc)) { /* convert the amount to the Value ... */ value = gnc_numeric_div (new_amount, amtconv, gnc_commodity_get_fraction (curr), GNC_HOW_RND_ROUND_HALF_UP); xaccSplitSetValue (sd->split, value); } else xaccSplitSetValue (sd->split, new_amount); /* Now re-compute the Amount from the Value. We may need to convert * from the Value back to the amount here using the convrate from * earlier. */ value = xaccSplitGetValue (sd->split); if (gnc_split_register_split_needs_amount (reg, sd->split)) { acc = xaccSplitGetAccount (sd->split); new_amount = gnc_numeric_mul (value, convrate, xaccAccountGetCommoditySCU (acc), GNC_HOW_RND_ROUND_HALF_UP); xaccSplitSetAmount (sd->split, new_amount); } }
gboolean gnc_tree_util_split_reg_get_debcred_entry (GncTreeViewSplitReg *view, Transaction *trans, Split *split, gboolean is_blank, gnc_numeric *ret_num, GNCPrintAmountInfo *ret_print_info) { GncTreeModelSplitReg *model; gnc_commodity *currency; model = gnc_tree_view_split_reg_get_model_from_view (view); currency = xaccTransGetCurrency (trans); if (!currency) currency = gnc_default_currency (); if (is_blank) { gnc_numeric imbalance; Account *acc; imbalance = xaccTransGetImbalanceValue (trans); if (gnc_numeric_zero_p (imbalance)) return FALSE; if (xaccTransUseTradingAccounts (trans)) { MonetaryList *imbal_list; gnc_monetary *imbal_mon; imbal_list = xaccTransGetImbalance (trans); if (!imbal_list) { /* No commodity imbalance, there shouldn't be a value imablance. */ return FALSE; } if (imbal_list->next) { /* Multiple currency imbalance. */ gnc_monetary_list_free (imbal_list); return FALSE; } imbal_mon = imbal_list->data; if (!gnc_commodity_equal (gnc_monetary_commodity (*imbal_mon), currency)) { /* Imbalance is in wrong currency */ gnc_monetary_list_free (imbal_list); return FALSE; } if (!gnc_numeric_equal (gnc_monetary_value (*imbal_mon), imbalance)) { /* Value and commodity imbalances differ */ gnc_monetary_list_free (imbal_list); return FALSE; } /* Done with the imbalance list */ gnc_monetary_list_free (imbal_list); } imbalance = gnc_numeric_neg (imbalance); acc = gnc_tree_model_split_reg_get_anchor (model); if (gnc_tree_util_split_reg_needs_conv_rate (view, trans, acc)) { imbalance = gnc_numeric_mul (imbalance, xaccTransGetAccountConvRate (trans, acc), gnc_commodity_get_fraction (currency), GNC_HOW_RND_ROUND_HALF_UP); } else { imbalance = gnc_numeric_convert (imbalance, gnc_commodity_get_fraction (currency), GNC_HOW_RND_ROUND_HALF_UP); } *ret_num = imbalance; *ret_print_info = gnc_account_print_info (acc, FALSE); return TRUE; } { gnc_numeric amount; gnc_commodity *split_commodity; GNCPrintAmountInfo print_info; Account *account; gnc_commodity *commodity; account = gnc_tree_model_split_reg_get_anchor (model); commodity = xaccAccountGetCommodity (account); split_commodity = xaccAccountGetCommodity (xaccSplitGetAccount (split)); if (xaccTransUseTradingAccounts (trans)) { gboolean use_symbol, is_current = FALSE; Split *current_split = gnc_tree_view_split_reg_get_current_split (view); RowDepth depth = gnc_tree_view_reg_get_selected_row_depth (view); if ((split == current_split) && (depth == SPLIT3)) is_current = TRUE; if (model->type == STOCK_REGISTER2 || model->type == CURRENCY_REGISTER2 || model->type == PORTFOLIO_LEDGER2) { gnc_commodity *amount_commodity; /* security register. If this split has price and shares columns, use the value, otherwise use the amount. */ if (gtu_sr_use_security (view)) { amount = xaccSplitGetValue (split); amount_commodity = currency; } else { amount = xaccSplitGetAmount (split); amount_commodity = split_commodity; } /* Show the currency if it is not the default currency */ if (is_current || gnc_commodity_equiv (amount_commodity, gnc_default_currency ())) use_symbol = FALSE; else use_symbol = TRUE; print_info = gnc_commodity_print_info (amount_commodity, use_symbol); } else { /* non-security register, always use the split amount. */ amount = xaccSplitGetAmount (split); if (is_current || gnc_commodity_equiv (split_commodity, commodity)) use_symbol = FALSE; else use_symbol = TRUE; print_info = gnc_commodity_print_info (split_commodity, use_symbol); } } else { /* If this account is not a stock/mutual/currency account, and * currency != the account commodity, then use the SplitAmount * instead of the SplitValue. */ switch (model->type) { case STOCK_REGISTER2: case CURRENCY_REGISTER2: case PORTFOLIO_LEDGER2: amount = xaccSplitGetValue (split); print_info = gnc_commodity_print_info (currency, FALSE); break; default: if (commodity && !gnc_commodity_equal (commodity, currency)) /* Convert this to the "local" value */ amount = xaccSplitConvertAmount (split, account); else amount = xaccSplitGetValue (split); print_info = gnc_account_print_info (account, FALSE); break; } } if (gnc_numeric_zero_p (amount)) return FALSE; *ret_num = amount; *ret_print_info = print_info; return TRUE; } }