mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Merge branch 'maint-797982' into maint #802
This commit is contained in:
commit
92f2727862
@ -21,6 +21,7 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(use-modules (ice-9 match))
|
||||
(use-modules (srfi srfi-26))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Functions to get splits with interesting data from accounts.
|
||||
@ -764,6 +765,18 @@
|
||||
(gnc:exchange-by-pricedb-nearest
|
||||
foreign domestic to-date-tp))))))
|
||||
|
||||
(define (gnc:case-price-fn source target-curr date)
|
||||
(define pdb (gnc-pricedb-get-db (gnc-get-current-book)))
|
||||
(case source
|
||||
((pricedb-nearest) (cut gnc-pricedb-get-nearest-price pdb <> target-curr date))
|
||||
((pricedb-latest) (cut gnc-pricedb-get-latest-price pdb <> target-curr))
|
||||
(else
|
||||
(lambda (commodity)
|
||||
(let* ((exchange-fn (gnc:case-exchange-fn source target-curr date))
|
||||
(foreign-mon (gnc:make-gnc-monetary commodity 1))
|
||||
(domestic-mon (exchange-fn foreign-mon target-curr)))
|
||||
(gnc:gnc-monetary-amount domestic-mon))))))
|
||||
|
||||
;; Return a ready-to-use function. Which one to use is determined by
|
||||
;; the value of 'source-option', whose possible values are set in
|
||||
;; gnc:options-add-price-source!.
|
||||
|
@ -167,12 +167,8 @@
|
||||
(xaccPrintAmount datum (gnc-default-print-info #f)))
|
||||
|
||||
;; renders a price to target currency
|
||||
(define (gnc:default-price-renderer currency amount)
|
||||
(xaccPrintAmount
|
||||
(gnc-numeric-convert
|
||||
amount (min 10000 (* 100 (gnc-commodity-get-fraction currency)))
|
||||
GNC-HOW-RND-ROUND)
|
||||
(gnc-price-print-info currency #t)))
|
||||
(define (gnc:default-price-renderer currency price)
|
||||
(xaccPrintAmount price (gnc-price-print-info currency #t)))
|
||||
|
||||
(define (gnc:default-html-gnc-monetary-renderer datum params)
|
||||
(let* ((comm (gnc:gnc-monetary-commodity datum))
|
||||
|
@ -207,6 +207,8 @@
|
||||
;; function 'exchange-fn' and the 'accounts' determine which
|
||||
;; commodities to show. Returns a html-object, a <html-table>.
|
||||
(define (gnc:html-make-exchangerates common-commodity exchange-fn accounts)
|
||||
(issue-deprecation-warning
|
||||
"gnc:html-make-exchangerates is deprecated. use gnc:html-make-rates-table instead.")
|
||||
(let ((comm-list (gnc:accounts-get-commodities accounts common-commodity))
|
||||
(markup (lambda (c) (gnc:make-html-table-cell/markup "number-cell" c)))
|
||||
(table (gnc:make-html-table)))
|
||||
@ -228,6 +230,30 @@
|
||||
(G_ "Exchange rates"))))))
|
||||
table))
|
||||
|
||||
;; Create a html-table of all prices. The report-currency is
|
||||
;; 'currency', The prices are given through the function 'price-fn'
|
||||
;; and the 'accounts' determine which commodities to show. Returns a
|
||||
;; html-object, a <html-table>. price-fn is easily obtained from
|
||||
;; gnc:case-price-fn
|
||||
(define (gnc:html-make-rates-table currency price-fn accounts)
|
||||
(define (cell c) (gnc:make-html-table-cell/markup "number-cell" c))
|
||||
(define table (gnc:make-html-table))
|
||||
(let lp ((comm-list (gnc:accounts-get-commodities accounts currency)) (entries 0))
|
||||
(match comm-list
|
||||
(()
|
||||
(unless (zero? entries)
|
||||
(gnc:html-table-set-col-headers!
|
||||
table (list (gnc:make-html-table-header-cell/size
|
||||
1 2 (if (= entries 1) (G_ "Exchange rate")
|
||||
(G_ "Exchange rates"))))))
|
||||
table)
|
||||
((comm . rest)
|
||||
(gnc:html-table-append-row!
|
||||
table
|
||||
(list (cell (gnc:make-gnc-monetary comm 1))
|
||||
(cell (gnc:default-price-renderer currency (price-fn comm)))))
|
||||
(lp rest (1+ entries))))))
|
||||
|
||||
|
||||
(define (gnc:html-make-generic-budget-warning report-title-string)
|
||||
(gnc:html-make-generic-simple-warning
|
||||
|
@ -58,6 +58,7 @@
|
||||
(export gnc:exchange-by-pricealist-nearest)
|
||||
(export gnc:case-exchange-fn)
|
||||
(export gnc:case-exchange-time-fn)
|
||||
(export gnc:case-price-fn)
|
||||
(export gnc:sum-collector-commodity)
|
||||
|
||||
;; options-utilities.scm
|
||||
@ -104,6 +105,7 @@
|
||||
(export gnc:assign-colors)
|
||||
(export gnc:html-table-append-ruler!)
|
||||
(export gnc:html-make-exchangerates)
|
||||
(export gnc:html-make-rates-table)
|
||||
(export gnc:html-render-options-changed)
|
||||
(export gnc:html-make-generic-warning)
|
||||
(export gnc:html-make-no-account-warning)
|
||||
|
@ -315,6 +315,7 @@
|
||||
(gnc:get-current-account-tree-depth)
|
||||
depth-limit))
|
||||
;; exchange rates calculation parameters
|
||||
(price-fn (gnc:case-price-fn price-source report-commodity to-date))
|
||||
(exchange-fn (gnc:case-exchange-fn price-source report-commodity to-date)))
|
||||
|
||||
(gnc:html-document-set-title!
|
||||
@ -441,8 +442,8 @@
|
||||
;; add currency information
|
||||
(when show-rates?
|
||||
(gnc:html-document-add-object!
|
||||
doc (gnc:html-make-exchangerates
|
||||
report-commodity exchange-fn
|
||||
doc (gnc:html-make-rates-table
|
||||
report-commodity price-fn
|
||||
(gnc:accounts-and-all-descendants accounts))))))
|
||||
|
||||
(gnc:report-finished)
|
||||
|
@ -343,6 +343,7 @@
|
||||
(tree-depth (if (eq? depth-limit 'all)
|
||||
(gnc:get-current-account-tree-depth)
|
||||
depth-limit))
|
||||
(price-fn (gnc:case-price-fn price-source report-commodity reportdate))
|
||||
;; exchange rates calculation parameters
|
||||
(exchange-fn
|
||||
(gnc:case-exchange-fn price-source report-commodity reportdate)))
|
||||
@ -550,7 +551,7 @@
|
||||
(gnc:report-percent-done 90)
|
||||
(when show-rates?
|
||||
(gnc:html-document-add-object!
|
||||
doc (gnc:html-make-exchangerates report-commodity exchange-fn accounts)))
|
||||
doc (gnc:html-make-rates-table report-commodity price-fn accounts)))
|
||||
|
||||
(gnc:report-percent-done 100)))
|
||||
|
||||
|
@ -355,7 +355,8 @@
|
||||
;; exchange rates calculation parameters
|
||||
(exchange-fn
|
||||
(gnc:case-exchange-fn price-source report-commodity date-t64))
|
||||
)
|
||||
|
||||
(price-fn (gnc:case-price-fn price-source report-commodity date-t64)))
|
||||
|
||||
(define (add-subtotal-line table pos-label neg-label signed-balance)
|
||||
(let* ((neg? (and signed-balance neg-label
|
||||
@ -808,8 +809,7 @@
|
||||
(if show-rates?
|
||||
(gnc:html-document-add-object!
|
||||
doc ;;(gnc:html-markup-p)
|
||||
(gnc:html-make-exchangerates
|
||||
report-commodity exchange-fn accounts)))
|
||||
(gnc:html-make-rates-table report-commodity price-fn accounts)))
|
||||
(gnc:report-percent-done 100)))))
|
||||
|
||||
(gnc:report-finished)
|
||||
|
@ -401,7 +401,8 @@
|
||||
;; exchange rates calculation parameters
|
||||
(exchange-fn
|
||||
(gnc:case-exchange-fn price-source report-commodity date-t64))
|
||||
)
|
||||
|
||||
(price-fn (gnc:case-price-fn price-source report-commodity date-t64)))
|
||||
|
||||
(define (add-subtotal-line table pos-label neg-label signed-balance)
|
||||
(let* ((neg? (and signed-balance neg-label
|
||||
@ -595,7 +596,7 @@
|
||||
(gnc:report-percent-done 90)
|
||||
(when show-rates?
|
||||
(gnc:html-document-add-object!
|
||||
doc (gnc:html-make-exchangerates report-commodity exchange-fn accounts)))
|
||||
doc (gnc:html-make-rates-table report-commodity price-fn accounts)))
|
||||
(gnc:report-percent-done 100))))
|
||||
|
||||
(gnc:report-finished)
|
||||
|
@ -149,6 +149,8 @@
|
||||
(exchange-fn (gnc:case-exchange-fn
|
||||
price-source report-currency to-date-t64))
|
||||
|
||||
(price-fn (gnc:case-price-fn price-source report-currency to-date-t64))
|
||||
|
||||
(doc (gnc:make-html-document))
|
||||
(table (gnc:make-html-table))
|
||||
|
||||
@ -321,8 +323,8 @@
|
||||
(if show-rates?
|
||||
(gnc:html-document-add-object!
|
||||
doc ;;(gnc:html-markup-p
|
||||
(gnc:html-make-exchangerates
|
||||
report-currency exchange-fn accounts))))))
|
||||
(gnc:html-make-rates-table
|
||||
report-currency price-fn accounts))))))
|
||||
|
||||
;; error condition: no accounts specified
|
||||
|
||||
|
@ -280,7 +280,9 @@
|
||||
(end-exchange-fn
|
||||
(gnc:case-exchange-fn
|
||||
price-source report-commodity end-date))
|
||||
)
|
||||
|
||||
(start-price-fn (gnc:case-price-fn price-source report-commodity start-date))
|
||||
(end-price-fn (gnc:case-price-fn price-source report-commodity end-date)))
|
||||
|
||||
(define (unrealized-gains-at-date book-balance exchange-fn date)
|
||||
(define cost-fn
|
||||
@ -496,10 +498,10 @@
|
||||
(headers (list
|
||||
(qof-print-date start-date-printable)
|
||||
(qof-print-date end-date)))
|
||||
(then (gnc:html-make-exchangerates
|
||||
report-commodity start-exchange-fn accounts))
|
||||
(now (gnc:html-make-exchangerates
|
||||
report-commodity end-exchange-fn accounts)))
|
||||
(then (gnc:html-make-rates-table
|
||||
report-commodity start-price-fn accounts))
|
||||
(now (gnc:html-make-rates-table
|
||||
report-commodity end-price-fn accounts)))
|
||||
(gnc:html-table-set-col-headers! curr-tbl headers)
|
||||
(gnc:html-table-set-style!
|
||||
curr-tbl "table" 'attribute '("border" "1"))
|
||||
|
@ -382,7 +382,7 @@
|
||||
;; exchange rates calculation parameters
|
||||
(exchange-fn
|
||||
(gnc:case-exchange-fn price-source report-commodity end-date))
|
||||
)
|
||||
(price-fn (gnc:case-price-fn price-source report-commodity end-date)))
|
||||
|
||||
;; Wrapper to call gnc:html-table-add-labeled-amount-line!
|
||||
;; with the proper arguments.
|
||||
@ -561,8 +561,8 @@
|
||||
(gnc:report-percent-done 90)
|
||||
(when show-rates?
|
||||
(gnc:html-document-add-object!
|
||||
doc (gnc:html-make-exchangerates
|
||||
report-commodity exchange-fn accounts)))
|
||||
doc (gnc:html-make-rates-table
|
||||
report-commodity price-fn accounts)))
|
||||
(gnc:report-percent-done 100)))
|
||||
|
||||
(gnc:report-finished)
|
||||
|
@ -401,6 +401,7 @@
|
||||
;; exchange rates calculation parameters
|
||||
(exchange-fn
|
||||
(gnc:case-exchange-fn price-source report-commodity end-date))
|
||||
(price-fn (gnc:case-price-fn price-source report-commodity end-date))
|
||||
(period-for (string-append " " (G_ "for Period"))))
|
||||
|
||||
(gnc:html-document-set-title!
|
||||
@ -894,8 +895,8 @@
|
||||
(if show-rates?
|
||||
(gnc:html-document-add-object!
|
||||
doc
|
||||
(gnc:html-make-exchangerates
|
||||
report-commodity exchange-fn accounts)))
|
||||
(gnc:html-make-rates-table
|
||||
report-commodity price-fn accounts)))
|
||||
(gnc:report-percent-done 100)))
|
||||
|
||||
(gnc:report-finished)
|
||||
|
@ -2435,35 +2435,6 @@ gnc_pricedb_lookup_latest_before_t64 (GNCPriceDB *db,
|
||||
return current_price;
|
||||
}
|
||||
|
||||
static gnc_numeric
|
||||
direct_balance_conversion (GNCPriceDB *db, gnc_numeric bal,
|
||||
const gnc_commodity *from, const gnc_commodity *to,
|
||||
time64 t)
|
||||
{
|
||||
GNCPrice *price;
|
||||
gnc_numeric retval = gnc_numeric_zero();
|
||||
if (from == NULL || to == NULL)
|
||||
return retval;
|
||||
if (gnc_numeric_zero_p(bal))
|
||||
return retval;
|
||||
if (t != INT64_MAX)
|
||||
price = gnc_pricedb_lookup_nearest_in_time64(db, from, to, t);
|
||||
else
|
||||
price = gnc_pricedb_lookup_latest(db, from, to);
|
||||
if (price == NULL)
|
||||
return retval;
|
||||
if (gnc_price_get_commodity(price) == from)
|
||||
retval = gnc_numeric_mul (bal, gnc_price_get_value (price),
|
||||
gnc_commodity_get_fraction (to),
|
||||
GNC_HOW_RND_ROUND);
|
||||
else
|
||||
retval = gnc_numeric_div (bal, gnc_price_get_value (price),
|
||||
gnc_commodity_get_fraction (to),
|
||||
GNC_HOW_RND_ROUND);
|
||||
gnc_price_unref (price);
|
||||
return retval;
|
||||
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -2513,47 +2484,43 @@ extract_common_prices (PriceList *from_prices, PriceList *to_prices,
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
static gnc_numeric
|
||||
convert_balance(gnc_numeric bal, const gnc_commodity *from,
|
||||
const gnc_commodity *to, PriceTuple tuple)
|
||||
convert_price (const gnc_commodity *from, const gnc_commodity *to, PriceTuple tuple)
|
||||
{
|
||||
gnc_commodity *from_com = gnc_price_get_commodity(tuple.from);
|
||||
gnc_commodity *from_cur = gnc_price_get_currency(tuple.from);
|
||||
gnc_commodity *to_com = gnc_price_get_commodity(tuple.to);
|
||||
gnc_commodity *to_cur = gnc_price_get_currency(tuple.to);
|
||||
gnc_numeric from_val = gnc_price_get_value(tuple.from);
|
||||
gnc_numeric to_val = gnc_price_get_value(tuple.to);
|
||||
int fraction = gnc_commodity_get_fraction(to);
|
||||
|
||||
gnc_commodity *from_com = gnc_price_get_commodity (tuple.from);
|
||||
gnc_commodity *from_cur = gnc_price_get_currency (tuple.from);
|
||||
gnc_commodity *to_com = gnc_price_get_commodity (tuple.to);
|
||||
gnc_commodity *to_cur = gnc_price_get_currency (tuple.to);
|
||||
gnc_numeric from_val = gnc_price_get_value (tuple.from);
|
||||
gnc_numeric to_val = gnc_price_get_value (tuple.to);
|
||||
gnc_numeric price;
|
||||
int no_round = GNC_HOW_DENOM_EXACT | GNC_HOW_RND_NEVER;
|
||||
if (from_cur == from && to_cur == to)
|
||||
return gnc_numeric_div(gnc_numeric_mul(bal, to_val, GNC_DENOM_AUTO,
|
||||
no_round),
|
||||
from_val, fraction, GNC_HOW_RND_ROUND);
|
||||
if (from_com == from && to_com == to)
|
||||
return gnc_numeric_div(gnc_numeric_mul(bal, from_val, GNC_DENOM_AUTO,
|
||||
no_round),
|
||||
to_val, fraction, GNC_HOW_RND_ROUND);
|
||||
if (from_cur == from)
|
||||
return gnc_numeric_div(bal, gnc_numeric_mul(from_val, to_val,
|
||||
GNC_DENOM_AUTO, no_round),
|
||||
fraction, GNC_HOW_RND_ROUND);
|
||||
return gnc_numeric_mul(bal, gnc_numeric_mul(from_val, to_val,
|
||||
GNC_DENOM_AUTO, no_round),
|
||||
fraction, GNC_HOW_RND_ROUND);
|
||||
|
||||
price = gnc_numeric_div (to_val, from_val, GNC_DENOM_AUTO, no_round);
|
||||
|
||||
if (from_cur == from && to_cur == to)
|
||||
return price;
|
||||
|
||||
if (from_com == from && to_com == to)
|
||||
return gnc_numeric_invert (price);
|
||||
|
||||
price = gnc_numeric_mul (from_val, to_val, GNC_DENOM_AUTO, no_round);
|
||||
|
||||
if (from_cur == from)
|
||||
return gnc_numeric_invert (price);
|
||||
|
||||
return price;
|
||||
}
|
||||
|
||||
static gnc_numeric
|
||||
indirect_balance_conversion (GNCPriceDB *db, gnc_numeric bal,
|
||||
const gnc_commodity *from, const gnc_commodity *to,
|
||||
time64 t )
|
||||
indirect_price_conversion (GNCPriceDB *db, const gnc_commodity *from,
|
||||
const gnc_commodity *to, time64 t)
|
||||
{
|
||||
GList *from_prices = NULL, *to_prices = NULL;
|
||||
PriceTuple tuple;
|
||||
gnc_numeric zero = gnc_numeric_zero();
|
||||
if (from == NULL || to == NULL)
|
||||
return zero;
|
||||
if (gnc_numeric_zero_p(bal))
|
||||
if (!from || !to)
|
||||
return zero;
|
||||
if (t == INT64_MAX)
|
||||
{
|
||||
@ -2565,50 +2532,106 @@ indirect_balance_conversion (GNCPriceDB *db, gnc_numeric bal,
|
||||
}
|
||||
else
|
||||
{
|
||||
from_prices = gnc_pricedb_lookup_nearest_in_time_any_currency_t64(db,
|
||||
from, t);
|
||||
from_prices = gnc_pricedb_lookup_nearest_in_time_any_currency_t64 (db, from, t);
|
||||
if (from_prices)
|
||||
to_prices = gnc_pricedb_lookup_nearest_in_time_any_currency_t64(db,
|
||||
to, t);
|
||||
to_prices = gnc_pricedb_lookup_nearest_in_time_any_currency_t64 (db, to, t);
|
||||
}
|
||||
if (from_prices == NULL || to_prices == NULL)
|
||||
if (!from_prices || !to_prices)
|
||||
return zero;
|
||||
tuple = extract_common_prices(from_prices, to_prices, from, to);
|
||||
gnc_price_list_destroy(from_prices);
|
||||
gnc_price_list_destroy(to_prices);
|
||||
tuple = extract_common_prices (from_prices, to_prices, from, to);
|
||||
gnc_price_list_destroy (from_prices);
|
||||
gnc_price_list_destroy (to_prices);
|
||||
if (tuple.from)
|
||||
return convert_balance(bal, from, to, tuple);
|
||||
return convert_price (from, to, tuple);
|
||||
return zero;
|
||||
}
|
||||
|
||||
|
||||
static gnc_numeric
|
||||
direct_price_conversion (GNCPriceDB *db, const gnc_commodity *from,
|
||||
const gnc_commodity *to, time64 t)
|
||||
{
|
||||
GNCPrice *price;
|
||||
gnc_numeric retval = gnc_numeric_zero();
|
||||
|
||||
if (!from || !to) return retval;
|
||||
|
||||
if (t == INT64_MAX)
|
||||
price = gnc_pricedb_lookup_latest(db, from, to);
|
||||
else
|
||||
price = gnc_pricedb_lookup_nearest_in_time64(db, from, to, t);
|
||||
|
||||
if (!price) return retval;
|
||||
|
||||
retval = gnc_price_get_value (price);
|
||||
|
||||
if (gnc_price_get_commodity (price) != from)
|
||||
retval = gnc_numeric_invert (retval);
|
||||
|
||||
gnc_price_unref (price);
|
||||
return retval;
|
||||
}
|
||||
|
||||
gnc_numeric
|
||||
gnc_pricedb_get_nearest_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);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
return gnc_numeric_reduce (price);
|
||||
}
|
||||
|
||||
gnc_numeric
|
||||
gnc_pricedb_get_latest_price (GNCPriceDB *pdb,
|
||||
const gnc_commodity *orig_currency,
|
||||
const gnc_commodity *new_currency)
|
||||
{
|
||||
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)
|
||||
{
|
||||
gnc_numeric price;
|
||||
|
||||
if (gnc_numeric_zero_p (amount))
|
||||
return amount;
|
||||
|
||||
price = gnc_pricedb_get_nearest_price (pdb, orig_currency, new_currency, t);
|
||||
|
||||
return gnc_numeric_mul
|
||||
(amount, price, gnc_commodity_get_fraction (new_currency),
|
||||
GNC_HOW_DENOM_EXACT | GNC_HOW_RND_ROUND);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a balance from one currency to another.
|
||||
*/
|
||||
gnc_numeric
|
||||
gnc_pricedb_convert_balance_latest_price(GNCPriceDB *pdb,
|
||||
gnc_numeric balance,
|
||||
const gnc_commodity *balance_currency,
|
||||
const gnc_commodity *new_currency)
|
||||
gnc_pricedb_convert_balance_latest_price (GNCPriceDB *pdb,
|
||||
gnc_numeric balance,
|
||||
const gnc_commodity *balance_currency,
|
||||
const gnc_commodity *new_currency)
|
||||
{
|
||||
gnc_numeric new_value;
|
||||
|
||||
if (gnc_numeric_zero_p (balance) ||
|
||||
gnc_commodity_equiv (balance_currency, new_currency))
|
||||
return balance;
|
||||
|
||||
/* Look for a direct price. */
|
||||
new_value = direct_balance_conversion(pdb, balance, balance_currency,
|
||||
new_currency, INT64_MAX);
|
||||
if (!gnc_numeric_zero_p(new_value))
|
||||
return new_value;
|
||||
|
||||
/*
|
||||
* no direct price found, try if we find a price in another currency
|
||||
* and convert in two stages
|
||||
*/
|
||||
return indirect_balance_conversion(pdb, balance, balance_currency,
|
||||
new_currency, INT64_MAX);
|
||||
return convert_amount_at_date
|
||||
(pdb, balance, balance_currency, new_currency, INT64_MAX);
|
||||
}
|
||||
|
||||
gnc_numeric
|
||||
@ -2618,24 +2641,8 @@ gnc_pricedb_convert_balance_nearest_price_t64(GNCPriceDB *pdb,
|
||||
const gnc_commodity *new_currency,
|
||||
time64 t)
|
||||
{
|
||||
gnc_numeric new_value;
|
||||
|
||||
if (gnc_numeric_zero_p (balance) ||
|
||||
gnc_commodity_equiv (balance_currency, new_currency))
|
||||
return balance;
|
||||
|
||||
/* Look for a direct price. */
|
||||
new_value = direct_balance_conversion(pdb, balance, balance_currency,
|
||||
new_currency, t);
|
||||
if (!gnc_numeric_zero_p(new_value))
|
||||
return new_value;
|
||||
|
||||
/*
|
||||
* no direct price found, try if we find a price in another currency
|
||||
* and convert in two stages
|
||||
*/
|
||||
return indirect_balance_conversion(pdb, balance, balance_currency,
|
||||
new_currency, t);
|
||||
return convert_amount_at_date
|
||||
(pdb, balance, balance_currency, new_currency, t);
|
||||
}
|
||||
|
||||
|
||||
|
@ -559,6 +559,24 @@ PriceList * gnc_pricedb_lookup_latest_before_any_currency_t64(GNCPriceDB *db,
|
||||
time64 t);
|
||||
|
||||
|
||||
/** @brief Retrieve the price one currency to another at specified date
|
||||
* @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
|
||||
* @return A price, or gnc_numeric_zero if no price is available.
|
||||
*/
|
||||
|
||||
gnc_numeric gnc_pricedb_get_nearest_price (GNCPriceDB *pdb,
|
||||
const gnc_commodity *orig_currency,
|
||||
const gnc_commodity *new_currency,
|
||||
const time64 t);
|
||||
|
||||
gnc_numeric gnc_pricedb_get_latest_price (GNCPriceDB *pdb,
|
||||
const gnc_commodity *orig_currency,
|
||||
const gnc_commodity *new_currency);
|
||||
|
||||
|
||||
/** @brief Convert a balance from one currency to another using the most recent
|
||||
* price between the two.
|
||||
* @param pdb The pricedb
|
||||
|
@ -1248,6 +1248,84 @@ test_gnc_pricedb_convert_balance_nearest_price_t64 (PriceDBFixture *fixture, gco
|
||||
g_assert_cmpint(result.denom, ==, 100);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
test_gnc_pricedb_get_latest_price (PriceDBFixture *fixture, gconstpointer pData)
|
||||
{
|
||||
gnc_numeric result;
|
||||
|
||||
result = gnc_pricedb_get_latest_price (fixture->pricedb,
|
||||
fixture->com->usd,
|
||||
fixture->com->aud);
|
||||
g_assert_cmpint(result.num, ==, 3587);
|
||||
g_assert_cmpint(result.denom, ==, 3125);
|
||||
|
||||
result = gnc_pricedb_get_latest_price (fixture->pricedb,
|
||||
fixture->com->usd,
|
||||
fixture->com->gbp);
|
||||
g_assert_cmpint(result.num, ==, 50000);
|
||||
g_assert_cmpint(result.denom, ==, 78829);
|
||||
|
||||
result = gnc_pricedb_get_latest_price (fixture->pricedb,
|
||||
fixture->com->usd,
|
||||
fixture->com->eur);
|
||||
g_assert_cmpint(result.num, ==, 63418);
|
||||
g_assert_cmpint(result.denom, ==, 78829);
|
||||
|
||||
result = gnc_pricedb_get_latest_price (fixture->pricedb,
|
||||
fixture->com->gbp,
|
||||
fixture->com->dkk);
|
||||
g_assert_cmpint(result.num, ==, 47194370497);
|
||||
g_assert_cmpint(result.denom, ==, 5000000000);
|
||||
|
||||
result = gnc_pricedb_get_latest_price (fixture->pricedb,
|
||||
fixture->com->amzn,
|
||||
fixture->com->aud);
|
||||
g_assert_cmpint(result.num, ==, 111738637);
|
||||
g_assert_cmpint(result.denom, ==, 312500);
|
||||
}
|
||||
|
||||
static void
|
||||
test_gnc_pricedb_get_nearest_price (PriceDBFixture *fixture, gconstpointer pData)
|
||||
{
|
||||
time64 t = gnc_dmy2time64(15, 8, 2011);
|
||||
gnc_numeric result;
|
||||
|
||||
result = gnc_pricedb_get_nearest_price (fixture->pricedb,
|
||||
fixture->com->usd,
|
||||
fixture->com->aud, t);
|
||||
g_assert_cmpint(result.num, ==, 1250);
|
||||
g_assert_cmpint(result.denom, ==, 1331);
|
||||
|
||||
result = gnc_pricedb_get_nearest_price (fixture->pricedb,
|
||||
fixture->com->usd,
|
||||
fixture->com->gbp,
|
||||
t);
|
||||
g_assert_cmpint(result.num, ==, 100000);
|
||||
g_assert_cmpint(result.denom, ==, 161643);
|
||||
|
||||
result = gnc_pricedb_get_nearest_price (fixture->pricedb,
|
||||
fixture->com->usd,
|
||||
fixture->com->eur,
|
||||
t);
|
||||
g_assert_cmpint(result.num, ==, 37763);
|
||||
g_assert_cmpint(result.denom, ==, 53881);
|
||||
|
||||
result = gnc_pricedb_get_nearest_price (fixture->pricedb,
|
||||
fixture->com->gbp,
|
||||
fixture->com->dkk,
|
||||
t);
|
||||
g_assert_cmpint(result.num, ==, 84450223707);
|
||||
g_assert_cmpint(result.denom, ==, 10000000000);
|
||||
|
||||
result = gnc_pricedb_get_nearest_price (fixture->pricedb,
|
||||
fixture->com->amzn,
|
||||
fixture->com->aud,
|
||||
t);
|
||||
g_assert_cmpint(result.num, ==, 278150);
|
||||
g_assert_cmpint(result.denom, ==, 1331);
|
||||
}
|
||||
|
||||
/* pricedb_foreach_pricelist
|
||||
static void
|
||||
pricedb_foreach_pricelist(gpointer key, gpointer val, gpointer user_data)// Local: 0:1:0
|
||||
@ -1504,6 +1582,8 @@ test_suite_gnc_pricedb (void)
|
||||
// GNC_TEST_ADD (suitename, "indirect balance conversion", Fixture, NULL, setup, test_indirect_balance_conversion, teardown);
|
||||
GNC_TEST_ADD (suitename, "gnc pricedb convert balance latest price", PriceDBFixture, NULL, setup, test_gnc_pricedb_convert_balance_latest_price, teardown);
|
||||
GNC_TEST_ADD (suitename, "gnc pricedb convert balance nearest price", PriceDBFixture, NULL, setup, test_gnc_pricedb_convert_balance_nearest_price_t64, teardown);
|
||||
GNC_TEST_ADD (suitename, "gnc pricedb get latest price", PriceDBFixture, NULL, setup, test_gnc_pricedb_get_latest_price, teardown);
|
||||
GNC_TEST_ADD (suitename, "gnc pricedb get nearest price", PriceDBFixture, NULL, setup, test_gnc_pricedb_get_nearest_price, teardown);
|
||||
// GNC_TEST_ADD (suitename, "pricedb foreach pricelist", Fixture, NULL, setup, test_pricedb_foreach_pricelist, teardown);
|
||||
// GNC_TEST_ADD (suitename, "pricedb foreach currencies hash", Fixture, NULL, setup, test_pricedb_foreach_currencies_hash, teardown);
|
||||
// GNC_TEST_ADD (suitename, "unstable price traversal", Fixture, NULL, setup, test_unstable_price_traversal, teardown);
|
||||
|
Loading…
Reference in New Issue
Block a user