gnucash master: Book-Currency Feature step 5

J. Alex Aycinena alex.aycinena at code.gnucash.org
Fri Jun 17 17:05:05 EDT 2016


Updated	 via  https://github.com/Gnucash/gnucash/commit/3ded9f9b (commit)
	from  https://github.com/Gnucash/gnucash/commit/2bbc1a19 (commit)



commit 3ded9f9b5627b4f05a811bb8347b085443ee59d8
Author: Alex Aycinena <alex.aycinena at gmail.com>
Date:   Fri Jun 17 13:48:03 2016 -0700

    Book-Currency Feature step 5
    
    Save a default gain/loss account in a book KVP and clean up some other book-currency items.
    
    The changes made are:
    
    	app-utils/gnc-ui-util.c & h - define new functions:
                gnc_book_get_book_currency_name,
                gnc_book_get_default_gain_loss_acct;
            reflect changed function names: qof_book_get_book_currency_name,
                gnc_valid_policy_name
    	app-utils/options.scm - reflect changed function name: gnc-valid-policy-name
    	app-utils/test/test-gnc-ui-util.c - include tests for gnc_book_get_default_gain_loss_acct;
            reflect changed function name: gnc_book_get_book_currency_name
    	engine/policy-p.h - add policy name, description and hint to policy structure
    	engine/policy.c & h - simplify gnc_get_valid_policy_list & define new functions:
                gnc_valid_policy, PolicyGetName, PolicyGetDescription,
                PolicyGetHint, xaccGetLIFOPolicy
    	gnome-utils/dialog-options.c - conform to changes to gnc_get_valid_policy_list
            and use new function gnc_cost_policy_select_new
    	gnome-utils/dialog-utils.c & h - define new function: gnc_cost_policy_select_new
    	libqof/qof/qofbook.cpp & h - define new property: PROP_OPT_DEFAULT_GAINS_ACCOUNT_GUID
            and new function: qof_book_get_default_gain_loss_acct_guid
            changed function name: qof_book_get_book_currency_name
    	libqof/qof/qofbookslots.h - define new option: OPTION_NAME_DEFAULT_GAINS_LOSS_ACCT_GUID
    	libqof/qof/test/test-qofbook.c - reflect changed function names: qof_book_get_book_currency_name,
                gnc_valid_policy_name; add test for qof_book_get_default_gain_loss_acct_guid

diff --git a/src/app-utils/gnc-ui-util.c b/src/app-utils/gnc-ui-util.c
index 54295ee..3b988e6 100644
--- a/src/app-utils/gnc-ui-util.c
+++ b/src/app-utils/gnc-ui-util.c
@@ -295,7 +295,7 @@ gnc_book_use_book_currency (QofBook *book)
     if (!book) return FALSE;
 
     policy = qof_book_get_default_gains_policy (book);
-    currency = qof_book_get_book_currency (book);
+    currency = qof_book_get_book_currency_name (book);
 
     /* If either a default gain/loss policy or a book-currency does not exist,
        book-currency accounting method not valid */
@@ -303,11 +303,11 @@ gnc_book_use_book_currency (QofBook *book)
        return FALSE;
 
     /* If both exist, both must be valid */
-    if (!gnc_valid_policy (policy) || !gnc_commodity_table_lookup
-                                        (gnc_commodity_table_get_table
-                                          (gnc_get_current_book()),
-                                            GNC_COMMODITY_NS_CURRENCY,
-                                             currency))
+    if (!gnc_valid_policy_name (policy) || !gnc_commodity_table_lookup
+                                            (gnc_commodity_table_get_table
+                                              (gnc_get_current_book()),
+                                                GNC_COMMODITY_NS_CURRENCY,
+                                                 currency))
        return FALSE;
 
     /* If both exist and are valid, there must be no trading accounts flag */
@@ -322,12 +322,30 @@ gnc_book_use_book_currency (QofBook *book)
   * both are valid, a requirement for the 'book-currency' currency accounting
   * method to apply. */
 const gchar *
+gnc_book_get_book_currency_name (QofBook *book)
+{
+    if (!book) return NULL;
+
+    if (gnc_book_use_book_currency (book))
+        return qof_book_get_book_currency_name (book);
+
+    return NULL;
+}
+
+/** Returns pointer to Book Currency for book or NULL; determines
+  * that both book-currency and default gain/loss policy KVPs exist and that
+  * both are valid, a requirement for the 'book-currency' currency accounting
+  * method to apply. */
+gnc_commodity *
 gnc_book_get_book_currency (QofBook *book)
 {
     if (!book) return NULL;
 
     if (gnc_book_use_book_currency (book))
-        return qof_book_get_book_currency (book);
+        return gnc_commodity_table_lookup
+                    (gnc_commodity_table_get_table(book),
+                     GNC_COMMODITY_NS_CURRENCY,
+                     qof_book_get_book_currency_name (book));
 
     return NULL;
 }
@@ -347,6 +365,24 @@ gnc_book_get_default_gains_policy (QofBook *book)
     return NULL;
 }
 
