gnucash master: Multiple changes pushed

John Ralls jralls at code.gnucash.org
Fri Mar 11 19:32:54 EST 2016


Updated	 via  https://github.com/Gnucash/gnucash/commit/71f7f457 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/18e61004 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/a4069037 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/1ca56c9d (commit)
	 via  https://github.com/Gnucash/gnucash/commit/c4ce44df (commit)
	 via  https://github.com/Gnucash/gnucash/commit/e26e598c (commit)
	 via  https://github.com/Gnucash/gnucash/commit/ba4acdfe (commit)
	 via  https://github.com/Gnucash/gnucash/commit/2ed85cef (commit)
	 via  https://github.com/Gnucash/gnucash/commit/afe7dacb (commit)
	 via  https://github.com/Gnucash/gnucash/commit/56cb0327 (commit)
	from  https://github.com/Gnucash/gnucash/commit/3a86998e (commit)



commit 71f7f45777024fc080a0098341903316cca20459
Merge: 3a86998 18e6100
Author: John Ralls <jralls at ceridwen.us>
Date:   Fri Mar 11 16:32:20 2016 -0800

    Merge branch 'maint'


commit 18e61004110663a979228711495c644f0247311e
Merge: 2ed85ce a406903
Author: John Ralls <jralls at ceridwen.us>
Date:   Fri Mar 11 15:46:45 2016 -0800

    Bug 763146 - Invalid exchange rate is recorded when entering multi-currency transaction
    
    A bunch of little fixes grouped into a feature branch.


commit a4069037055d92755be154fc72da53ea0dc79fc8
Author: John Ralls <jralls at ceridwen.us>
Date:   Fri Mar 11 15:43:30 2016 -0800

    Ensure numerator is positive before checking if the value is < 1.

diff --git a/src/gnome-utils/dialog-transfer.c b/src/gnome-utils/dialog-transfer.c
index 7d84370..eefc5d1 100644
--- a/src/gnome-utils/dialog-transfer.c
+++ b/src/gnome-utils/dialog-transfer.c
@@ -1631,6 +1631,7 @@ new_price(XferDialog *xferData, Timespec ts)
 /* We want to store currency rates such that the rate > 1 and commodity
  * prices in terms of a currency regardless of value.
  */
+    value = gnc_numeric_abs(value);
     if (gnc_commodity_is_currency(from) && gnc_commodity_is_currency(to))
     {
         if (value.num < value.denom)

commit 1ca56c9d0df55037a7515f78dd81abed1fe9df95
Author: John Ralls <jralls at ceridwen.us>
Date:   Fri Mar 11 15:42:53 2016 -0800

    Ensure price is set when the amount is entered and user doesn't tab out.

diff --git a/src/gnome-utils/dialog-transfer.c b/src/gnome-utils/dialog-transfer.c
index 67813f4..7d84370 100644
--- a/src/gnome-utils/dialog-transfer.c
+++ b/src/gnome-utils/dialog-transfer.c
@@ -1748,6 +1748,8 @@ gnc_xfer_dialog_response_cb (GtkDialog *dialog, gint response, gpointer data)
             gnc_xfer_update_to_amount(xferData);
 
         price_value = gnc_xfer_dialog_compute_price_value(xferData);
+        gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(xferData->price_edit),
+                                   price_value);
         *(xferData->exch_rate) = gnc_numeric_abs(price_value);
     }
     else

commit c4ce44df64ed8ad3d83f369d9a0e2856ad3cfd90
Author: John Ralls <jralls at ceridwen.us>
Date:   Fri Mar 11 15:10:12 2016 -0800

    Test rounded values, but don't store them, to minimize jitter in prices.

diff --git a/src/gnome-utils/dialog-transfer.c b/src/gnome-utils/dialog-transfer.c
index 5e0b1ec..67813f4 100644
--- a/src/gnome-utils/dialog-transfer.c
+++ b/src/gnome-utils/dialog-transfer.c
@@ -1586,15 +1586,21 @@ update_price(XferDialog *xferData, PriceReq *pr)
     gnc_commodity *to = xferData->to_commodity;
     gnc_numeric value = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->price_edit));
     gnc_numeric price_value = gnc_price_get_value(pr->price);
+    gnc_numeric rounded_pr_value = round_price(pr->from, pr->to, price_value);
+    gnc_numeric rounded_value;
 
-    if (gnc_numeric_equal(pr->reverse ? gnc_numeric_invert(value) : value,
-                          price_value))
     if (gnc_price_get_source(pr->price) < xferData->price_source)
     {
         PINFO("Existing price is preferred, so won't supersede.");
         gnc_price_unref (pr->price);
         return;
     }
