Extract function lookup_price in dialog_transfer.c

This commit is contained in:
John Ralls 2015-09-03 11:22:51 -07:00
parent 76c1259f1b
commit ab15ca8f84

View File

@ -215,16 +215,87 @@ round_price(gnc_commodity *from, gnc_commodity *to, gnc_numeric value)
return value;
}
typedef struct
{
GNCPrice *price;
GNCPriceDB *pricedb;
gnc_commodity *from;
gnc_commodity *to;
Timespec ts;
gboolean reverse;
} PriceReq;
static void
price_request_from_xferData(PriceReq *pr, XferDialog *xd)
{
g_return_if_fail (pr != NULL);
g_return_if_fail (xd != NULL);
pr->price = NULL;
pr->pricedb = xd->pricedb;
pr->from = xd->from_commodity;
pr->to = xd->to_commodity;
pr->ts = gnc_date_edit_get_date_ts (GNC_DATE_EDIT (xd->date_entry));
pr->reverse = FALSE;
}
static gboolean
lookup_price(PriceReq *pr, gboolean day_only)
{
GNCPrice *prc = NULL;
g_return_val_if_fail (pr != NULL, FALSE);
g_return_val_if_fail (pr->pricedb != NULL, FALSE);
g_return_val_if_fail (pr->from != NULL, FALSE);
g_return_val_if_fail (pr->to != NULL, FALSE);
pr->reverse = FALSE;
if (day_only)
{
prc = gnc_pricedb_lookup_day (pr->pricedb, pr->from, pr->to, pr->ts);
if (!prc)
{
prc = gnc_pricedb_lookup_day (pr->pricedb, pr->to,
pr->from, pr->ts);
pr->reverse = TRUE;
}
}
else
{
prc = gnc_pricedb_lookup_nearest_in_time (pr->pricedb, pr->from,
pr->to, pr->ts);
if (!prc)
{
prc = gnc_pricedb_lookup_nearest_in_time (pr->pricedb, pr->to,
pr->from, pr->ts);
pr->reverse = TRUE;
}
}
if (pr->reverse)
{
PINFO("Found reverse price: 1 %s = %f %s",
gnc_commodity_get_mnemonic(pr->to),
gnc_numeric_to_double(gnc_price_get_value(prc)),
gnc_commodity_get_mnemonic(pr->from));
}
else
{
PINFO("Found price: 1 %s = %f %s",
gnc_commodity_get_mnemonic(pr->from),
gnc_numeric_to_double(gnc_price_get_value(prc)),
gnc_commodity_get_mnemonic(pr->to));
}
if (!prc)
return FALSE;
pr->price = prc;
return TRUE;
}
/* (maybe) update the price from the pricedb. */
static void
gnc_xfer_dialog_update_price (XferDialog *xferData)
{
GNCPrice *prc;
PriceReq pr;
gnc_numeric price_value;
Timespec date;
gnc_commodity *from = xferData->from_commodity;
gnc_commodity *to = xferData->to_commodity;
gboolean reverse;
if (!xferData) return;
if (!xferData->from_commodity || ! xferData->to_commodity) return;
@ -232,56 +303,19 @@ gnc_xfer_dialog_update_price (XferDialog *xferData)
return;
if (!xferData->pricedb) return;
/* when do we update, and when do we NOT update? */
/* XXX: I'm ALWAYS going to update whenever we get called */
/* grab the price on the same day or nearest to the DATE out of the pricedb */
date = gnc_date_edit_get_date_ts (GNC_DATE_EDIT (xferData->date_entry));
/* Look for a price on the same day or, failing that, closest in time. */
prc = gnc_pricedb_lookup_day (xferData->pricedb, from, to, date);
reverse = FALSE;
if (!prc)
{
/* Look for reverse price on same day */
prc = gnc_pricedb_lookup_day (xferData->pricedb, to, from, date);
reverse = TRUE;
}
if (!prc)
{
/* Didn't find one on the same day, look for nearest in time */
prc = gnc_pricedb_lookup_nearest_in_time (xferData->pricedb, from,
to, date);
reverse = FALSE;
}
if (!prc)
{
prc = gnc_pricedb_lookup_nearest_in_time (xferData->pricedb, to,
from, date);
reverse = TRUE;
}
if (!prc)
price_request_from_xferData(&pr, xferData);
if (!lookup_price(&pr, TRUE))
if (!lookup_price(&pr, FALSE))
return;
/* grab the price from the pricedb */
price_value = gnc_price_get_value (prc);
if (reverse)
price_value = gnc_price_get_value (pr.price);
if (pr.reverse)
{
PINFO("Found reverse price: 1 %s = %f %s", gnc_commodity_get_mnemonic(to),
gnc_numeric_to_double(price_value), gnc_commodity_get_mnemonic(from));
price_value = gnc_numeric_invert (price_value);
price_value = round_price(from, to, price_value);
}
else
{
PINFO("Found price: 1 %s = %f %s", gnc_commodity_get_mnemonic(from),
gnc_numeric_to_double(price_value), gnc_commodity_get_mnemonic(to));
price_value = round_price(pr.from, pr.to, price_value);
}
gnc_price_unref(pr.price);
/* and set the price entry */
gnc_xfer_dialog_set_price_edit(xferData, price_value);
@ -1542,9 +1576,10 @@ swap_commodities(gnc_commodity **from, gnc_commodity **to, gnc_numeric value)
static void
create_price(XferDialog *xferData, Timespec ts)
{
PriceReq pr;
GNCPrice *price = NULL;
gnc_commodity *from = xferData->from_commodity;
gnc_commodity *to = xferData->to_commodity;
GNCPrice *price;
gnc_numeric price_value;
gnc_numeric value;
gnc_numeric from_amt, to_amt;
@ -1561,52 +1596,49 @@ create_price(XferDialog *xferData, Timespec ts)
(strcmp (gnc_commodity_get_mnemonic(from),
gnc_commodity_get_mnemonic(to)) < 0)))
swap_amount (&from, &to, &value, &from_amt, &to_amt);
/* First see if the closest entry on the same day has an equivalent rate */
price = gnc_pricedb_lookup_day (xferData->pricedb, from, to, ts);
if (!price)
{
price = gnc_pricedb_lookup_day (xferData->pricedb, to, from, ts);
if (price)
swap = TRUE;
}
/* Normally we want to store currency rates such that the rate > 1 and commodity
* prices in terms of a currency regardless of value. However, if we already
* have a price in either direction we want to continue using that direction for
* the rest of the day so that we don't wind up with two prices if the rate
* shifts to be < 1. */
if (price)
price_request_from_xferData(&pr, xferData);
if (lookup_price(&pr, TRUE))
{
price_value = gnc_price_get_value(price);
if (gnc_numeric_equal(swap ? gnc_numeric_invert(value) : value,
price_value = gnc_price_get_value(pr.price);
if (gnc_numeric_equal(pr.reverse ? gnc_numeric_invert(value) : value,
price_value))
{
PINFO("Found price for %s in %s", gnc_commodity_get_mnemonic(from),
gnc_commodity_get_mnemonic(to));
gnc_price_unref (price);
PINFO("Found price for %s in %s",
gnc_commodity_get_mnemonic(pr.from),
gnc_commodity_get_mnemonic(pr.to));
gnc_price_unref (pr.price);
return;
}
if (strcmp (gnc_price_get_source(price), PRICE_SOURCE_FQ) == 0)
if (strcmp (gnc_price_get_source(pr.price), PRICE_SOURCE_FQ) == 0)
{
PINFO("Existing price is from Finance::Quote, so won't supersede.");
gnc_price_unref (price);
gnc_price_unref (pr.price);
return;
}
if (swap)
if (pr.reverse)
{
value = swap_commodities(&from, &to, value);
xferData->from_commodity = from;
xferData->to_commodity = to;
}
value = round_price(from, to, value);
gnc_price_begin_edit (price);
gnc_price_set_time (price, ts);
gnc_price_set_source (price, PRICE_SOURCE_XFER_DLG);
gnc_price_set_value (price, value);
gnc_price_commit_edit (price);
PINFO("Modified price: 1 %s = %f %s", gnc_commodity_get_mnemonic(from),
gnc_numeric_to_double(value), gnc_commodity_get_mnemonic(to));
gnc_price_unref (price);
value = round_price(pr.from, pr.to, value);
gnc_price_begin_edit (pr.price);
gnc_price_set_time (pr.price, ts);
gnc_price_set_source (pr.price, PRICE_SOURCE_XFER_DLG);
gnc_price_set_value (pr.price, value);
gnc_price_commit_edit (pr.price);
PINFO("Modified price: 1 %s = %f %s",
gnc_commodity_get_mnemonic(from),
gnc_numeric_to_double(value),
gnc_commodity_get_mnemonic(to));
gnc_price_unref (pr.price);
return;
}
if (gnc_commodity_is_currency(from) && gnc_commodity_is_currency(to))