gnucash master: Book-Currency Feature step 1

J. Alex Aycinena alex.aycinena at code.gnucash.org
Mon Feb 9 16:18:58 EST 2015


Updated	 via  https://github.com/Gnucash/gnucash/commit/b22c6b6e (commit)
	from  https://github.com/Gnucash/gnucash/commit/9c8405da (commit)



commit b22c6b6eb9ab86273bfc7225cc50504f28158bc8
Author: Alex Aycinena <alex.aycinena at gmail.com>
Date:   Mon Feb 9 12:52:29 2015 -0800

    Book-Currency Feature step 1
    
    The changes made are:
    
         libqof/qof/qofbookslots.h - define Currency Accounting Method option; keep
             the current Trading Accounts option (in order to read prior files)
         libqof/qof/qofbook.cpp & .h - define function to determine if book uses
             book-currency, modify function to determine if book uses trading
             accounts and add gobject properties accordingly
         libqof/qof/test/test-qofbook.c - define test function to determine if book
             uses book-currency and modify test function for trading accounts
         engine/test/utest-Split.cpp - modify test function for trading accounts
             to use new "currency-accounting" and "trading" book properties
         engine/test/utest-Transaction.c - modify test function for trading accounts
             to use new "currency-accounting" and "trading" book properties

diff --git a/src/engine/test/utest-Split.cpp b/src/engine/test/utest-Split.cpp
index 4e3425d..733e5fb 100644
--- a/src/engine/test/utest-Split.cpp
+++ b/src/engine/test/utest-Split.cpp
@@ -1808,7 +1808,7 @@ test_xaccSplitGetOtherSplit (Fixture *fixture, gconstpointer pData)
     g_assert (kvp_frame_get_slot (split1->inst.kvp_data, "lot-split") == NULL);
     qof_book_begin_edit (book);
     qof_instance_set (QOF_INSTANCE (book),
-		      "trading-accts", "t",
+		      "currency-accounting", "trading",
 		      NULL);
     qof_book_commit_edit (book);
     g_assert (xaccTransUseTradingAccounts (txn));
diff --git a/src/engine/test/utest-Transaction.c b/src/engine/test/utest-Transaction.c
index 7611c2c..8c3ee23 100644
--- a/src/engine/test/utest-Transaction.c
+++ b/src/engine/test/utest-Transaction.c
@@ -1053,7 +1053,7 @@ test_xaccTransGetImbalance_trading (Fixture *fixture,
     MonetaryList *mlist;
     qof_book_begin_edit (book);
     qof_instance_set (QOF_INSTANCE (book),
-		      "trading-accts", "t",
+		      "currency-accounting", "trading",
 		      NULL);
     qof_book_commit_edit (book);
 
@@ -1140,7 +1140,7 @@ test_xaccTransIsBalanced_trading (Fixture *fixture, gconstpointer pData)
 
     qof_book_begin_edit (book);
     qof_instance_set (QOF_INSTANCE (book),
-		      "trading-accts", "t",
+		      "currency-accounting", "trading",
 		      NULL);
     qof_book_commit_edit (book);
 
diff --git a/src/libqof/qof/qofbook.cpp b/src/libqof/qof/qofbook.cpp
index 2f92119..d0c7d1a 100644
--- a/src/libqof/qof/qofbook.cpp
+++ b/src/libqof/qof/qofbook.cpp
@@ -66,7 +66,11 @@ enum
     PROP_0,
 //  PROP_ROOT_ACCOUNT,		/* Table */
 //  PROP_ROOT_TEMPLATE,		/* Table */
+/*   keep trading accounts property, while adding currency accounting
+     preperty, so that files prior to 2.7 can be read/processed; GUI changed
+     to use currency accounting property as of 2.7 */
     PROP_OPT_TRADING_ACCOUNTS,	/* KVP */
+    PROP_OPT_CURRENCY_ACCOUNTING,	/* KVP */
     PROP_OPT_AUTO_READONLY_DAYS,/* KVP */
     PROP_OPT_NUM_FIELD_SOURCE,	/* KVP */
     PROP_OPT_DEFAULT_BUDGET,	/* KVP */
@@ -75,6 +79,13 @@ enum
     N_PROPERTIES		/* Just a counter */
 };
 
+enum
+{
+    CURRENCY_ACCOUNTING_TRADING,
+    CURRENCY_ACCOUNTING_BOOK_CURRENCY,
+    CURRENCY_ACCOUNTING_NEITHER,
+};
+
 QOF_GOBJECT_GET_TYPE(QofBook, qof_book, QOF_TYPE_INSTANCE, {});
 QOF_GOBJECT_DISPOSE(qof_book);
 QOF_GOBJECT_FINALIZE(qof_book);