+/** Returns pointer to default gain/loss account for book or NULL; determines
+  * that both book-currency and default gain/loss policy KVPs exist and that
+  * both are valid, a requirement for the 'book-currency' currency accounting
+  * method to apply. */
+Account *
+gnc_book_get_default_gain_loss_acct (QofBook *book)
+{
+    Account *gains_account = NULL;
+
+    if (!book) return NULL;
+
+    if (gnc_book_use_book_currency (book))
+        gains_account = xaccAccountLookup
+                        (qof_book_get_default_gain_loss_acct_guid (book), book);
+
+    return gains_account;
+}
+
 Account *
 gnc_get_current_root_account (void)
 {
@@ -995,6 +1031,9 @@ gnc_default_currency_common (gchar *requested_currency,
                                           GNC_COMMODITY_NS_CURRENCY,
                                           requested_currency);
 
+    if (gnc_book_use_book_currency (gnc_get_current_book ()))
+        return gnc_book_get_book_currency (gnc_get_current_book ());
+
     if (gnc_prefs_get_bool (section, GNC_PREF_CURRENCY_CHOICE_OTHER))
     {
         mnemonic = gnc_prefs_get_string(section, GNC_PREF_CURRENCY_OTHER);
diff --git a/src/app-utils/gnc-ui-util.h b/src/app-utils/gnc-ui-util.h
index 79c02db..4f61609 100644
--- a/src/app-utils/gnc-ui-util.h
+++ b/src/app-utils/gnc-ui-util.h
@@ -94,7 +94,13 @@ gboolean gnc_book_use_book_currency (QofBook *book);
   * that both book-currency and default gain/loss policy KVPs exist and that
   * both are valid, a requirement for the 'book-currency' currency accounting
   * method to apply. */
-const gchar * gnc_book_get_book_currency (QofBook *book);
+const gchar * gnc_book_get_book_currency_name (QofBook *book);
+
+/** Returns pointer to Book Currency for book or NULL; determines
+  * that both book-currency and default gain/loss policy KVPs exist and that
+  * both are valid, a requirement for the 'book-currency' currency accounting
+  * method to apply. */
+gnc_commodity * gnc_book_get_book_currency (QofBook *book);
 
 /** Returns pointer to default gain/loss policy for book or NULL; determines
   * that both book-currency and default gain/loss policy KVPs exist and that
@@ -102,6 +108,12 @@ const gchar * gnc_book_get_book_currency (QofBook *book);
   * method to apply. */
 const gchar * gnc_book_get_default_gains_policy (QofBook *book);
 
+/** Returns pointer to default gain/loss account for book or NULL; determines
+  * that both book-currency and default gain/loss policy KVPs exist and that
+  * both are valid, a requirement for the 'book-currency' currency accounting
+  * method to apply. */
+Account * gnc_book_get_default_gain_loss_acct (QofBook *book);
+
 Account * gnc_get_current_root_account (void);
 gnc_commodity_table * gnc_get_current_commodities (void);
 
diff --git a/src/app-utils/options.scm b/src/app-utils/options.scm
index df2f195..d771680 100644
--- a/src/app-utils/options.scm
+++ b/src/app-utils/options.scm
@@ -1441,7 +1441,7 @@
                                             (currency?
                                               book-currency-option-path-kvp?))
                                         (if gains-policy-option-path-kvp?
-                                            (gnc-valid-policy
+                                            (gnc-valid-policy-name
                                               gains-policy-option-path-kvp?)))
                                    (begin
                                      (set! book-currency
@@ -1464,7 +1464,7 @@
            (if (legal-val (car x) ok-radiobutton-values)
                (if (eq? 'book-currency (car x))
                    (if (currency? (currency->scm (cadr x)))
-                       (if (gnc-valid-policy (symbol->string (caddr x)))
+                       (if (gnc-valid-policy-name (symbol->string (caddr x)))
                            (list #t x)
                            (list #f "cap-gains-policy-option: illegal value"))
                        (list #f "currency-option: illegal value"))
diff --git a/src/app-utils/test/test-gnc-ui-util.c b/src/app-utils/test/test-gnc-ui-util.c
index a6a84cb..704171f 100644
--- a/src/app-utils/test/test-gnc-ui-util.c
+++ b/src/app-utils/test/test-gnc-ui-util.c
@@ -26,7 +26,7 @@
 #include <glib.h>
 #include <unittest-support.h>
 #include <qof.h>
-/*#include <qofbookslots.h> */
+#include "test-engine-stuff.h"
 
 #include "../gnc-ui-util.h"
 
@@ -64,12 +64,15 @@ test_book_use_book_currency( Fixture *fixture, gconstpointer pData )
 {
     const gchar *cur;
     const gchar *pol;
+    Account *acct, *acc;
 
     g_test_message( "Testing with no currency accounting method selected" );
-    cur = gnc_book_get_book_currency( fixture-> book );
+    cur = gnc_book_get_book_currency_name( fixture-> book );
     g_assert_cmpstr( cur, == , NULL );
     pol = gnc_book_get_default_gains_policy( fixture-> book );
     g_assert_cmpstr( pol, == , NULL );
+    acct = gnc_book_get_default_gain_loss_acct ( fixture-> book );
+    g_assert (acct == NULL );
     g_assert( !gnc_book_use_book_currency ( fixture-> book ));
 
     g_test_message( "Testing with trading accounts set to true - t" );
@@ -77,17 +80,19 @@ test_book_use_book_currency( Fixture *fixture, gconstpointer pData )
     qof_instance_set (QOF_INSTANCE (fixture->book),
 		      "trading-accts", "t",
 		      NULL);
-    cur = gnc_book_get_book_currency( fixture-> book );
+    cur = gnc_book_get_book_currency_name( fixture-> book );
     g_assert_cmpstr( cur, == , NULL );
     pol = gnc_book_get_default_gains_policy( fixture-> book );
     g_assert_cmpstr( pol, == , NULL );
+    acct = gnc_book_get_default_gain_loss_acct ( fixture-> book );
+    g_assert (acct == NULL );
     g_assert( !gnc_book_use_book_currency ( fixture-> book ));
     qof_book_commit_edit (fixture->book);
 
     qof_book_destroy( fixture->book );
     fixture->book = qof_book_new();
 
-    g_test_message( "Testing with valid book-currency but default-gains-policy set to nonsense" );
+    g_test_message( "Testing with valid book-currency but default-gains-policy set to nonsense and default-gain-loss-account-guid set to random valid acct" );
     qof_book_begin_edit (fixture->book);
     qof_instance_set (QOF_INSTANCE (fixture->book),
 		      "book-currency", "USD",
@@ -95,17 +100,23 @@ test_book_use_book_currency( Fixture *fixture, gconstpointer pData )
     qof_instance_set (QOF_INSTANCE (fixture->book),
 		      "default-gains-policy", "random",
 		      NULL);
-    cur = gnc_book_get_book_currency( fixture-> book );
+    acc = get_random_account( fixture-> book );
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "default-gain-loss-account-guid", qof_entity_get_guid(QOF_INSTANCE(acc)),
+		      NULL);
+    cur = gnc_book_get_book_currency_name( fixture-> book );
     g_assert_cmpstr( cur, == , NULL );
     pol = gnc_book_get_default_gains_policy( fixture-> book );
     g_assert_cmpstr( pol, == , NULL );
+    acct = gnc_book_get_default_gain_loss_acct ( fixture-> book );
+    g_assert (acct == NULL );
     g_assert( !gnc_book_use_book_currency ( fixture-> book ));
     qof_book_commit_edit (fixture->book);
 
     qof_book_destroy( fixture->book );
     fixture->book = qof_book_new();
 
-    g_test_message( "Testing with valid default-gains-policy but book-currency set to nonsense" );
+    g_test_message( "Testing with valid default-gains-policy but book-currency set to nonsense and default-gain-loss-account-guid set to random valid acct" );
     qof_book_begin_edit (fixture->book);
     qof_instance_set (QOF_INSTANCE (fixture->book),
 		      "book-currency", "myMoney",
@@ -113,17 +124,23 @@ test_book_use_book_currency( Fixture *fixture, gconstpointer pData )
     qof_instance_set (QOF_INSTANCE (fixture->book),
 		      "default-gains-policy", "fifo",
 		      NULL);
-    cur = gnc_book_get_book_currency( fixture-> book );
+    acc = get_random_account( fixture-> book );
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "default-gain-loss-account-guid", qof_entity_get_guid(QOF_INSTANCE(acc)),
+		      NULL);
+    cur = gnc_book_get_book_currency_name( fixture-> book );
     g_assert_cmpstr( cur, == , NULL );
     pol = gnc_book_get_default_gains_policy( fixture-> book );
     g_assert_cmpstr( pol, == , NULL );
+    acct = gnc_book_get_default_gain_loss_acct ( fixture-> book );
+    g_assert (acct == NULL );
     g_assert( !gnc_book_use_book_currency ( fixture-> book ));
     qof_book_commit_edit (fixture->book);
 
     qof_book_destroy( fixture->book );
     fixture->book = qof_book_new();
 
-    g_test_message( "Testing with book-currency and default-gains-policy set to nonsense" );
+    g_test_message( "Testing with book-currency and default-gains-policy set to nonsense and default-gain-loss-account-guid set to random valid acct" );
     qof_book_begin_edit (fixture->book);
     qof_instance_set (QOF_INSTANCE (fixture->book),
 		      "book-currency", "myMoney",
@@ -131,47 +148,65 @@ test_book_use_book_currency( Fixture *fixture, gconstpointer pData )
     qof_instance_set (QOF_INSTANCE (fixture->book),
 		      "default-gains-policy", "random",
 		      NULL);
-    cur = gnc_book_get_book_currency( fixture-> book );
+    acc = get_random_account( fixture-> book );
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "default-gain-loss-account-guid", qof_entity_get_guid(QOF_INSTANCE(acc)),
+		      NULL);
+    cur = gnc_book_get_book_currency_name( fixture-> book );
     g_assert_cmpstr( cur, == , NULL );
     pol = gnc_book_get_default_gains_policy( fixture-> book );
     g_assert_cmpstr( pol, == , NULL );
+    acct = gnc_book_get_default_gain_loss_acct ( fixture-> book );
+    g_assert (acct == NULL );
     g_assert( !gnc_book_use_book_currency ( fixture-> book ));
     qof_book_commit_edit (fixture->book);
 
     qof_book_destroy( fixture->book );
     fixture->book = qof_book_new();
 
-    g_test_message( "Testing with book-currency set and no default-gains-policy" );
+    g_test_message( "Testing with book-currency set and no default-gains-policy and default-gain-loss-account-guid set to random valid acct" );
     qof_book_begin_edit (fixture->book);
     qof_instance_set (QOF_INSTANCE (fixture->book),
 		      "book-currency", "USD",
 		      NULL);
-    cur = gnc_book_get_book_currency( fixture-> book );
+    acc = get_random_account( fixture-> book );
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "default-gain-loss-account-guid", qof_entity_get_guid(QOF_INSTANCE(acc)),
+		      NULL);
+    cur = gnc_book_get_book_currency_name( fixture-> book );
     g_assert_cmpstr( cur, == , NULL );
     pol = gnc_book_get_default_gains_policy( fixture-> book );
     g_assert_cmpstr( pol, == , NULL );
+    acct = gnc_book_get_default_gain_loss_acct ( fixture-> book );
+    g_assert (acct == NULL );
     g_assert( !gnc_book_use_book_currency ( fixture-> book ));
     qof_book_commit_edit (fixture->book);
 
     qof_book_destroy( fixture->book );
     fixture->book = qof_book_new();
 
-    g_test_message( "Testing with default-gains-policy set and no book-currency" );
+    g_test_message( "Testing with default-gains-policy set and no book-currency and default-gain-loss-account-guid set to random valid acct" );
     qof_book_begin_edit (fixture->book);
     qof_instance_set (QOF_INSTANCE (fixture->book),
 		      "default-gains-policy", "fifo",
 		      NULL);
-    cur = gnc_book_get_book_currency( fixture-> book );
+    acc = get_random_account( fixture-> book );
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "default-gain-loss-account-guid", qof_entity_get_guid(QOF_INSTANCE(acc)),
+		      NULL);
+    cur = gnc_book_get_book_currency_name( fixture-> book );
     g_assert_cmpstr( cur, == , NULL );
     pol = gnc_book_get_default_gains_policy( fixture-> book );
     g_assert_cmpstr( pol, == , NULL );
+    acct = gnc_book_get_default_gain_loss_acct ( fixture-> book );
+    g_assert (acct == NULL );
     g_assert( !gnc_book_use_book_currency ( fixture-> book ));
     qof_book_commit_edit (fixture->book);
 
     qof_book_destroy( fixture->book );
     fixture->book = qof_book_new();
 
-    g_test_message( "Testing with book-currency and default-gains-policy set to valid values and with trading accounts set to true - t" );
+    g_test_message( "Testing with book-currency, default-gains-policy and default-gain-loss-account-guid set to valid values and with trading accounts set to true - t" );
     qof_book_begin_edit (fixture->book);
     qof_instance_set (QOF_INSTANCE (fixture->book),
 		      "trading-accts", "t",
@@ -182,17 +217,23 @@ test_book_use_book_currency( Fixture *fixture, gconstpointer pData )
     qof_instance_set (QOF_INSTANCE (fixture->book),
 		      "default-gains-policy", "fifo",
 		      NULL);
-    cur = gnc_book_get_book_currency( fixture-> book );
+    acc = get_random_account( fixture-> book );
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "default-gain-loss-account-guid", qof_entity_get_guid(QOF_INSTANCE(acc)),
+		      NULL);
+    cur = gnc_book_get_book_currency_name( fixture-> book );
     g_assert_cmpstr( cur, == , NULL );
     pol = gnc_book_get_default_gains_policy( fixture-> book );
     g_assert_cmpstr( pol, == , NULL );
+    acct = gnc_book_get_default_gain_loss_acct ( fixture-> book );
+    g_assert (acct == NULL );
     g_assert( !gnc_book_use_book_currency ( fixture-> book ));
     qof_book_commit_edit (fixture->book);
 
     qof_book_destroy( fixture->book );
     fixture->book = qof_book_new();
 
-    g_test_message( "Testing with book-currency and default-gains-policy set to valid values and no trading accounts flag" );
+    g_test_message( "Testing with book-currency, default-gains-policy and default-gain-loss-account-guid set to valid values and no trading accounts flag" );
     qof_book_begin_edit (fixture->book);
     qof_instance_set (QOF_INSTANCE (fixture->book),
 		      "book-currency", "USD",
@@ -200,10 +241,16 @@ test_book_use_book_currency( Fixture *fixture, gconstpointer pData )
     qof_instance_set (QOF_INSTANCE (fixture->book),
 		      "default-gains-policy", "fifo",
 		      NULL);
-    cur = gnc_book_get_book_currency( fixture-> book );
+    acc = get_random_account( fixture-> book );
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "default-gain-loss-account-guid", qof_entity_get_guid(QOF_INSTANCE(acc)),
+		      NULL);
+    cur = gnc_book_get_book_currency_name( fixture-> book );
     g_assert_cmpstr( cur, == , "USD" );
     pol = gnc_book_get_default_gains_policy( fixture-> book );
     g_assert_cmpstr( pol, == , "fifo" );
+    acct = gnc_book_get_default_gain_loss_acct ( fixture-> book );
+    g_assert ( xaccAccountEqual(acct, acc, TRUE) );
     g_assert( gnc_book_use_book_currency ( fixture-> book ));
     qof_book_commit_edit (fixture->book);
 }
diff --git a/src/engine/policy-p.h b/src/engine/policy-p.h
index 76cd97e..0ca7b04 100644
--- a/src/engine/policy-p.h
+++ b/src/engine/policy-p.h
@@ -63,6 +63,9 @@
 
 struct gncpolicy_s
 {
+    char *name;
+    char *description;
+    char *hint;
     GNCLot * (*PolicyGetLot) (GNCPolicy *, Split *split);
     Split  * (*PolicyGetSplit) (GNCPolicy *, GNCLot *lot);
     void     (*PolicyGetLotOpening) (GNCPolicy *, GNCLot *lot,
diff --git a/src/engine/policy.c b/src/engine/policy.c
index 38da205..b66c84c 100644
--- a/src/engine/policy.c
+++ b/src/engine/policy.c
@@ -67,38 +67,22 @@ GList *
 gnc_get_valid_policy_list (void)
 {
     GList *return_list = NULL;
-    GList *policy_list1 = NULL;
-    GList *policy_list2 = NULL;
-    GList *policy_list3 = NULL;
-    GList *policy_list4 = NULL;
-
-    policy_list1 = g_list_prepend (policy_list1, MANUAL_POLICY_HINT);
-    policy_list1 = g_list_prepend (policy_list1, MANUAL_POLICY_DESC);
-    policy_list1 = g_list_prepend (policy_list1, MANUAL_POLICY);
-    return_list = g_list_prepend (return_list, policy_list1);
-    policy_list2 = g_list_prepend (policy_list2, AVERAGE_POLICY_HINT);
-    policy_list2 = g_list_prepend (policy_list2, AVERAGE_POLICY_DESC);
-    policy_list2 = g_list_prepend (policy_list2, AVERAGE_POLICY);
-    return_list = g_list_prepend (return_list, policy_list2);
-    policy_list3 = g_list_prepend (policy_list3, LIFO_POLICY_HINT);
-    policy_list3 = g_list_prepend (policy_list3, LIFO_POLICY_DESC);
-    policy_list3 = g_list_prepend (policy_list3, LIFO_POLICY);
-    return_list = g_list_prepend (return_list, policy_list3);
-    policy_list4 = g_list_prepend (policy_list4, FIFO_POLICY_HINT);
-    policy_list4 = g_list_prepend (policy_list4, FIFO_POLICY_DESC);
-    policy_list4 = g_list_prepend (policy_list4, FIFO_POLICY);
-    return_list = g_list_prepend (return_list, policy_list4);
+
+/*    return_list = g_list_prepend (return_list, xaccGetManualPolicy());
+    return_list = g_list_prepend (return_list, xaccGetAveragePolicy()); */
+    return_list = g_list_prepend (return_list, xaccGetLIFOPolicy());
+    return_list = g_list_prepend (return_list, xaccGetFIFOPolicy());
 
     return return_list;
 }
 
 gboolean
-gnc_valid_policy (const gchar *name)
+gnc_valid_policy_name (const gchar *policy_name)
 {
     GList *list_of_policies = NULL;
     gboolean ret_val = FALSE;
 
-    if (!name)
+    if (!policy_name)
         return ret_val;
 
     list_of_policies = gnc_get_valid_policy_list();
@@ -111,13 +95,12 @@ gnc_valid_policy (const gchar *name)
         GList *l = NULL;
         for (l = list_of_policies; l != NULL; l = l->next)
         {
-            GList *policy_list = l->data;
-            if (g_strcmp0(policy_list->data, name) == 0)
+            GNCPolicy *list_pcy = l->data;
+            if (g_strcmp0(PolicyGetName (list_pcy), policy_name) == 0)
                 ret_val = TRUE;
-            g_list_free(policy_list);
         }
         g_list_free(list_of_policies);
-    return ret_val;
+        return ret_val;
     }
 }
 
@@ -208,6 +191,26 @@ donext:
     return NULL;
 }
 
+const char *
+PolicyGetName (const GNCPolicy *pcy)
+{
+    if(!pcy) return NULL;
+    return pcy->name;
+}
+
+const char *
+PolicyGetDescription (const GNCPolicy *pcy)
+{
+    if(!pcy) return NULL;
+    return pcy->description;
+}
+const char *
+PolicyGetHint (const GNCPolicy *pcy)
+{
+    if(!pcy) return NULL;
+    return pcy->hint;
+}
+
 /* ============================================================== */
 
 static GNCLot *
@@ -246,11 +249,6 @@ FIFOPolicyIsOpeningSplit (GNCPolicy *pcy, GNCLot *lot, Split *split)
     return (split == opening_split);
 }
 
-/* ============================================================== */
-/* Define a single, static policy, since we have no per-object data.
- * I suppose this could change, but we don't need any better at the
- * moment ... */
-
 GNCPolicy *
 xaccGetFIFOPolicy (void)
 {
@@ -259,6 +257,9 @@ xaccGetFIFOPolicy (void)
     if (!pcy)
     {
         pcy = g_new (GNCPolicy, 1);
+        pcy->name = FIFO_POLICY;
+        pcy->description = FIFO_POLICY_DESC;
+        pcy->hint = FIFO_POLICY_HINT;
         pcy->PolicyGetLot = FIFOPolicyGetLot;
         pcy->PolicyGetSplit = FIFOPolicyGetSplit;
         pcy->PolicyGetLotOpening = FIFOPolicyGetLotOpening;
@@ -267,12 +268,7 @@ xaccGetFIFOPolicy (void)
     return pcy;
 }
 
-/* ============================================================== */
-/* Stab at implementing the LIFO policy.  This is untested.
- * I'm not sure I got it right.
- */
-
-G_GNUC_UNUSED static GNCLot *
+static GNCLot *
 LIFOPolicyGetLot (GNCPolicy *pcy, Split *split)
 {
     if (!split) return NULL;
@@ -280,14 +276,14 @@ LIFOPolicyGetLot (GNCPolicy *pcy, Split *split)
                                          split->parent->common_currency);
 }
 
-G_GNUC_UNUSED static Split *
+static Split *
 LIFOPolicyGetSplit (GNCPolicy *pcy, GNCLot *lot)
 {
     return DirectionPolicyGetSplit (pcy, lot, 1);
 }
 
 /* This routine is actually identical to FIFO... */
-G_GNUC_UNUSED static void
+static void
 LIFOPolicyGetLotOpening (GNCPolicy *pcy,
                          GNCLot *lot,
                          gnc_numeric *ret_amount, gnc_numeric *ret_value,
@@ -302,7 +298,7 @@ LIFOPolicyGetLotOpening (GNCPolicy *pcy,
 }
 
 /* This routine is actually identical to FIFO... */
-G_GNUC_UNUSED static gboolean
+static gboolean
 LIFOPolicyIsOpeningSplit (GNCPolicy *pcy, GNCLot *lot, Split *split)
 {
     Split *opening_split;
@@ -310,4 +306,23 @@ LIFOPolicyIsOpeningSplit (GNCPolicy *pcy, GNCLot *lot, Split *split)
     return (split == opening_split);
 }
 
+GNCPolicy *
+xaccGetLIFOPolicy (void)
+{
+    static GNCPolicy *pcy = NULL;
+
+    if (!pcy)
+    {
+        pcy = g_new (GNCPolicy, 1);
+        pcy->name = LIFO_POLICY;
+        pcy->description = LIFO_POLICY_DESC;
+        pcy->hint = LIFO_POLICY_HINT;
+        pcy->PolicyGetLot = LIFOPolicyGetLot;
+        pcy->PolicyGetSplit = LIFOPolicyGetSplit;
+        pcy->PolicyGetLotOpening = LIFOPolicyGetLotOpening;
+        pcy->PolicyIsOpeningSplit = LIFOPolicyIsOpeningSplit;
+    }
+    return pcy;
+}
+
 /* =========================== END OF FILE ======================= */
diff --git a/src/engine/policy.h b/src/engine/policy.h
index 5c4ad8c..42dc812 100644
--- a/src/engine/policy.h
+++ b/src/engine/policy.h
@@ -40,21 +40,22 @@
 typedef struct gncpolicy_s GNCPolicy;
 
 /** Valid Policy List
- *  Provides a glist of glists for implemented policies. For each implemented
- *  policy, this glist contains: name, description, hint, as follows:
- *    glist(
- *       glist("fifo", "First In First Out", "Use oldest lots first.")
- *       glist("lifo", "Last In First Out", "Use newest lots first.")
- *       etc.
- *         )
- *  Both levels of lists must be freed with g_list_free().
+ *  Provides a glist of implemented policies.
+ *
+ *  List must be freed with g_list_free().
  */
 GList * gnc_get_valid_policy_list (void);
 
-/** Valid Policy
+/** Valid Policy Name
  *  Uses the Valid Policy List to determine if a policy name is valid.
  */
-gboolean gnc_valid_policy (const gchar *name);
+gboolean gnc_valid_policy_name (const gchar *policy_name);
+
+const char *PolicyGetName (const GNCPolicy *pcy);
+
+const char *PolicyGetDescription (const GNCPolicy *pcy);
+
+const char *PolicyGetHint (const GNCPolicy *pcy);
 
 /** First-in, First-out Policy
  *  This policy will create FIFO Lots.  FIFO Lots have the following
@@ -64,10 +65,24 @@ gboolean gnc_valid_policy (const gchar *name);
  *  -- Splits are added to the lot in date order, with earliest splits
  *     added first.
  *  -- All splits in the lot share the same transaction currency as
- *     the split that opened the lot.
+ *     the split that opened the lot (if book-currency book option
+ *     selected, this will always be book currency).
  */
 GNCPolicy *xaccGetFIFOPolicy (void);
 
+/** Last-in, Last-out Policy
+ *  This policy will create LIFO Lots.  LIFO Lots have the following
+ *  properties:
+ *  -- The lot is started with the latest posted split that isn't
+ *     a part of another lot already.
+ *  -- Splits are added to the lot in date order, with latest splits
+ *     added first.
+ *  -- All splits in the lot share the same transaction currency as
+ *     the split that opened the lot (if book-currency book option
+ *     selected, this will always be book currency).
+ */
+GNCPolicy *xaccGetLIFOPolicy (void);
+
 #endif /* XACC_POLICY_H */
 /** @} */
 /** @} */
diff --git a/src/gnome-utils/dialog-options.c b/src/gnome-utils/dialog-options.c
index 8c4cb62..f75ca53 100644
--- a/src/gnome-utils/dialog-options.c
+++ b/src/gnome-utils/dialog-options.c
@@ -571,8 +571,8 @@ gnc_option_currency_accounting_set_sensitivity(GNCOption *option,
             for (l = list_of_policies; l != NULL; l = l->next)
             {
                 /* First item in policy_list is internal name of policy */
-                GList *policy_list = l->data;
-                if (g_strcmp0(policy_list->data,
+                GNCPolicy *pcy = l->data;
+                if (g_strcmp0(PolicyGetName (pcy),
                                gnc_scm_symbol_to_locale_string(list_symbol))
                                == 0)
                 {
@@ -581,7 +581,6 @@ gnc_option_currency_accounting_set_sensitivity(GNCOption *option,
                                     GNC_COMBOTT(default_cost_policy_widget), i);
                 }
                 i++;
-                g_list_free(policy_list);
             }
             g_list_free(list_of_policies);
         }
@@ -869,17 +868,12 @@ gnc_option_create_currency_accounting_widget (char *name, GNCOption *option)
     GtkWidget *frame = NULL, *vbox1 = NULL;
     GtkWidget *widget = NULL;
     int num_values;
-    GList *list_of_policies = NULL;
     int i;
 
     num_values = gnc_option_num_permissible_values(option);
 
     g_return_val_if_fail(num_values == 3, NULL);
 
-    list_of_policies = gnc_get_valid_policy_list();
-
-    g_return_val_if_fail(g_list_length (list_of_policies) >= 0, NULL);
-
     /* Create our button frame */
     frame = gtk_frame_new (name);
 
@@ -915,7 +909,7 @@ gnc_option_create_currency_accounting_widget (char *name, GNCOption *option)
         {
             GtkWidget *widget_label;
             GtkWidget *book_currency_widget = NULL,
-                      *default_cost_policy_widget = NULL;
+                      *default_cost_policy_widget = gnc_cost_policy_select_new();
 
             g_signal_connect(G_OBJECT(widget),
                          "toggled",
@@ -934,46 +928,8 @@ gnc_option_create_currency_accounting_widget (char *name, GNCOption *option)
             gtk_box_pack_start (GTK_BOX (vbox2),
                                 book_currency_widget, FALSE, FALSE, 0);
             gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 0);
-            if (list_of_policies)
+            if (default_cost_policy_widget)
             {
-                GtkListStore *store;
-                GtkTreeIter  iter;
-                char *itemstring;
-                char *description;
-                GList *l = NULL;
-
-                store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
-                /* Add values to the list store, entry and tooltip */
-                for (l = list_of_policies; l != NULL; l = l->next)
-                {
-                    GList *policy_list = l->data;
-                    /* First item in policy_list is internal name of policy */
-                    policy_list = policy_list->next;
-                    /* Second item in policy_list is policy description */
-                    itemstring = policy_list->data;
-                    policy_list = policy_list->next;
-                    /* Third item in policy_list is policy hint */
-                    description = policy_list->data;
-                    gtk_list_store_append (store, &iter);
-                    gtk_list_store_set
-                           (store,
-                            &iter,
-                            0,
-                            (itemstring && *itemstring) ? _(itemstring) : "",
-                            1,
-                            (description && *description) ? _(description) : "",
-                            -1);
-                    g_list_free(policy_list);
-                }
-                g_list_free(list_of_policies);
-                /* Create the new Combo with tooltip and add the store */
-                default_cost_policy_widget = GTK_WIDGET(gnc_combott_new());
-                g_object_set( G_OBJECT( default_cost_policy_widget ),
-                              "model",
-                              GTK_TREE_MODEL(store),
-                              NULL );
-                g_object_unref(store);
-
                 g_signal_connect(G_OBJECT(default_cost_policy_widget), "changed",
                                  G_CALLBACK(gnc_option_multichoice_cb), option);
             }
@@ -3089,8 +3045,9 @@ gnc_option_set_ui_value_currency_accounting (GNCOption *option,
                         {
                             /* First item in policy_list is internal name of
                                policy */
-                            GList *policy_list = l->data;
-                            if (g_strcmp0(policy_list->data,
+                            GNCPolicy *pcy = l->data;
+
+                            if (g_strcmp0(PolicyGetName (pcy),
                                    gnc_scm_symbol_to_locale_string(list_symbol))
                                    == 0)
                             {
@@ -3101,7 +3058,6 @@ gnc_option_set_ui_value_currency_accounting (GNCOption *option,
                                     i);
                             }
                             i++;
-                            g_list_free(policy_list);
                         }
                         g_list_free(list_of_policies);
                     }
@@ -3470,11 +3426,10 @@ gnc_option_get_ui_value_currency_accounting (GNCOption *option, GtkWidget *widge
             gint i = 0;
             for (l = list_of_policies; l != NULL; l = l->next)
             {
-                GList *policy_list = l->data;
+                GNCPolicy *pcy = l->data;
                 if(i == policy_index)
-                    str = policy_list->data;
+                    str = PolicyGetName (pcy);
                 i++;
-                g_list_free(policy_list);
             }
             g_list_free(list_of_policies);
         }
diff --git a/src/gnome-utils/dialog-utils.c b/src/gnome-utils/dialog-utils.c
index 40959c9..0f26d4a 100644
--- a/src/gnome-utils/dialog-utils.c
+++ b/src/gnome-utils/dialog-utils.c
@@ -40,6 +40,7 @@
 #include "gnc-euro.h"
 #include "gnc-ui-util.h"
 #include "gnc-prefs.h"
+#include "gnc-combott.h"
 #include "guile-util.h"
 #include "gnc-main-window.h"
 #include <gnc-gdate-utils.h>
@@ -580,8 +581,8 @@ gnc_dialog_run (GtkDialog *dialog, const gchar *pref_name)
 
 /* If this is a new book, this function can be used to display book options
  * dialog so user can specify options, before any transactions can be
- * imported/entered, since they can affect how transactions are created
- * Note: This dialog is modal! */
+ * imported/entered, since the book options can affect how transactions are
+ * created. Note: This dialog is modal! */
 gboolean
 gnc_new_book_option_display (GtkWidget *parent)
 {
@@ -603,3 +604,52 @@ gnc_new_book_option_display (GtkWidget *parent)
     }
     return TRUE;
 }
+
+/* This function returns a widget for selecting a cost policy
+ */
+GtkWidget *
+gnc_cost_policy_select_new (void)
+{
+    GtkWidget *cost_policy_widget = NULL;
+    GList *list_of_policies = NULL;
+
+    list_of_policies = gnc_get_valid_policy_list();
+
+    g_return_val_if_fail(g_list_length (list_of_policies) >= 0, NULL);
+    if (list_of_policies)
+    {
+        GtkListStore *store;
+        GtkTreeIter  iter;
+        const char *description;
+        const char *hintstring;
+        GList *l = NULL;
+
+        store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
+        /* Add values to the list store, entry and tooltip */
+        for (l = list_of_policies; l != NULL; l = l->next)
+        {
+            GNCPolicy *pcy = l->data;
+            description = PolicyGetDescription(pcy);
+            hintstring = PolicyGetHint(pcy);
+            gtk_list_store_append (store, &iter);
+            gtk_list_store_set
+                   (store,
+                    &iter,
+                    0,
+                    (description && *description) ? _(description) : "",
+                    1,
+                    (hintstring && *hintstring) ? _(hintstring) : "",
+                    -1);
+        }
+        g_list_free(list_of_policies);
+        /* Create the new Combo with tooltip and add the store */
+        cost_policy_widget = GTK_WIDGET(gnc_combott_new());
+        g_object_set( G_OBJECT( cost_policy_widget ),
+                      "model",
+                      GTK_TREE_MODEL(store),
+                      NULL );
+        g_object_unref(store);
+    }
+    return cost_policy_widget;
+}
+
diff --git a/src/gnome-utils/dialog-utils.h b/src/gnome-utils/dialog-utils.h
index 7c14783..30a29fa 100644
--- a/src/gnome-utils/dialog-utils.h
+++ b/src/gnome-utils/dialog-utils.h
@@ -101,8 +101,13 @@ gnc_dialog_run(GtkDialog *dialog, const gchar *pref_key);
 
 /* If this is a new book, this function can be used to display book options
  * dialog so user can specify options, before any transactions can be
- * imported/entered, since they can affect how transactions are created
- * Note: This dialog is modal! */
+ * imported/entered, since the book options can affect how transactions are
+ * created. Note: This dialog is modal! */
 gboolean gnc_new_book_option_display (GtkWidget *parent);
 
+/** This function returns a widget for selecting a cost policy
+  */
+GtkWidget *
+gnc_cost_policy_select_new (void);
+
 #endif /* DIALOG_UTILS_H */
diff --git a/src/libqof/qof/qofbook.cpp b/src/libqof/qof/qofbook.cpp
index 5a9a6db..e5f3ad9 100644
--- a/src/libqof/qof/qofbook.cpp
+++ b/src/libqof/qof/qofbook.cpp
@@ -69,17 +69,22 @@ enum
     PROP_0,
 //  PROP_ROOT_ACCOUNT,		/* Table */
 //  PROP_ROOT_TEMPLATE,		/* Table */
-/*   keep trading accounts property, while adding book-currency and default
-     gains properties, so that files prior to 2.7 can be read/processed; GUI
-     changed to use all three properties as of 2.7. Trading accounts, on the
-     one hand, and book-currency plus default-gains-policy, on the other,
-     are mutually exclusive */
+/*   keep trading accounts property, while adding book-currency, default gains
+     policy and default gains account properties, so that files prior to 2.7 can
+     be read/processed; GUI changed to use all four properties as of 2.7.
+     Trading accounts, on the one hand, and book-currency plus default-gains-
+     policy, and optionally, default gains account, on the other, are mutually
+     exclusive */
     PROP_OPT_TRADING_ACCOUNTS,	/* KVP */
-/*   Book currency and default gains properties only apply if currency
+/*   Book currency and default gains policy properties only apply if currency
      accounting method selected in GUI is 'book-currency'; both required and
      both are exclusive with trading accounts */
     PROP_OPT_BOOK_CURRENCY, 	/* KVP */
     PROP_OPT_DEFAULT_GAINS_POLICY, 	/* KVP */
+/*   Default gains account property only applies if currency accounting method
+     selected in GUI is 'book-currency'; its use is optional but exclusive with
+     trading accounts */
+    PROP_OPT_DEFAULT_GAINS_ACCOUNT_GUID, 	/* KVP */
     PROP_OPT_AUTO_READONLY_DAYS,/* KVP */
     PROP_OPT_NUM_FIELD_SOURCE,	/* KVP */
     PROP_OPT_DEFAULT_BUDGET,	/* KVP */
@@ -158,6 +163,13 @@ qof_book_get_property (GObject* object,
 	qof_instance_get_kvp (QOF_INSTANCE (book), key, value);
 	g_free (key);
 	break;
+    case PROP_OPT_DEFAULT_GAINS_ACCOUNT_GUID:
+	key = g_strdup_printf ("%s/%s/%s", KVP_OPTION_PATH,
+			       OPTION_SECTION_ACCOUNTS,
+                   OPTION_NAME_DEFAULT_GAINS_LOSS_ACCT_GUID);
+	qof_instance_get_kvp (QOF_INSTANCE (book), key, value);
+	g_free (key);
+	break;
     case PROP_OPT_AUTO_READONLY_DAYS:
 	key = g_strdup_printf ("%s/%s/%s", KVP_OPTION_PATH,
 			       OPTION_SECTION_ACCOUNTS,
@@ -229,6 +241,13 @@ qof_book_set_property (GObject      *object,
 	qof_instance_set_kvp (QOF_INSTANCE (book), key, value);
 	g_free (key);
 	break;
+    case PROP_OPT_DEFAULT_GAINS_ACCOUNT_GUID:
+	key = g_strdup_printf ("%s/%s/%s", KVP_OPTION_PATH,
+			       OPTION_SECTION_ACCOUNTS,
+                   OPTION_NAME_DEFAULT_GAINS_LOSS_ACCT_GUID);
+	qof_instance_set_kvp (QOF_INSTANCE (book), key, value);
+	g_free (key);
+	break;
     case PROP_OPT_AUTO_READONLY_DAYS:
 	key = g_strdup_printf ("%s/%s/%s", KVP_OPTION_PATH,
 			       OPTION_SECTION_ACCOUNTS,
@@ -309,6 +328,18 @@ qof_book_class_init (QofBookClass *klass)
 
     g_object_class_install_property
     (gobject_class,
+     PROP_OPT_DEFAULT_GAINS_ACCOUNT_GUID,
+     g_param_spec_boxed("default-gain-loss-account-guid",
+                        "Select Default Gain/Loss Account",
+			 "The default account to be used for calculated gains/losses on "
+             "dispositions of currencies/commodities other than "
+             "'book-currency' when 'book-currency' currency accounting "
+             "method selected; requires valid book-currency.",
+                         GNC_TYPE_GUID,
+                         G_PARAM_READWRITE));
+
+    g_object_class_install_property
+    (gobject_class,
      PROP_OPT_NUM_FIELD_SOURCE,
      g_param_spec_string("split-action-num-field",
                          "Use Split-Action in the Num Field",
@@ -951,35 +982,15 @@ qof_book_normalize_counter_format_internal(const gchar *p,
   * KVP, or NULL; does not validate contents nor determine if there is a valid
   * default gain/loss policy, both of which are required, for the
   * 'book-currency' currency accounting method to apply. Use instead
-  * 'gnc_book_get_book_currency' which does these validations. */
+  * 'gnc_book_get_book_currency_name' which does these validations. */
 const gchar *
-qof_book_get_book_currency (QofBook *book)
+qof_book_get_book_currency_name (QofBook *book)
 {
-    KvpFrame *kvp;
-    KvpValue *value;
-
-    if (!book)
-    {
-        PWARN ("No book!!!");
-        return NULL;
-    }
-
-    /* Get the KVP from the current book */
-    kvp = qof_instance_get_slots (QOF_INSTANCE (book));
-
-    if (!kvp)
-    {
-        PWARN ("Book has no KVP_Frame");
-        return NULL;
-    }
-
-    /* See if there is a book currency. */
-    value = kvp->get_slot({KVP_OPTION_PATH, OPTION_SECTION_ACCOUNTS,
-                           OPTION_NAME_BOOK_CURRENCY});
-    if (!value) /* No book-currency */
-        return nullptr;
-
-    return value->get<const char*>();
+    const gchar *opt = NULL;
+    qof_instance_get (QOF_INSTANCE (book),
+		      "book-currency", &opt,
+		      NULL);
+    return opt;
 }
 
 /** Returns pointer to default gain/loss policy for book, if one exists in the
@@ -990,36 +1001,29 @@ qof_book_get_book_currency (QofBook *book)
 const gchar *
 qof_book_get_default_gains_policy (QofBook *book)
 {
-    KvpFrame *kvp;
-    KvpValue *value;
-
-    if (!book)
-    {
-        PWARN ("No book!!!");
-        return NULL;
-    }
-
-    /* Get the KVP from the current book */
-    kvp = qof_instance_get_slots (QOF_INSTANCE (book));
-
-    if (!kvp)
-    {
-        PWARN ("Book has no KVP_Frame");
-        return NULL;
-    }
+    const gchar *opt = NULL;
+    qof_instance_get (QOF_INSTANCE (book),
+		      "default-gains-policy", &opt,
+		      NULL);
+    return opt;
+}
 
-    /* See if there is a default gain/loss policy */
-    value = kvp->get_slot({KVP_OPTION_PATH, OPTION_SECTION_ACCOUNTS,
-                           OPTION_NAME_DEFAULT_GAINS_POLICY});
-    if (!value)
-    /* No default gain/loss policy, therefore not valid book-currency
-       accounting method */
-        return nullptr;
+/** Returns pointer to default gain/loss account GUID for book, if one exists in
+  * the KVP, or NULL; does not validate contents nor determine if there is a
+  * valid book-currency, both of which are required, for the 'book-currency'
+  * currency accounting method to apply. Use instead
+  * 'gnc_book_get_default_gain_loss_acct' which does these validations. */
+const GncGUID *
+qof_book_get_default_gain_loss_acct_guid (QofBook *book)
+{
+    GncGUID *guid = NULL;
+    qof_instance_get (QOF_INSTANCE (book),
+		      "default-gain-loss-account-guid", &guid,
+		      NULL);
+    return guid;
 
-    return g_strdup(value->get<const char*>());
 }
 
-
 /* Determine whether this book uses trading accounts */
 gboolean
 qof_book_use_trading_accounts (const QofBook *book)
diff --git a/src/libqof/qof/qofbook.h b/src/libqof/qof/qofbook.h
index f18a1ea..547f6b3 100644
--- a/src/libqof/qof/qofbook.h
+++ b/src/libqof/qof/qofbook.h
@@ -253,8 +253,8 @@ gboolean qof_book_use_trading_accounts (const QofBook *book);
   * KVP, or NULL; does not validate contents nor determine if there is a valid
   * default gain/loss policy, both of which are required, for the
   * 'book-currency' currency accounting method to apply. Use instead
-  * 'gnc_book_get_book_currency' which does these validations. */
-const gchar * qof_book_get_book_currency (QofBook *book);
+  * 'gnc_book_get_book_currency_name' which does these validations. */
+const gchar * qof_book_get_book_currency_name (QofBook *book);
 
 /** Returns pointer to default gain/loss policy for book, if one exists in the
   * KVP, or NULL; does not validate contents nor determine if there is a valid
@@ -263,6 +263,13 @@ const gchar * qof_book_get_book_currency (QofBook *book);
   * 'gnc_book_get_default_gains_policy' which does these validations. */
 const gchar * qof_book_get_default_gains_policy (QofBook *book);
 
+/** Returns pointer to default gain/loss account GUID for book, if one exists in
+  * the KVP, or NULL; does not validate contents nor determine if there is a
+  * valid book-currency, both of which are required, for the 'book-currency'
+  * currency accounting method to apply. Use instead
+  * 'gnc_book_get_default_gain_loss_acct' which does these validations. */
+const GncGUID * qof_book_get_default_gain_loss_acct_guid (QofBook *book);
+
 /** Returns TRUE if the auto-read-only feature should be used, otherwise
  * FALSE. This is just a wrapper on qof_book_get_num_days_autoreadonly() == 0. */
 gboolean qof_book_uses_autoreadonly (const QofBook *book);
diff --git a/src/libqof/qof/qofbookslots.h b/src/libqof/qof/qofbookslots.h
index f820fd3..10e1d64 100644
--- a/src/libqof/qof/qofbookslots.h
+++ b/src/libqof/qof/qofbookslots.h
@@ -67,6 +67,7 @@
 #define OPTION_NAME_CURRENCY_ACCOUNTING   N_("Currency Accounting")
 #define OPTION_NAME_BOOK_CURRENCY      N_("Book Currency")
 #define OPTION_NAME_DEFAULT_GAINS_POLICY      N_("Default Gains Policy")
+#define OPTION_NAME_DEFAULT_GAINS_LOSS_ACCT_GUID      N_("Default Gain or Loss Account")
 #define OPTION_NAME_AUTO_READONLY_DAYS N_("Day Threshold for Read-Only Transactions (red line)")
 #define OPTION_NAME_NUM_FIELD_SOURCE   N_("Use Split Action Field for Number")
 
@@ -82,6 +83,7 @@
  * OPTION-NAME-CURRENCY-ACCOUNTING
  * OPTION-NAME-BOOK-CURRENCY
  * OPTION_NAME_DEFAULT_GAINS_POLICY
+ * OPTION_NAME_DEFAULT_GAINS_LOSS_ACCT_GUID
  * OPTION-NAME-AUTO-READONLY-DAYS
  * OPTION-NAME_NUM-FIELD-SOURCE
  * OPTION-SECTION-BUDGETING
diff --git a/src/libqof/qof/test/test-qofbook.c b/src/libqof/qof/test/test-qofbook.c
index cc31369..ee086a1 100644
--- a/src/libqof/qof/test/test-qofbook.c
+++ b/src/libqof/qof/test/test-qofbook.c
@@ -460,35 +460,43 @@ test_book_use_book_currency( Fixture *fixture, gconstpointer pData )
 {
     const gchar *cur;
     const gchar *pol;
+    GncGUID *acct;
+    const GncGUID *acct2;
 
-    cur = qof_book_get_book_currency( fixture-> book );
+    cur = qof_book_get_book_currency_name( fixture-> book );
     g_assert_cmpstr( cur, == , NULL );
     pol = qof_book_get_default_gains_policy( fixture-> book );
     g_assert_cmpstr( pol, == , NULL );
+    acct2 = qof_book_get_default_gain_loss_acct_guid( fixture-> book );
+    g_assert (acct2 == NULL );
 
     g_test_message( "Testing with existing trading accounts set to true - t" );
     qof_book_begin_edit (fixture->book);
     qof_instance_set (QOF_INSTANCE (fixture->book),
 		      "trading-accts", "t",
 		      NULL);
-    cur = qof_book_get_book_currency( fixture-> book );
+    cur = qof_book_get_book_currency_name( fixture-> book );
     g_assert_cmpstr( cur, == , NULL );
     pol = qof_book_get_default_gains_policy( fixture-> book );
     g_assert_cmpstr( pol, == , NULL );
+    acct2 = qof_book_get_default_gain_loss_acct_guid( fixture-> book );
+    g_assert (acct2 == NULL );
     qof_book_commit_edit (fixture->book);
 
     qof_book_destroy( fixture->book );
     fixture->book = qof_book_new();
 
-    g_test_message( "Testing with book-currency set and no default-gains-policy" );
+    g_test_message( "Testing with book-currency set and no default-gains-policy or account" );
     qof_book_begin_edit (fixture->book);
     qof_instance_set (QOF_INSTANCE (fixture->book),
 		      "book-currency", "USD",
 		      NULL);
-    cur = qof_book_get_book_currency( fixture-> book );
+    cur = qof_book_get_book_currency_name( fixture-> book );
     g_assert_cmpstr( cur, == , "USD" );
     pol = qof_book_get_default_gains_policy( fixture-> book );
     g_assert_cmpstr( pol, == , NULL );
+    acct2 = qof_book_get_default_gain_loss_acct_guid( fixture-> book );
+    g_assert (acct2 == NULL );
     qof_book_commit_edit (fixture->book);
 
     qof_book_destroy( fixture->book );
@@ -499,10 +507,12 @@ test_book_use_book_currency( Fixture *fixture, gconstpointer pData )
     qof_instance_set (QOF_INSTANCE (fixture->book),
 		      "default-gains-policy", "fifo",
 		      NULL);
-    cur = qof_book_get_book_currency( fixture-> book );
+    cur = qof_book_get_book_currency_name( fixture-> book );
     g_assert_cmpstr( cur, == , NULL );
     pol = qof_book_get_default_gains_policy( fixture-> book );
     g_assert_cmpstr( pol, == , "fifo" );
+    acct2 = qof_book_get_default_gain_loss_acct_guid( fixture-> book );
+    g_assert (acct2 == NULL );
     qof_book_commit_edit (fixture->book);
 
     qof_book_destroy( fixture->book );
@@ -516,16 +526,18 @@ test_book_use_book_currency( Fixture *fixture, gconstpointer pData )
     qof_instance_set (QOF_INSTANCE (fixture->book),
 		      "default-gains-policy", "random",
 		      NULL);
-    cur = qof_book_get_book_currency( fixture-> book );
+    cur = qof_book_get_book_currency_name( fixture-> book );
     g_assert_cmpstr( cur, == , "myMoney" );
     pol = qof_book_get_default_gains_policy( fixture-> book );
     g_assert_cmpstr( pol, == , "random" );
+    acct2 = qof_book_get_default_gain_loss_acct_guid( fixture-> book );
+    g_assert (acct2 == NULL );
     qof_book_commit_edit (fixture->book);
 
     qof_book_destroy( fixture->book );
     fixture->book = qof_book_new();
 
-    g_test_message( "Testing with book-currency and default-gains-policy set to valid values" );
+    g_test_message( "Testing with book-currency, default-gains-policy and default-gains-account set to valid values" );
     qof_book_begin_edit (fixture->book);
     qof_instance_set (QOF_INSTANCE (fixture->book),
 		      "book-currency", "USD",
@@ -533,10 +545,18 @@ test_book_use_book_currency( Fixture *fixture, gconstpointer pData )
     qof_instance_set (QOF_INSTANCE (fixture->book),
 		      "default-gains-policy", "fifo",
 		      NULL);
-    cur = qof_book_get_book_currency( fixture-> book );
+    acct = guid_new();
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "default-gain-loss-account-guid", acct,
+		      NULL);
+    cur = qof_book_get_book_currency_name( fixture-> book );
     g_assert_cmpstr( cur, == , "USD" );
     pol = qof_book_get_default_gains_policy( fixture-> book );
     g_assert_cmpstr( pol, == , "fifo" );
+    acct2 = qof_book_get_default_gain_loss_acct_guid( fixture-> book );
+    g_assert_cmpstr( guid_to_string (acct), == , guid_to_string (acct2) );
+    g_assert (guid_equal(acct, acct2));
+    guid_free (acct);
     qof_book_commit_edit (fixture->book);
 }
 



Summary of changes:
 src/app-utils/gnc-ui-util.c           |  53 +++++++++++++--
 src/app-utils/gnc-ui-util.h           |  14 +++-
 src/app-utils/options.scm             |   4 +-
 src/app-utils/test/test-gnc-ui-util.c |  81 +++++++++++++++++-----
 src/engine/policy-p.h                 |   3 +
 src/engine/policy.c                   |  97 +++++++++++++++------------
 src/engine/policy.h                   |  37 ++++++++---
 src/gnome-utils/dialog-options.c      |  63 +++---------------
 src/gnome-utils/dialog-utils.c        |  54 ++++++++++++++-
 src/gnome-utils/dialog-utils.h        |   9 ++-
 src/libqof/qof/qofbook.cpp            | 122 ++++++++++++++++++----------------
 src/libqof/qof/qofbook.h              |  11 ++-
 src/libqof/qof/qofbookslots.h         |   2 +
 src/libqof/qof/test/test-qofbook.c    |  36 +++++++---
 14 files changed, 380 insertions(+), 206 deletions(-)



More information about the gnucash-changes mailing list