gnucash maint: Multiple changes pushed

Robert Fewell bobit at code.gnucash.org
Fri Apr 23 06:57:06 EDT 2021


Updated	 via  https://github.com/Gnucash/gnucash/commit/49102c7a (commit)
	 via  https://github.com/Gnucash/gnucash/commit/87285f94 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/e535ba54 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/e75308e6 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/d3bd7fda (commit)
	 via  https://github.com/Gnucash/gnucash/commit/4a491f7c (commit)
	 via  https://github.com/Gnucash/gnucash/commit/05507008 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/b54c30e0 (commit)
	from  https://github.com/Gnucash/gnucash/commit/ab80a0c4 (commit)



commit 49102c7ac2693c5408ac28f8be8d32be4957bb86
Author: John Ralls <jralls at ceridwen.us>
Date:   Thu Apr 22 18:36:42 2021 -0700

    Python Bindings: Provide a deprecated GncPriceDB.lookup_latest_before_t64.
    
    To avoid breaking user scripts.

diff --git a/bindings/python/deprecation.py b/bindings/python/deprecation.py
index 81d4cdc36..46d0a71f0 100644
--- a/bindings/python/deprecation.py
+++ b/bindings/python/deprecation.py
@@ -8,6 +8,31 @@
 # @ingroup python_bindings
 
 from functools import wraps
+import inspect
+from warnings import warn_explicit, warn
+
+# General purpose deprecation decorator. Lifted from
+# https://gist.github.com/kgriffs/8202106
+
+def deprecated(message):
+    '''
+    Flags a method as deprecated.
+    param message: Text emitted as part of warning. Include instructions to replace the deprecated function e.g. "use waldo_pepper() isnstead."
+    '''
+    def decorator(func):
+        @wraps(func)
+        def wrapper(*args, **kwargs):
+            warning_msg = 'Call to deprecated function {}. {}'.format(
+                func.__name__, message)
+            frame = inspect.current_frame().f_back
+
+            warn_explicit(message,
+                          category=DeprecationWarnig,
+                          filename=inspect.getfile(frame.f_code),
+                          lineno=frame.f_lineno)
+            return func(*args, **kwargs)
+        return wrapper
+    return decorator
 
 # use of is_new, force_new and ignore_lock is deprecated, use mode instead
 # the following decorators enable backward compatibility for the deprecation period