@@ -131,6 +142,13 @@ qof_book_get_property (GObject* object,
 	qof_instance_get_kvp (QOF_INSTANCE (book), key, value);
 	g_free (key);
 	break;
+    case PROP_OPT_CURRENCY_ACCOUNTING:
+	key = g_strdup_printf ("%s/%s/%s", KVP_OPTION_PATH,
+			       OPTION_SECTION_ACCOUNTS,
+			       OPTION_NAME_CURRENCY_ACCOUNTING);
+	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,
@@ -187,6 +205,13 @@ qof_book_set_property (GObject      *object,
 	qof_instance_set_kvp (QOF_INSTANCE (book), key, value);
 	g_free (key);
 	break;
+    case PROP_OPT_CURRENCY_ACCOUNTING:
+	key = g_strdup_printf ("%s/%s/%s", KVP_OPTION_PATH,
+			       OPTION_SECTION_ACCOUNTS,
+			       OPTION_NAME_CURRENCY_ACCOUNTING);
+	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,
@@ -244,6 +269,22 @@ qof_book_class_init (QofBookClass *klass)
 
     g_object_class_install_property
     (gobject_class,
+     PROP_OPT_CURRENCY_ACCOUNTING,
+     g_param_spec_string("currency-accounting",
+                         "Select Currency Accounting Method",
+			 "Scheme 'trading', 'book-currency', or 'neither' (or NULL). "
+			 "If 'trading', then the book uses trading accounts for "
+			 "managing multiple-currency transactions.  If 'book-currency', "
+			 "then the book uses the 'book-currency' as a reference currency "
+             "for managing multiple-currency transactions. If 'neither', or "
+             "if the property is not set or NULL, then the book handles "
+             "multiple-currency transactions in the traditional way gnucash "
+             "has in the past.",
+                         NULL,
+                         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",
@@ -826,16 +867,70 @@ qof_book_validate_counter_format_internal(const gchar *p,
     return NULL;
 }
 
+/* Returns Currency Accounting Method for book */
+gint
+qof_book_currency_accounting_method (const QofBook *book)
+{
+    KvpFrame *kvp;
+    KvpValue *value;
+
+    if (!book)
+    {
+        PWARN ("No book!!!");
+        return CURRENCY_ACCOUNTING_NEITHER;
+    }
+
+    /* Get the KVP from the current book */
+    kvp = qof_instance_get_slots (QOF_INSTANCE (book));
+
+    if (!kvp)
+    {
+        PWARN ("Book has no KVP_Frame");
+        return CURRENCY_ACCOUNTING_NEITHER;
+    }
+
+    /* Get the Currency Accounting Method */
+    value = kvp_frame_get_slot_path (kvp,
+                                     KVP_OPTION_PATH,
+                                     OPTION_SECTION_ACCOUNTS,
+                                     OPTION_NAME_CURRENCY_ACCOUNTING,
+                                     NULL);
+    if (value)
+    {
+        if (strcmp (kvp_value_get_string (value), "book-currency") == 0)
+           return CURRENCY_ACCOUNTING_BOOK_CURRENCY;
+        if (strcmp (kvp_value_get_string (value), "trading") == 0)
+           return CURRENCY_ACCOUNTING_TRADING;
+    }
+    return CURRENCY_ACCOUNTING_NEITHER;
+}
+
 /* Determine whether this book uses trading accounts */
 gboolean
 qof_book_use_trading_accounts (const QofBook *book)
 {
+    /* Prior to version 2.7, Gnucash had a boolean flag for trading accounts;
+       need to accommodate files from version 2.6 and earlier */
     const char *opt = NULL;
     qof_instance_get (QOF_INSTANCE (book),
 		      "trading-accts", &opt,
 		      NULL);
     if (opt && opt[0] == 't' && opt[1] == 0)
         return TRUE;
+
+    /* Else, get the Currency Accounting Method */
+    if (qof_book_currency_accounting_method (book) == CURRENCY_ACCOUNTING_TRADING)
+        return TRUE;
+    return FALSE;
+}
+
+/* Returns TRUE if this book uses a book-currency */
+gboolean
+qof_book_use_book_currency (const QofBook *book)
+{
+    /* Get the Currency Accounting Method */
+    if (qof_book_currency_accounting_method (book) == CURRENCY_ACCOUNTING_BOOK_CURRENCY)
+        return TRUE;
     return FALSE;
 }
 
diff --git a/src/libqof/qof/qofbook.h b/src/libqof/qof/qofbook.h
index c1e5ae4..9725984 100644
--- a/src/libqof/qof/qofbook.h
+++ b/src/libqof/qof/qofbook.h
@@ -245,6 +245,9 @@ void qof_book_mark_readonly(QofBook *book);
 /** Returns flag indicating whether this book uses trading accounts */
 gboolean qof_book_use_trading_accounts (const QofBook *book);
 
+/** Returns TRUE if this book uses a book-currency */
+gboolean qof_book_use_book_currency (const 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 53cc1c7..2ccce86 100644
--- a/src/libqof/qof/qofbookslots.h
+++ b/src/libqof/qof/qofbookslots.h
@@ -64,6 +64,7 @@
 
 #define OPTION_SECTION_ACCOUNTS        N_("Accounts")
 #define OPTION_NAME_TRADING_ACCOUNTS   N_("Use Trading Accounts")
+#define OPTION_NAME_CURRENCY_ACCOUNTING   N_("Select Currency Accounting Method")
 #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")
 
@@ -76,6 +77,7 @@
  * KVP-OPTION-PATH
  * OPTION-SECTION-ACCOUNTS
  * OPTION-NAME-TRADING-ACCOUNTS
+ * OPTION-NAME-CURRENCY-ACCOUNTING
  * 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 81c3cae..d6922a5 100644
--- a/src/libqof/qof/test/test-qofbook.c
+++ b/src/libqof/qof/test/test-qofbook.c
@@ -364,6 +364,9 @@ test_book_increment_and_format_counter ( Fixture *fixture, gconstpointer pData )
     g_free( r );
 }
 
+/* keep this testing of trading accounts, while adding testing of currency-
+   accounting-based trading accounts, so that files prior to version 2.7
+   can be read/processed */
 static void
 test_book_use_trading_accounts( Fixture *fixture, gconstpointer pData )
 {
@@ -386,6 +389,48 @@ test_book_use_trading_accounts( Fixture *fixture, gconstpointer pData )
 }
 
 static void
+test_book_use_trading_accounts_currency_accounting( Fixture *fixture, gconstpointer pData )
+{
+    g_assert( qof_book_use_trading_accounts( fixture-> book ) == FALSE );
+
+    g_test_message( "Testing with existing currency-accounting set to 'trading'" );
+    qof_book_begin_edit (fixture->book);
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "currency-accounting", "trading",
+		      NULL);
+    g_assert( qof_book_use_trading_accounts( fixture-> book ) == TRUE );
+
+    g_test_message( "Testing with existing currency-accounting set to 'book-currency'" );
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "currency-accounting", "book-currency",
+		      NULL);
+    g_assert( qof_book_use_trading_accounts( fixture-> book ) == FALSE );
+    qof_book_commit_edit (fixture->book);
+
+}
+
+static void
+test_book_use_book_currency( Fixture *fixture, gconstpointer pData )
+{
+    g_assert( qof_book_use_book_currency( fixture-> book ) == FALSE );
+
+    g_test_message( "Testing with existing currency-accounting set to 'book-currency'" );
+    qof_book_begin_edit (fixture->book);
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "currency-accounting", "book-currency",
+		      NULL);
+    g_assert( qof_book_use_book_currency( fixture-> book ) == TRUE );
+
+    g_test_message( "Testing with existing currency-accounting set to 'trading'" );
+    qof_instance_set (QOF_INSTANCE (fixture->book),
+		      "currency-accounting", "trading",
+		      NULL);
+    g_assert( qof_book_use_book_currency( fixture-> book ) == FALSE );
+    qof_book_commit_edit (fixture->book);
+
+}
+
+static void
 test_book_get_num_days_autofreeze( Fixture *fixture, gconstpointer pData )
 {
     g_test_message( "Testing default: No auto-freeze days are set" );
@@ -757,6 +802,8 @@ test_suite_qofbook ( void )
     GNC_TEST_ADD( suitename, "get counter format", Fixture, NULL, setup, test_book_get_counter_format, teardown );
     GNC_TEST_ADD( suitename, "increment and format counter", Fixture, NULL, setup, test_book_increment_and_format_counter, teardown );
     GNC_TEST_ADD( suitename, "use trading accounts", Fixture, NULL, setup, test_book_use_trading_accounts, teardown );
+    GNC_TEST_ADD( suitename, "use trading accounts - currency accounting", Fixture, NULL, setup, test_book_use_trading_accounts_currency_accounting, teardown );
+    GNC_TEST_ADD( suitename, "use book-currency", Fixture, NULL, setup, test_book_use_book_currency, teardown );
     GNC_TEST_ADD( suitename, "get autofreeze days", Fixture, NULL, setup, test_book_get_num_days_autofreeze, teardown );
     GNC_TEST_ADD( suitename, "use split action for num field", Fixture, NULL, setup, test_book_use_split_action_for_num_field, teardown );
     GNC_TEST_ADD( suitename, "mark session dirty", Fixture, NULL, setup, test_book_mark_session_dirty, teardown );



Summary of changes:
 src/engine/test/utest-Split.cpp     |  2 +-
 src/engine/test/utest-Transaction.c |  4 +-
 src/libqof/qof/qofbook.cpp          | 95 +++++++++++++++++++++++++++++++++++++
 src/libqof/qof/qofbook.h            |  3 ++
 src/libqof/qof/qofbookslots.h       |  2 +
 src/libqof/qof/test/test-qofbook.c  | 47 ++++++++++++++++++
 6 files changed, 150 insertions(+), 3 deletions(-)



More information about the gnucash-changes mailing list