+
+    if (pr->reverse)
+        value = swap_commodities(&from, &to, value);
+    /* Test the rounded values for equality to minimize price-dithering. */
+    rounded_value = round_price(from, to, value);
+    if (gnc_numeric_equal(rounded_value, rounded_pr_value))
     {
         PINFO("Same price for %s in %s",
               gnc_commodity_get_mnemonic(pr->from),
@@ -1605,10 +1611,7 @@ update_price(XferDialog *xferData, PriceReq *pr)
     gnc_price_begin_edit (pr->price);
     gnc_price_set_time (pr->price, pr->ts);
     gnc_price_set_typestr(pr->price, xferData->price_type);
-    if (pr->reverse)
-        gnc_price_set_value (pr->price, gnc_numeric_invert(value));
-    else
-        gnc_price_set_value (pr->price, value);
+    gnc_price_set_value (pr->price, value);
     gnc_price_commit_edit (pr->price);
     PINFO("Updated price: 1 %s = %f %s",
           gnc_commodity_get_mnemonic(pr->from),

commit e26e598cdc8f635d9a7700e8732b401d619e3dd5
Author: John Ralls <jralls at ceridwen.us>
Date:   Fri Mar 11 15:08:11 2016 -0800

    Check price_source precedence first to save computation.

diff --git a/src/gnome-utils/dialog-transfer.c b/src/gnome-utils/dialog-transfer.c
index 66d148a..5e0b1ec 100644
--- a/src/gnome-utils/dialog-transfer.c
+++ b/src/gnome-utils/dialog-transfer.c
@@ -1589,16 +1589,16 @@ update_price(XferDialog *xferData, PriceReq *pr)
 
     if (gnc_numeric_equal(pr->reverse ? gnc_numeric_invert(value) : value,
                           price_value))
+    if (gnc_price_get_source(pr->price) < xferData->price_source)
     {
-        PINFO("Same price for %s in %s",
-              gnc_commodity_get_mnemonic(pr->from),
-              gnc_commodity_get_mnemonic(pr->to));
+        PINFO("Existing price is preferred, so won't supersede.");
         gnc_price_unref (pr->price);
         return;
     }
-    if (gnc_price_get_source(pr->price) < xferData->price_source)
     {
-        PINFO("Existing price is preferred, so won't supersede.");
+        PINFO("Same price for %s in %s",
+              gnc_commodity_get_mnemonic(pr->from),
+              gnc_commodity_get_mnemonic(pr->to));
         gnc_price_unref (pr->price);
         return;
     }

commit ba4acdfef1919ae27fc1c6b12822aa605f88676a
Author: John Ralls <jralls at ceridwen.us>
Date:   Fri Mar 11 15:03:19 2016 -0800

    Ensure that xferData->price_source is always set correctly.
    
    If the user doesn't tab out of the price window before pressing return
    or clicking OK gnc_xfer_price_update_cb isn't called, but it does call
    gnc_xfer_update_to_amount, which does get called by
    gnc_xfer_dialog_response_cb.

diff --git a/src/gnome-utils/dialog-transfer.c b/src/gnome-utils/dialog-transfer.c
index 6b72a0a..66d148a 100644
--- a/src/gnome-utils/dialog-transfer.c
+++ b/src/gnome-utils/dialog-transfer.c
@@ -1016,6 +1016,8 @@ gnc_xfer_update_to_amount (XferDialog *xferData)
 
     g_return_if_fail(xferData);
 
+    xferData->price_source = PRICE_SOURCE_USER_PRICE;
+
     /* Get the amount editing controls of the dialog. */
     amount_edit     = GNC_AMOUNT_EDIT(xferData->amount_edit);
     price_edit      = GNC_AMOUNT_EDIT(xferData->price_edit);
@@ -1056,7 +1058,6 @@ gnc_xfer_price_update_cb(GtkWidget *widget, GdkEventFocus *event,
     XferDialog *xferData = data;
 
     gnc_xfer_update_to_amount (xferData);
-    xferData->price_source = PRICE_SOURCE_USER_PRICE;
     xferData->price_type = PRICE_TYPE_TRN;
 
 

commit 2ed85cefa3150dc0cfbcd147126fbfe2010e8b90
Author: John Ralls <jralls at ceridwen.us>
Date:   Fri Mar 11 13:23:23 2016 -0800

    Fix double semicolon.

diff --git a/src/gnome-utils/dialog-transfer.c b/src/gnome-utils/dialog-transfer.c
index fb204f9..6b72a0a 100644
--- a/src/gnome-utils/dialog-transfer.c
+++ b/src/gnome-utils/dialog-transfer.c
@@ -1583,7 +1583,7 @@ update_price(XferDialog *xferData, PriceReq *pr)
 {
     gnc_commodity *from = xferData->from_commodity;
     gnc_commodity *to = xferData->to_commodity;
-    gnc_numeric value = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->price_edit));;
+    gnc_numeric value = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->price_edit));
     gnc_numeric price_value = gnc_price_get_value(pr->price);
 
     if (gnc_numeric_equal(pr->reverse ? gnc_numeric_invert(value) : value,

commit afe7dacb8501f0bf3187dc29c40f04eac906dd28
Author: John Ralls <jralls at ceridwen.us>
Date:   Fri Mar 11 12:59:01 2016 -0800

    Remove price-direction code for to default currency and alphabetic order.
    
    It's much more important to have currency exchange rates > 1 to preserve
    significant digits.

diff --git a/src/gnome-utils/dialog-transfer.c b/src/gnome-utils/dialog-transfer.c
index d9d7938..fb204f9 100644
--- a/src/gnome-utils/dialog-transfer.c
+++ b/src/gnome-utils/dialog-transfer.c
@@ -1567,20 +1567,6 @@ create_transaction(XferDialog *xferData, Timespec *ts,
         xferData->transaction_cb(trans, xferData->transaction_user_data);
 }
 
-static void
-swap_amount (gnc_commodity **from, gnc_commodity **to, gnc_numeric *value,
-             gnc_numeric *from_amt, gnc_numeric *to_amt)
-{
-    gnc_commodity *tmp = *from;
-    gnc_numeric *tmp_amt = from_amt;
-    *from = *to;
-    *to = tmp;
-    from_amt = to_amt;
-    to_amt = tmp_amt;
-    *value = gnc_numeric_invert (*value);
-    *value = round_price(*from, *to, *value);
-}
-
 static gnc_numeric
 swap_commodities(gnc_commodity **from, gnc_commodity **to, gnc_numeric value)
 {
@@ -1637,37 +1623,19 @@ new_price(XferDialog *xferData, Timespec ts)
     gnc_commodity *from = xferData->from_commodity;
     gnc_commodity *to = xferData->to_commodity;
     gnc_numeric value = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->price_edit));
-    gnc_numeric from_amt, to_amt;
 
-/* Normally we want to store currency rates such that the rate > 1 and commodity
- * prices in terms of a currency regardless of value, but we also try to be
- * consistent about how quotes are installed.
+/* We want to store currency rates such that the rate > 1 and commodity
+ * prices in terms of a currency regardless of value.
  */
-    if (from == gnc_default_currency() ||
-        ((to != gnc_default_currency()) &&
-         (strcmp (gnc_commodity_get_mnemonic(from),
-                  gnc_commodity_get_mnemonic(to)) < 0)))
-        swap_amount (&from, &to, &value, &from_amt, &to_amt);
-
     if (gnc_commodity_is_currency(from) && gnc_commodity_is_currency(to))
     {
         if (value.num < value.denom)
-        {
             value = swap_commodities(&from, &to, value);
-        }
-        value = gnc_numeric_convert(value, CURRENCY_DENOM,
-                                    GNC_HOW_RND_ROUND_HALF_UP);
     }
-    else if (gnc_commodity_is_currency(from) || gnc_commodity_is_currency(to))
-    {
-        int scu;
-        if (gnc_commodity_is_currency(from))
+    else if (gnc_commodity_is_currency(from))
             value = swap_commodities(&from, &to, value);
-        scu = gnc_commodity_get_fraction (to);
-        value = gnc_numeric_convert(value, scu * COMMODITY_DENOM_MULT,
-                                    GNC_HOW_RND_ROUND_HALF_UP);
-    }
 
+    value = round_price (from, to, value);
     price = gnc_price_create (xferData->book);
     gnc_price_begin_edit (price);
     gnc_price_set_commodity (price, from);

commit 56cb0327e18625a292d9e32a9e21420b51d9bca4
Author: John Ralls <jralls at ceridwen.us>
Date:   Fri Mar 11 12:22:57 2016 -0800

    Extract functions update_price and new_price from create_price.

diff --git a/src/gnome-utils/dialog-transfer.c b/src/gnome-utils/dialog-transfer.c
index 7826e6b..d9d7938 100644
--- a/src/gnome-utils/dialog-transfer.c
+++ b/src/gnome-utils/dialog-transfer.c
@@ -1593,74 +1593,62 @@ swap_commodities(gnc_commodity **from, gnc_commodity **to, gnc_numeric value)
 }
 
 static void
-create_price(XferDialog *xferData, Timespec ts)
+update_price(XferDialog *xferData, PriceReq *pr)
 {
-    PriceReq pr;
-    GNCPrice *price = NULL;
     gnc_commodity *from = xferData->from_commodity;
     gnc_commodity *to = xferData->to_commodity;
-    gnc_numeric price_value;
-    gnc_numeric value;
-    gnc_numeric from_amt, to_amt;
-    gboolean swap = FALSE;
+    gnc_numeric value = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->price_edit));;
+    gnc_numeric price_value = gnc_price_get_value(pr->price);
 