@@ -30,8 +55,7 @@ def deprecated_args_session(ignore_lock_or_mode=None, is_new=None,
 
     if deprecation:
         # if any(item in ("is_new", "ignore_lock", "force_new") for item in kwargs):
-        import warnings
-        warnings.warn(
+        warn(
             "Use of ignore_lock, is_new or force_new arguments is deprecated. Use mode argument instead. Have a look at gnucash.SessionOpenMode.",
             category=DeprecationWarning,
             stacklevel=3
@@ -65,4 +89,3 @@ def deprecated_args_session_begin(original_function):
         mode = deprecated_args_session(ignore_lock_or_mode, is_new, force_new, mode, ignore_lock)
         return(original_function(self, new_uri=new_uri, mode=mode))
     return new_function
-
diff --git a/bindings/python/gnucash_core.py b/bindings/python/gnucash_core.py
index cd2d55729..f088fd03f 100644
--- a/bindings/python/gnucash_core.py
+++ b/bindings/python/gnucash_core.py
@@ -53,7 +53,8 @@ from gnucash.gnucash_core_c import gncInvoiceLookup, gncInvoiceGetInvoiceFromTxn
 from gnucash.deprecation import (
     deprecated_args_session,
     deprecated_args_session_init,
-    deprecated_args_session_begin
+    deprecated_args_session_begin,
+    deprecated
 )
 
 try:
@@ -502,6 +503,14 @@ class GncPriceDB(GnuCashCoreClass):
     See also https://code.gnucash.org/docs/head/gnc-pricedb_8h.html
     '''
 
+ at deprecated("Use gnc_pricedb_latest_before_t64")
+def gnc_pricedb_lookup_latest_before_t64(self, commodity, currency, date):
+    return self.lookup_nearest_before_t64(commodit, currency,date)
+
+GncPriceDB.add_method('gnc_pricedb_lookup_latest_before_t64', 'lookup_latest_before_t64')
+
+GncPriceDB.lookup_latest_before_t64 = method_function_returns_instance(GncPriceDB.lookup_latest_before_t64, GncPrice)
+
 GncPriceDB.add_methods_with_prefix('gnc_pricedb_')
 PriceDB_dict =  {
                 'lookup_latest' : GncPrice,
@@ -514,7 +523,6 @@ methods_return_instance(GncPriceDB,PriceDB_dict)
 GncPriceDB.get_prices = method_function_returns_instance_list(
     GncPriceDB.get_prices, GncPrice )
 
-
 class GncCommodity(GnuCashCoreClass): pass
 
 class GncCommodityTable(GnuCashCoreClass):

commit 87285f945e082314ff8c25c2a90fcc4560a15708
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Thu Apr 22 13:48:25 2021 +0100

    Update gnucash_core.py with gnc-pricedb function name change

diff --git a/bindings/python/gnucash_core.py b/bindings/python/gnucash_core.py
index 50eb6c41a..cd2d55729 100644
--- a/bindings/python/gnucash_core.py
+++ b/bindings/python/gnucash_core.py
@@ -506,7 +506,7 @@ GncPriceDB.add_methods_with_prefix('gnc_pricedb_')
 PriceDB_dict =  {
                 'lookup_latest' : GncPrice,
                 'lookup_nearest_in_time64' : GncPrice,
-                'lookup_latest_before_t64' : GncPrice,
+                'lookup_nearest_before_t64' : GncPrice,
                 'convert_balance_latest_price' : GncNumeric,
                 'convert_balance_nearest_price_t64' : GncNumeric,
                 }

commit e535ba5411f3cd583b7a6e30a86f7d025d756c54
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Thu Apr 22 12:54:50 2021 +0100

    Change some functions to use const gnc_commodity for gnc_pricedb

diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index b36f10bbb..f820cbdba 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -3609,8 +3609,8 @@ xaccAccountConvertBalanceToCurrency(const Account *acc, /* for book */
 gnc_numeric
 xaccAccountConvertBalanceToCurrencyAsOfDate(const Account *acc, /* for book */
         gnc_numeric balance,
-        gnc_commodity *balance_currency,
-        gnc_commodity *new_currency,
+        const gnc_commodity *balance_currency,
+        const gnc_commodity *new_currency,
         time64 date)
 {
     QofBook *book;
@@ -3667,7 +3667,7 @@ xaccAccountGetXxxBalanceAsOfDateInCurrency(Account *acc, time64 date,
 
     priv = GET_PRIVATE(acc);
     return xaccAccountConvertBalanceToCurrencyAsOfDate(
-               acc, fn(acc, date), priv->commodity, (gnc_commodity*)report_commodity, date);
+               acc, fn(acc, date), priv->commodity, report_commodity, date);
 }
 
 /*
@@ -3769,7 +3769,7 @@ xaccAccountGetXxxBalanceInCurrencyRecursive (const Account *acc,
 static gnc_numeric
 xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive (
     Account *acc, time64 date, xaccGetBalanceAsOfDateFn fn,
-    gnc_commodity *report_commodity, gboolean include_children)
+    const gnc_commodity *report_commodity, gboolean include_children)
 {
     gnc_numeric balance;
 
@@ -3843,7 +3843,7 @@ xaccAccountGetPresentBalanceInCurrency (const Account *acc,
 {
     return xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive (
                (Account*)acc, gnc_time64_get_today_end (), xaccAccountGetBalanceAsOfDate,
-               (gnc_commodity*)report_commodity,
+               report_commodity,
                include_children);
 }
 
diff --git a/libgnucash/engine/Account.h b/libgnucash/engine/Account.h
index 9dbf9ca05..1e2504f2e 100644
--- a/libgnucash/engine/Account.h
+++ b/libgnucash/engine/Account.h
@@ -584,8 +584,8 @@ gnc_numeric xaccAccountConvertBalanceToCurrency(
     const gnc_commodity *new_currency);
 gnc_numeric xaccAccountConvertBalanceToCurrencyAsOfDate(
     const Account *account, /* for book */
-    gnc_numeric balance, gnc_commodity *balance_currency,
-    gnc_commodity *new_currency, time64 date);
+    gnc_numeric balance, const gnc_commodity *balance_currency,
+    const gnc_commodity *new_currency, time64 date);
 
 /* These functions get some type of balance in the desired commodity.
    'report_commodity' may be NULL to use the account's commodity. */
diff --git a/libgnucash/engine/gnc-pricedb.c b/libgnucash/engine/gnc-pricedb.c
index 422d62c3f..f3dae1dbd 100644
--- a/libgnucash/engine/gnc-pricedb.c
+++ b/libgnucash/engine/gnc-pricedb.c
@@ -2406,8 +2406,8 @@ gnc_pricedb_lookup_nearest_in_time64(GNCPriceDB *db,
 
 GNCPrice *
 gnc_pricedb_lookup_nearest_before_t64 (GNCPriceDB *db,
-                                       gnc_commodity *c,
-                                       gnc_commodity *currency,
+                                       const gnc_commodity *c,
+                                       const gnc_commodity *currency,
                                        time64 t)
 {
     GList *price_list;
@@ -2566,7 +2566,7 @@ 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_nearest_before_t64(db, (gnc_commodity*)from, (gnc_commodity*)to, t);
+        price = gnc_pricedb_lookup_nearest_before_t64(db, from, to, t);
     else
         price = gnc_pricedb_lookup_nearest_in_time64(db, from, to, t);
 
diff --git a/libgnucash/engine/gnc-pricedb.h b/libgnucash/engine/gnc-pricedb.h
index a0589f6d6..d64768240 100644
--- a/libgnucash/engine/gnc-pricedb.h
+++ b/libgnucash/engine/gnc-pricedb.h
@@ -539,8 +539,8 @@ PriceList * gnc_pricedb_lookup_nearest_in_time_any_currency_t64(GNCPriceDB *db,
  * @return A GNCPrice or NULL if no prices are found before t.
  */
 GNCPrice * gnc_pricedb_lookup_nearest_before_t64 (GNCPriceDB *db,
-                                                  gnc_commodity *c,
-                                                  gnc_commodity *currency,
+                                                  const gnc_commodity *c,
+                                                  const gnc_commodity *currency,
                                                   time64 t);
 
 /** @brief Return the nearest price between the given commodity and any other

commit e75308e6842644645aba1f593b260b4b6f6a3bcd
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Thu Apr 22 11:42:26 2021 +0100

    Rename a couple of gnc-pricedb functions that have not been used.
    
    To be more consistent change gnc_pricedb_lookup_latest_before_t64 and
    gnc_pricedb_lookup_latest_before_any_currency_t64 to be of the form
    '_nearest_before_' and add a missing utest.

diff --git a/libgnucash/engine/gnc-pricedb.c b/libgnucash/engine/gnc-pricedb.c
index c87787934..422d62c3f 100644
--- a/libgnucash/engine/gnc-pricedb.c
+++ b/libgnucash/engine/gnc-pricedb.c
@@ -2024,8 +2024,8 @@ PriceList *
 gnc_pricedb_lookup_latest_any_currency(GNCPriceDB *db,
                                        const gnc_commodity *commodity)
 {
-    return gnc_pricedb_lookup_latest_before_any_currency_t64(db, commodity,
-                                                         gnc_time(NULL));
+    return gnc_pricedb_lookup_nearest_before_any_currency_t64(db, commodity,
+                                                              gnc_time(NULL));
 }
 
 PriceList *
@@ -2049,9 +2049,9 @@ gnc_pricedb_lookup_nearest_in_time_any_currency_t64(GNCPriceDB *db,
 }
 
 PriceList *
-gnc_pricedb_lookup_latest_before_any_currency_t64(GNCPriceDB *db,
-                                                  const gnc_commodity *commodity,
-                                                  time64 t)
+gnc_pricedb_lookup_nearest_before_any_currency_t64(GNCPriceDB *db,
+                                                   const gnc_commodity *commodity,
+                                                   time64 t)
 {
     GList *prices = NULL, *result;
     UsesCommodity helper = {&prices, commodity, t};
@@ -2405,10 +2405,10 @@ gnc_pricedb_lookup_nearest_in_time64(GNCPriceDB *db,
 
 
 GNCPrice *
-gnc_pricedb_lookup_latest_before_t64 (GNCPriceDB *db,
-                                      gnc_commodity *c,
-                                      gnc_commodity *currency,
-                                      time64 t)
+gnc_pricedb_lookup_nearest_before_t64 (GNCPriceDB *db,
+                                       gnc_commodity *c,
+                                       gnc_commodity *currency,
+                                       time64 t)
 {
     GList *price_list;
     GNCPrice *current_price = NULL;
@@ -2533,9 +2533,9 @@ indirect_price_conversion (GNCPriceDB *db, const gnc_commodity *from,
     }
     else if (before_date)
     {
-        from_prices = gnc_pricedb_lookup_latest_before_any_currency_t64 (db, from, t);
+        from_prices = gnc_pricedb_lookup_nearest_before_any_currency_t64 (db, from, t);
         if (from_prices)
-            to_prices = gnc_pricedb_lookup_latest_before_any_currency_t64 (db, to, t);
+            to_prices = gnc_pricedb_lookup_nearest_before_any_currency_t64 (db, to, t);
     }
     else
     {
@@ -2566,7 +2566,7 @@ 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);
+        price = gnc_pricedb_lookup_nearest_before_t64(db, (gnc_commodity*)from, (gnc_commodity*)to, t);
     else
         price = gnc_pricedb_lookup_nearest_in_time64(db, from, to, t);
 
diff --git a/libgnucash/engine/gnc-pricedb.h b/libgnucash/engine/gnc-pricedb.h
index 8596d3294..a0589f6d6 100644
--- a/libgnucash/engine/gnc-pricedb.h
+++ b/libgnucash/engine/gnc-pricedb.h
@@ -527,7 +527,7 @@ PriceList * gnc_pricedb_lookup_nearest_in_time_any_currency_t64(GNCPriceDB *db,
         const gnc_commodity *c,
         time64 t);
 
-/** @brief Return the latest price between the given commodities before the
+/** @brief Return the nearest price between the given commodities before the
  * given time.
  *
  * The returned GNCPrice may be in either direction so check to ensure that its
@@ -538,12 +538,12 @@ PriceList * gnc_pricedb_lookup_nearest_in_time_any_currency_t64(GNCPriceDB *db,
  * @param t The time before which to find the price
  * @return A GNCPrice or NULL if no prices are found before t.
  */
-GNCPrice * gnc_pricedb_lookup_latest_before_t64(GNCPriceDB *db,
-                                                gnc_commodity *c,
-                                                gnc_commodity *currency,
-                                                time64 t);
+GNCPrice * gnc_pricedb_lookup_nearest_before_t64 (GNCPriceDB *db,
+                                                  gnc_commodity *c,
+                                                  gnc_commodity *currency,
+                                                  time64 t);
 
-/** @brief Return the latest price between the given commodity and any other
+/** @brief Return the nearest price between the given commodity and any other
  * before the given time.
  *
  * The returned GNCPrice may be in either direction so check to ensure that its
@@ -553,9 +553,9 @@ GNCPrice * gnc_pricedb_lookup_latest_before_t64(GNCPriceDB *db,
  * @param t The time before which to find prices
  * @return A PriceList of prices for each commodity found or NULL if none are.
  */
-PriceList * gnc_pricedb_lookup_latest_before_any_currency_t64(GNCPriceDB *db,
-                                                         const gnc_commodity *c,
-                                                              time64 t);
+PriceList * gnc_pricedb_lookup_nearest_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.
diff --git a/libgnucash/engine/test/utest-gnc-pricedb.c b/libgnucash/engine/test/utest-gnc-pricedb.c
index fdd24a824..eb1728b2b 100644
--- a/libgnucash/engine/test/utest-gnc-pricedb.c
+++ b/libgnucash/engine/test/utest-gnc-pricedb.c
@@ -1004,27 +1004,27 @@ test_gnc_pricedb_lookup_nearest_in_time_any_currency_t64 (PriceDBFixture *fixtur
 }
 
 // Not Used
-/* gnc_pricedb_lookup_latest_before_any_currency_t64
+/* gnc_pricedb_lookup_nearest_before_any_currency_t64
 PriceList *
-gnc_pricedb_lookup_latest_before_any_currency_t64(GNCPriceDB *db,// Local: 0:0:0
+gnc_pricedb_lookup_nearest_before_any_currency_t64(GNCPriceDB *db,// Local: 0:0:0
 */
 static void
-test_gnc_pricedb_lookup_latest_before_any_currency_t64 (PriceDBFixture *fixture,
-                                                    gconstpointer pData)
+test_gnc_pricedb_lookup_nearest_before_any_currency_t64 (PriceDBFixture *fixture,
+                                                         gconstpointer pData)
 {
     time64 t1 = gnc_dmy2time64(31, 7, 2013);
     time64 t2 = gnc_dmy2time64(5, 8, 2013);
     PriceList *prices =
-        gnc_pricedb_lookup_latest_before_any_currency_t64(fixture->pricedb,
-                                                        fixture->com->usd, t1);
+        gnc_pricedb_lookup_nearest_before_any_currency_t64 (fixture->pricedb,
+                                                            fixture->com->usd, t1);
     g_assert_cmpint(g_list_length(prices), ==, 4);
     prices = g_list_sort(prices, compare_price_commodities);
     g_assert_cmpstr(GET_COM_NAME(prices->next->data), ==, "AUD");
     g_assert_cmpstr(GET_CUR_NAME(prices->next->data), ==, "USD");
     gnc_price_list_destroy(prices);
     prices =
-        gnc_pricedb_lookup_latest_before_any_currency_t64(fixture->pricedb,
-                                                        fixture->com->usd, t2);
+        gnc_pricedb_lookup_nearest_before_any_currency_t64 (fixture->pricedb,
+                                                            fixture->com->usd, t2);
     g_assert_cmpint(g_list_length(prices), ==, 4);
     prices = g_list_sort(prices, compare_price_commodities);
     g_assert_cmpstr(GET_CUR_NAME(prices->next->data), ==, "AUD");
@@ -1120,20 +1120,51 @@ test_gnc_pricedb_lookup_nearest_in_time64 (PriceDBFixture *fixture, gconstpointe
         gnc_pricedb_lookup_nearest_in_time64(fixture->pricedb,
                                              fixture->com->usd,
                                              fixture->com->aud, t1);
+    gnc_numeric result = gnc_price_get_value (price);
+    g_assert_cmpint(result.num, ==, 103415);
+    g_assert_cmpint(result.denom, ==, 100000);
     g_assert_cmpstr(GET_COM_NAME(price), ==, "AUD");
     g_assert_cmpstr(GET_CUR_NAME(price), ==, "USD");
     price =
         gnc_pricedb_lookup_nearest_in_time64(fixture->pricedb,
                                              fixture->com->usd,
                                              fixture->com->aud, t2);
-    g_assert_cmpstr(GET_CUR_NAME(price), ==, "AUD");
+    result = gnc_price_get_value (price);
+    g_assert_cmpint(result.num, ==, 111878);
+    g_assert_cmpint(result.denom, ==, 100000);
     g_assert_cmpstr(GET_COM_NAME(price), ==, "USD");
+    g_assert_cmpstr(GET_CUR_NAME(price), ==, "AUD");
 }
-// Not Used
-/* gnc_pricedb_lookup_latest_before_t64
+
+/* gnc_pricedb_lookup_nearest_before_t64
 GNCPrice *
-gnc_pricedb_lookup_latest_before_t64 (GNCPriceDB *db,// Local: 0:0:0
+gnc_pricedb_lookup_nearest_before_t64 (GNCPriceDB *db,// Local: 0:0:0
 */
+static void
+test_gnc_pricedb_lookup_nearest_before_t64 (PriceDBFixture *fixture, gconstpointer pData)
+{
+    time64 t1 = gnc_dmy2time64(16, 11, 2012);
+    time64 t2 = gnc_dmy2time64(17, 11, 2012);
+    GNCPrice *price =
+        gnc_pricedb_lookup_nearest_before_t64(fixture->pricedb,
+                                             fixture->com->usd,
+                                             fixture->com->aud, t1);
+    gnc_numeric result = gnc_price_get_value (price);
+    g_assert_cmpint(result.num, ==, 106480);
+    g_assert_cmpint(result.denom, ==, 100000);
+    g_assert_cmpstr(GET_COM_NAME(price), ==, "AUD");
+    g_assert_cmpstr(GET_CUR_NAME(price), ==, "USD");
+    price =
+        gnc_pricedb_lookup_nearest_before_t64(fixture->pricedb,
+                                             fixture->com->usd,
+                                             fixture->com->aud, t2);
+    result = gnc_price_get_value (price);
+    g_assert_cmpint(result.num, ==, 103415);
+    g_assert_cmpint(result.denom, ==, 100000);
+    g_assert_cmpstr(GET_COM_NAME(price), ==, "AUD");
+    g_assert_cmpstr(GET_CUR_NAME(price), ==, "USD");
+
+}
 /* direct_balance_conversion
 static gnc_numeric
 direct_balance_conversion (GNCPriceDB *db, gnc_numeric bal,// Local: 2:0:0
@@ -1651,13 +1682,14 @@ test_suite_gnc_pricedb (void)
 // GNC_TEST_ADD (suitename, "nearest to", Fixture, NULL, setup, test_nearest_to, teardown);
     GNC_TEST_ADD (suitename, "gnc pricedb lookup latest any currency", PriceDBFixture, NULL, setup, test_gnc_pricedb_lookup_latest_any_currency, teardown);
     GNC_TEST_ADD (suitename, "gnc pricedb lookup nearest in time any currency", PriceDBFixture, NULL, setup, test_gnc_pricedb_lookup_nearest_in_time_any_currency_t64, teardown);
-    GNC_TEST_ADD (suitename, "gnc pricedb lookup latest before any currency", PriceDBFixture, NULL, setup, test_gnc_pricedb_lookup_latest_before_any_currency_t64, teardown);
+    GNC_TEST_ADD (suitename, "gnc pricedb lookup nearest before any currency", PriceDBFixture, NULL, setup, test_gnc_pricedb_lookup_nearest_before_any_currency_t64, teardown);
 // GNC_TEST_ADD (suitename, "hash values helper", PriceDBFixture, NULL, setup, test_hash_values_helper, teardown);
     GNC_TEST_ADD (suitename, "gnc pricedb has prices", PriceDBFixture, NULL, setup, test_gnc_pricedb_has_prices, teardown);
     GNC_TEST_ADD (suitename, "gnc pricedb get prices", PriceDBFixture, NULL, setup, test_gnc_pricedb_get_prices, teardown);
     GNC_TEST_ADD (suitename, "gnc pricedb lookup day", PriceDBFixture, NULL, setup, test_gnc_pricedb_lookup_day_t64, teardown);
 // GNC_TEST_ADD (suitename, "lookup nearest in time", Fixture, NULL, setup, test_lookup_nearest_in_time, teardown);
     GNC_TEST_ADD (suitename, "gnc pricedb lookup nearest in time", PriceDBFixture, NULL, setup, test_gnc_pricedb_lookup_nearest_in_time64, teardown);
+    GNC_TEST_ADD (suitename, "gnc pricedb lookup nearest before in time", PriceDBFixture, NULL, setup, test_gnc_pricedb_lookup_nearest_before_t64, teardown);
 // GNC_TEST_ADD (suitename, "direct balance conversion", Fixture, NULL, setup, test_direct_balance_conversion, teardown);
 // GNC_TEST_ADD (suitename, "extract common prices", Fixture, NULL, setup, test_extract_common_prices, teardown);
 // GNC_TEST_ADD (suitename, "convert balance", Fixture, NULL, setup, test_convert_balance, teardown);

commit d3bd7fda61aefc5a4f15041454f0179c42bba3a7
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Wed Apr 21 14:33:56 2021 +0100

    Add unit tests for new gnc-pricedb functions

diff --git a/libgnucash/engine/test/utest-gnc-pricedb.c b/libgnucash/engine/test/utest-gnc-pricedb.c
index daf34df4f..fdd24a824 100644
--- a/libgnucash/engine/test/utest-gnc-pricedb.c
+++ b/libgnucash/engine/test/utest-gnc-pricedb.c
@@ -1249,6 +1249,48 @@ test_gnc_pricedb_convert_balance_nearest_price_t64 (PriceDBFixture *fixture, gco
 
 }
 
+static void
+test_gnc_pricedb_convert_balance_nearest_before_price_t64 (PriceDBFixture *fixture, gconstpointer pData)
+{
+    time64 t = gnc_dmy2time64(16, 11, 2012);
+    gnc_numeric from = gnc_numeric_create(10000, 100);
+    gnc_numeric result =
+        gnc_pricedb_convert_balance_nearest_before_price_t64(fixture->pricedb, from,
+                                                            fixture->com->usd,
+                                                            fixture->com->aud, t);
+    g_assert_cmpint(result.num, ==, 9391);
+    g_assert_cmpint(result.denom, ==, 100);
+    result = gnc_pricedb_convert_balance_nearest_before_price_t64(fixture->pricedb,
+                                                                 from,
+                                                                 fixture->com->usd,
+                                                                 fixture->com->gbp,
+                                                                 t);
+    g_assert_cmpint(result.num, ==, 6223);
+    g_assert_cmpint(result.denom, ==, 100);
+    result = gnc_pricedb_convert_balance_nearest_before_price_t64(fixture->pricedb,
+                                                                 from,
+                                                                 fixture->com->usd,
+                                                                 fixture->com->eur,
+                                                                 t);
+    g_assert_cmpint(result.num, ==, 7720);
+    g_assert_cmpint(result.denom, ==, 100);
+    result = gnc_pricedb_convert_balance_nearest_before_price_t64(fixture->pricedb,
+                                                                 from,
+                                                                 fixture->com->gbp,
+                                                                 fixture->com->dkk,
+                                                                 t);
+    g_assert_cmpint(result.num, ==, 83960);
+    g_assert_cmpint(result.denom, ==, 100);
+    result = gnc_pricedb_convert_balance_nearest_before_price_t64(fixture->pricedb,
+                                                                 from,
+                                                                 fixture->com->amzn,
+                                                                 fixture->com->aud,
+                                                                 t);
+    g_assert_cmpint(result.num, ==, 2089782);
+    g_assert_cmpint(result.denom, ==, 100);
+
+}
+
 static void
 test_gnc_pricedb_get_latest_price (PriceDBFixture *fixture, gconstpointer pData)
 {
@@ -1326,6 +1368,46 @@ test_gnc_pricedb_get_nearest_price (PriceDBFixture *fixture, gconstpointer pData
     g_assert_cmpint(result.denom, ==, 1331);
 }
 
+static void
+test_gnc_pricedb_get_nearest_before_price (PriceDBFixture *fixture, gconstpointer pData)
+{
+    time64 t = gnc_dmy2time64(16, 11, 2012);
+    gnc_numeric result;
+
+    result = gnc_pricedb_get_nearest_before_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_before_price (fixture->pricedb,
+                                                   fixture->com->usd,
+                                                   fixture->com->gbp,
+                                                   t);
+    g_assert_cmpint(result.num, ==, 20000);
+    g_assert_cmpint(result.denom, ==, 32141);
+
+    result = gnc_pricedb_get_nearest_before_price (fixture->pricedb,
+                                                   fixture->com->usd,
+                                                   fixture->com->eur,
+                                                   t);
+    g_assert_cmpint(result.num, ==, 124072);
+    g_assert_cmpint(result.denom, ==, 160705);
+
+    result = gnc_pricedb_get_nearest_before_price (fixture->pricedb,
+                                                   fixture->com->gbp,
+                                                   fixture->com->dkk,
+                                                   t);
+    g_assert_cmpint(result.num, ==, 16792033309);
+    g_assert_cmpint(result.denom, ==, 2000000000);
+
+    result = gnc_pricedb_get_nearest_before_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
@@ -1582,8 +1664,10 @@ 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 convert balance nearest before price", PriceDBFixture, NULL, setup, test_gnc_pricedb_convert_balance_nearest_before_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, "gnc pricedb get nearest before price", PriceDBFixture, NULL, setup, test_gnc_pricedb_get_nearest_before_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);

commit 4a491f7cdee5cdc3706c3c2b47c8ed11689ef3c8
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Wed Apr 21 14:33:19 2021 +0100

    Change a couple of docbook definitions in gnc-pricdb.h

diff --git a/libgnucash/engine/gnc-pricedb.h b/libgnucash/engine/gnc-pricedb.h
index 8cf91d903..8596d3294 100644
--- a/libgnucash/engine/gnc-pricedb.h
+++ b/libgnucash/engine/gnc-pricedb.h
@@ -538,7 +538,6 @@ PriceList * gnc_pricedb_lookup_nearest_in_time_any_currency_t64(GNCPriceDB *db,
  * @param t The time before which to find the price
  * @return A GNCPrice or NULL if no prices are found before t.
  */
-/* NOT USED, but see bug 743753 */
 GNCPrice * gnc_pricedb_lookup_latest_before_t64(GNCPriceDB *db,
                                                 gnc_commodity *c,
                                                 gnc_commodity *currency,
@@ -554,7 +553,6 @@ GNCPrice * gnc_pricedb_lookup_latest_before_t64(GNCPriceDB *db,
  * @param t The time before which to find prices
  * @return A PriceList of prices for each commodity found or NULL if none are.
  */
-/* NOT USED, but see bug 743753 */
 PriceList * gnc_pricedb_lookup_latest_before_any_currency_t64(GNCPriceDB *db,
                                                          const gnc_commodity *c,
                                                               time64 t);
@@ -573,19 +571,27 @@ gnc_numeric gnc_pricedb_get_nearest_before_price (GNCPriceDB *pdb,
                                                   const gnc_commodity *new_currency,
                                                   const time64 t);
 
-/** @brief Retrieve the price one currency to another at specified date
+/** @brief Retrieve the price one currency to another using the price
+ * nearest to 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 in which the nearest price should be used.
  * @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);
 
+/** @brief Retrieve the price one currency to another using the latest price
+ * @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_latest_price (GNCPriceDB *pdb,
                                           const gnc_commodity *orig_currency,
                                           const gnc_commodity *new_currency);

commit 05507008c5cbce6fdfeb8f4daf6c2c409ced7de9
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Wed Apr 21 14:32:40 2021 +0100

    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.

diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index c1d598f3c..b36f10bbb 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -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;
diff --git a/libgnucash/engine/gnc-pricedb.c b/libgnucash/engine/gnc-pricedb.c
index 4d3bc23c2..c87787934 100644
--- a/libgnucash/engine/gnc-pricedb.c
+++ b/libgnucash/engine/gnc-pricedb.c
@@ -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
diff --git a/libgnucash/engine/gnc-pricedb.h b/libgnucash/engine/gnc-pricedb.h
index 1d9db26e4..8cf91d903 100644
--- a/libgnucash/engine/gnc-pricedb.h
+++ b/libgnucash/engine/gnc-pricedb.h
@@ -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

commit b54c30e03ddaf65c93c5f2cd1e7386a62c2b7772
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Tue Apr 20 13:29:57 2021 +0100

    Bug 798148 - Chart of Accounts page Present(xxx) value wrong
    
    If for some reason you have price information in the future for a
    security, the present value is based on the price retrieved for the
    greatest date and not a price which is before the current date.
    
    To fix this use the 'xaccAccountGetBalanceAsOfDateInCurrencyRecursive'
    function.

diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index 109297db6..c1d598f3c 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -3666,8 +3666,8 @@ xaccAccountGetXxxBalanceAsOfDateInCurrency(Account *acc, time64 date,
     g_return_val_if_fail(GNC_IS_COMMODITY(report_commodity), gnc_numeric_zero());
 
     priv = GET_PRIVATE(acc);
-    return xaccAccountConvertBalanceToCurrency(
-               acc, fn(acc, date), priv->commodity, report_commodity);
+    return xaccAccountConvertBalanceToCurrencyAsOfDate(
+               acc, fn(acc, date), priv->commodity, (gnc_commodity*)report_commodity, date);
 }
 
 /*
@@ -3841,8 +3841,9 @@ xaccAccountGetPresentBalanceInCurrency (const Account *acc,
                                         const gnc_commodity *report_commodity,
                                         gboolean include_children)
 {
-    return xaccAccountGetXxxBalanceInCurrencyRecursive (
-               acc, xaccAccountGetPresentBalance, report_commodity,
+    return xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive (
+               (Account*)acc, gnc_time64_get_today_end (), xaccAccountGetBalanceAsOfDate,
+               (gnc_commodity*)report_commodity,
                include_children);
 }
 



Summary of changes:
 bindings/python/deprecation.py             |  29 +++++-
 bindings/python/gnucash_core.py            |  14 ++-
 libgnucash/engine/Account.cpp              |  17 ++--
 libgnucash/engine/Account.h                |   4 +-
 libgnucash/engine/gnc-pricedb.c            |  88 +++++++++++++-----
 libgnucash/engine/gnc-pricedb.h            |  62 ++++++++++---
 libgnucash/engine/test/utest-gnc-pricedb.c | 142 ++++++++++++++++++++++++++---
 7 files changed, 293 insertions(+), 63 deletions(-)



More information about the gnucash-changes mailing list