mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Add retrieval functions for price before the date given
Add a new function, gnc_pricedb_convert_balance_nearest_before_price_t64 that retrieves the balance using the last price dated before a specified date like today for the preset value. This uses another new function gnc_pricedb_get_nearest_before_price to do the retrieval.
This commit is contained in:
@@ -3623,7 +3623,7 @@ xaccAccountConvertBalanceToCurrencyAsOfDate(const Account *acc, /* for book */
|
||||
book = gnc_account_get_book (acc);
|
||||
pdb = gnc_pricedb_get_db (book);
|
||||
|
||||
balance = gnc_pricedb_convert_balance_nearest_price_t64(
|
||||
balance = gnc_pricedb_convert_balance_nearest_before_price_t64 (
|
||||
pdb, balance, balance_currency, new_currency, date);
|
||||
|
||||
return balance;
|
||||
|
||||
@@ -2516,7 +2516,7 @@ convert_price (const gnc_commodity *from, const gnc_commodity *to, PriceTuple tu
|
||||
|
||||
static gnc_numeric
|
||||
indirect_price_conversion (GNCPriceDB *db, const gnc_commodity *from,
|
||||
const gnc_commodity *to, time64 t)
|
||||
const gnc_commodity *to, time64 t, gboolean before_date)
|
||||
{
|
||||
GList *from_prices = NULL, *to_prices = NULL;
|
||||
PriceTuple tuple;
|
||||
@@ -2531,6 +2531,12 @@ indirect_price_conversion (GNCPriceDB *db, const gnc_commodity *from,
|
||||
if (from_prices)
|
||||
to_prices = gnc_pricedb_lookup_latest_any_currency(db, to);
|
||||
}
|
||||
else if (before_date)
|
||||
{
|
||||
from_prices = gnc_pricedb_lookup_latest_before_any_currency_t64 (db, from, t);
|
||||
if (from_prices)
|
||||
to_prices = gnc_pricedb_lookup_latest_before_any_currency_t64 (db, to, t);
|
||||
}
|
||||
else
|
||||
{
|
||||
from_prices = gnc_pricedb_lookup_nearest_in_time_any_currency_t64 (db, from, t);
|
||||
@@ -2550,7 +2556,7 @@ indirect_price_conversion (GNCPriceDB *db, const gnc_commodity *from,
|
||||
|
||||
static gnc_numeric
|
||||
direct_price_conversion (GNCPriceDB *db, const gnc_commodity *from,
|
||||
const gnc_commodity *to, time64 t)
|
||||
const gnc_commodity *to, time64 t, gboolean before_date)
|
||||
{
|
||||
GNCPrice *price;
|
||||
gnc_numeric retval = gnc_numeric_zero();
|
||||
@@ -2559,6 +2565,8 @@ direct_price_conversion (GNCPriceDB *db, const gnc_commodity *from,
|
||||
|
||||
if (t == INT64_MAX)
|
||||
price = gnc_pricedb_lookup_latest(db, from, to);
|
||||
else if (before_date)
|
||||
price = gnc_pricedb_lookup_latest_before_t64(db, (gnc_commodity*)from, (gnc_commodity*)to, t);
|
||||
else
|
||||
price = gnc_pricedb_lookup_nearest_in_time64(db, from, to, t);
|
||||
|
||||
@@ -2573,6 +2581,29 @@ direct_price_conversion (GNCPriceDB *db, const gnc_commodity *from,
|
||||
return retval;
|
||||
}
|
||||
|
||||
gnc_numeric
|
||||
gnc_pricedb_get_nearest_before_price (GNCPriceDB *pdb,
|
||||
const gnc_commodity *orig_currency,
|
||||
const gnc_commodity *new_currency,
|
||||
const time64 t)
|
||||
{
|
||||
gnc_numeric price;
|
||||
|
||||
if (gnc_commodity_equiv (orig_currency, new_currency))
|
||||
return gnc_numeric_create (1, 1);
|
||||
|
||||
/* Look for a direct price. */
|
||||
price = direct_price_conversion (pdb, orig_currency, new_currency, t, TRUE);
|
||||
|
||||
/*
|
||||
* no direct price found, try find a price in another currency
|
||||
*/
|
||||
if (gnc_numeric_zero_p (price))
|
||||
price = indirect_price_conversion (pdb, orig_currency, new_currency, t, TRUE);
|
||||
|
||||
return gnc_numeric_reduce (price);
|
||||
}
|
||||
|
||||
gnc_numeric
|
||||
gnc_pricedb_get_nearest_price (GNCPriceDB *pdb,
|
||||
const gnc_commodity *orig_currency,
|
||||
@@ -2585,13 +2616,13 @@ gnc_pricedb_get_nearest_price (GNCPriceDB *pdb,
|
||||
return gnc_numeric_create (1, 1);
|
||||
|
||||
/* Look for a direct price. */
|
||||
price = direct_price_conversion (pdb, orig_currency, new_currency, t);
|
||||
price = direct_price_conversion (pdb, orig_currency, new_currency, t, FALSE);
|
||||
|
||||
/*
|
||||
* no direct price found, try find a price in another currency
|
||||
*/
|
||||
if (gnc_numeric_zero_p (price))
|
||||
price = indirect_price_conversion (pdb, orig_currency, new_currency, t);
|
||||
price = indirect_price_conversion (pdb, orig_currency, new_currency, t, FALSE);
|
||||
|
||||
return gnc_numeric_reduce (price);
|
||||
}
|
||||
@@ -2604,18 +2635,23 @@ gnc_pricedb_get_latest_price (GNCPriceDB *pdb,
|
||||
return gnc_pricedb_get_nearest_price (pdb, orig_currency, new_currency, INT64_MAX);
|
||||
}
|
||||
|
||||
static gnc_numeric convert_amount_at_date (GNCPriceDB *pdb,
|
||||
gnc_numeric amount,
|
||||
const gnc_commodity *orig_currency,
|
||||
const gnc_commodity *new_currency,
|
||||
const time64 t)
|
||||
static gnc_numeric
|
||||
convert_amount_at_date (GNCPriceDB *pdb,
|
||||
gnc_numeric amount,
|
||||
const gnc_commodity *orig_currency,
|
||||
const gnc_commodity *new_currency,
|
||||
const time64 t,
|
||||
gboolean before_date)
|
||||
{
|
||||
gnc_numeric price;
|
||||
|
||||
if (gnc_numeric_zero_p (amount))
|
||||
return amount;
|
||||
|
||||
price = gnc_pricedb_get_nearest_price (pdb, orig_currency, new_currency, t);
|
||||
if (before_date)
|
||||
price = gnc_pricedb_get_nearest_before_price (pdb, orig_currency, new_currency, t);
|
||||
else
|
||||
price = gnc_pricedb_get_nearest_price (pdb, orig_currency, new_currency, t);
|
||||
|
||||
/* the price retrieved may be invalid. return zero. see 798015 */
|
||||
if (gnc_numeric_check (price))
|
||||
@@ -2636,7 +2672,7 @@ gnc_pricedb_convert_balance_latest_price (GNCPriceDB *pdb,
|
||||
const gnc_commodity *new_currency)
|
||||
{
|
||||
return convert_amount_at_date
|
||||
(pdb, balance, balance_currency, new_currency, INT64_MAX);
|
||||
(pdb, balance, balance_currency, new_currency, INT64_MAX, FALSE);
|
||||
}
|
||||
|
||||
gnc_numeric
|
||||
@@ -2647,9 +2683,19 @@ gnc_pricedb_convert_balance_nearest_price_t64(GNCPriceDB *pdb,
|
||||
time64 t)
|
||||
{
|
||||
return convert_amount_at_date
|
||||
(pdb, balance, balance_currency, new_currency, t);
|
||||
(pdb, balance, balance_currency, new_currency, t, FALSE);
|
||||
}
|
||||
|
||||
gnc_numeric
|
||||
gnc_pricedb_convert_balance_nearest_before_price_t64 (GNCPriceDB *pdb,
|
||||
gnc_numeric balance,
|
||||
const gnc_commodity *balance_currency,
|
||||
const gnc_commodity *new_currency,
|
||||
time64 t)
|
||||
{
|
||||
return convert_amount_at_date
|
||||
(pdb, balance, balance_currency, new_currency, t, TRUE);
|
||||
}
|
||||
|
||||
/* ==================================================================== */
|
||||
/* gnc_pricedb_foreach_price infrastructure
|
||||
|
||||
@@ -559,6 +559,19 @@ PriceList * gnc_pricedb_lookup_latest_before_any_currency_t64(GNCPriceDB *db,
|
||||
const gnc_commodity *c,
|
||||
time64 t);
|
||||
|
||||
/** @brief Retrieve the price one currency to another using the price
|
||||
* nearest to before the given time.
|
||||
* @param pdb The pricedb
|
||||
* @param orig_currency The commodity in which the balance is currently
|
||||
* expressed
|
||||
* @param new_currency The commodity to which the balance should be converted
|
||||
* @param t The time to be used for for comparison
|
||||
* @return A price, or gnc_numeric_zero if no price is available.
|
||||
*/
|
||||
gnc_numeric gnc_pricedb_get_nearest_before_price (GNCPriceDB *pdb,
|
||||
const gnc_commodity *orig_currency,
|
||||
const gnc_commodity *new_currency,
|
||||
const time64 t);
|
||||
|
||||
/** @brief Retrieve the price one currency to another at specified date
|
||||
* @param pdb The pricedb
|
||||
@@ -610,6 +623,23 @@ gnc_pricedb_convert_balance_nearest_price_t64(GNCPriceDB *pdb,
|
||||
const gnc_commodity *new_currency,
|
||||
time64 t);
|
||||
|
||||
/** @brief Convert a balance from one currency to another using the price
|
||||
* nearest to before the given time.
|
||||
* @param pdb The pricedb
|
||||
* @param balance The balance to be converted
|
||||
* @param balance_currency The commodity in which the balance is currently
|
||||
* expressed
|
||||
* @param new_currency The commodity to which the balance should be converted
|
||||
* @param t The time in which the last price before it should be used.
|
||||
* @return A new balance or gnc_numeric_zero if no price is available.
|
||||
*/
|
||||
gnc_numeric
|
||||
gnc_pricedb_convert_balance_nearest_before_price_t64 (GNCPriceDB *pdb,
|
||||
gnc_numeric balance,
|
||||
const gnc_commodity *balance_currency,
|
||||
const gnc_commodity *new_currency,
|
||||
time64 t);
|
||||
|
||||
typedef gboolean (*GncPriceForeachFunc)(GNCPrice *p, gpointer user_data);
|
||||
|
||||
/** @brief Call a GncPriceForeachFunction once for each price in db, until the
|
||||
|
||||
Reference in New Issue
Block a user