-/* Bail in the unlikely event that both currencies have joined the Euro. */
-    if (gnc_is_euro_currency (from) && gnc_is_euro_currency (to))
+    if (gnc_numeric_equal(pr->reverse ? gnc_numeric_invert(value) : value,
+                          price_value))
+    {
+        PINFO("Same price for %s in %s",
+              gnc_commodity_get_mnemonic(pr->from),
+              gnc_commodity_get_mnemonic(pr->to));
+        gnc_price_unref (pr->price);
+        return;
+    }
+    if (gnc_price_get_source(pr->price) < xferData->price_source)
+    {
+        PINFO("Existing price is preferred, so won't supersede.");
+        gnc_price_unref (pr->price);
         return;
+    }
+    gnc_price_begin_edit (pr->price);
+    gnc_price_set_time (pr->price, pr->ts);
+    gnc_price_set_typestr(pr->price, xferData->price_type);
+    if (pr->reverse)
+        gnc_price_set_value (pr->price, gnc_numeric_invert(value));
+    else
+        gnc_price_set_value (pr->price, value);
+    gnc_price_commit_edit (pr->price);
+    PINFO("Updated price: 1 %s = %f %s",
+          gnc_commodity_get_mnemonic(pr->from),
+          gnc_numeric_to_double(gnc_price_get_value(pr->price)),
+          gnc_commodity_get_mnemonic(pr->to));
+    gnc_price_unref (pr->price);
+}
+
+static void
+new_price(XferDialog *xferData, Timespec ts)
+{
+    GNCPrice *price = NULL;
+    gnc_commodity *from = xferData->from_commodity;
+    gnc_commodity *to = xferData->to_commodity;
+    gnc_numeric value = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->price_edit));
+    gnc_numeric from_amt, to_amt;
 
-    value = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->price_edit));
-    /* Try to be consistent about how quotes are installed. */
+/* Normally we want to store currency rates such that the rate > 1 and commodity
+ * prices in terms of a currency regardless of value, but we also try to be
+ * consistent about how quotes are installed.
+ */
     if (from == gnc_default_currency() ||
         ((to != gnc_default_currency()) &&
          (strcmp (gnc_commodity_get_mnemonic(from),
                   gnc_commodity_get_mnemonic(to)) < 0)))
         swap_amount (&from, &to, &value, &from_amt, &to_amt);
 
-/* 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. */
-
-    price_request_from_xferData(&pr, xferData);
-    if (lookup_price(&pr, SAME_DAY))
-    {
-        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(pr.from),
-                  gnc_commodity_get_mnemonic(pr.to));
-            gnc_price_unref (pr.price);
-            return;
-        }
-        if (gnc_price_get_source(pr.price) < xferData->price_source)
-        {
-            PINFO("Existing price is preferred, so won't supersede.");
-            gnc_price_unref (pr.price);
-            return;
-        }
-        if (pr.reverse)
-        {
-            value = swap_commodities(&from, &to, value);
-            xferData->from_commodity = from;
-            xferData->to_commodity = to;
-        }
-        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, xferData->price_source);
-        gnc_price_set_typestr(pr.price, xferData->price_type);
-        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))
     {
         if (value.num < value.denom)
@@ -1679,6 +1667,7 @@ create_price(XferDialog *xferData, Timespec ts)
         value = gnc_numeric_convert(value, scu * COMMODITY_DENOM_MULT,
                                     GNC_HOW_RND_ROUND_HALF_UP);
     }
+
     price = gnc_price_create (xferData->book);
     gnc_price_begin_edit (price);
     gnc_price_set_commodity (price, from);
@@ -1692,6 +1681,25 @@ create_price(XferDialog *xferData, Timespec ts)
     PINFO("Created price: 1 %s = %f %s", gnc_commodity_get_mnemonic(from),
           gnc_numeric_to_double(value), gnc_commodity_get_mnemonic(to));
     gnc_price_unref (price);
+}    
+
+static void
+create_price(XferDialog *xferData, Timespec ts)
+{
+    PriceReq pr;
+
+/* Bail in the unlikely event that both currencies have joined the Euro. */
+    if (gnc_is_euro_currency (xferData->from_commodity) &&
+        gnc_is_euro_currency (xferData->to_commodity))
+        return;
+
+    price_request_from_xferData(&pr, xferData);
+    if (lookup_price(&pr, SAME_DAY))
+    {
+        update_price(xferData, &pr);
+        return;
+    }
+    new_price (xferData, ts);
 }
 
 void



Summary of changes:
 src/gnome-utils/dialog-transfer.c | 135 +++++++++++++++++++-------------------
 1 file changed, 69 insertions(+), 66 deletions(-)



More information about the gnucash-changes mailing list