From bfbe9b87c414a4a38354fafa883b779c4dbf049d Mon Sep 17 00:00:00 2001 From: Christian Stimming Date: Wed, 21 Mar 2012 22:18:29 +0000 Subject: [PATCH] Add option for automatically setting old transactions to read-only. The number of days for this read-only threshold can be chosen. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@22107 57a11ea4-9604-0410-9ed3-97b8803252fd --- src/app-utils/app-utils.scm | 3 ++- src/app-utils/business-prefs.scm | 11 +++++++++ src/engine/Makefile.am | 6 +++-- src/engine/engine.i | 1 + src/libqof/qof/qofbook.c | 35 +++++++++++++++++++++++++++++ src/libqof/qof/qofbook.h | 17 ++++++++++++++ src/libqof/qof/qofbookslots.h | 2 ++ src/libqof/qof/test/test-qofbook.c | 36 ++++++++++++++++++++++++++++++ 8 files changed, 108 insertions(+), 3 deletions(-) diff --git a/src/app-utils/app-utils.scm b/src/app-utils/app-utils.scm index 6fdc0407cf..c2efd9c4c3 100644 --- a/src/app-utils/app-utils.scm +++ b/src/app-utils/app-utils.scm @@ -322,8 +322,9 @@ (define gnc:*option-section-accounts* OPTION-SECTION-ACCOUNTS) (define gnc:*option-name-trading-accounts* OPTION-NAME-TRADING-ACCOUNTS) +(define gnc:*option-name-auto-freeze-days* OPTION-NAME-AUTO-FREEZE-DAYS) -(export gnc:*option-section-accounts* gnc:*option-name-trading-accounts*) +(export gnc:*option-section-accounts* gnc:*option-name-trading-accounts* gnc:*option-name-auto-freeze-days*) (define gnc:*option-section-budgeting* OPTION-SECTION-BUDGETING) (define gnc:*option-name-default-budget* OPTION-NAME-DEFAULT-BUDGET) diff --git a/src/app-utils/business-prefs.scm b/src/app-utils/business-prefs.scm index d93beaad52..40a0339036 100644 --- a/src/app-utils/business-prefs.scm +++ b/src/app-utils/business-prefs.scm @@ -131,6 +131,17 @@ "a" (N_ "Check to have trading accounts used for transactions involving more than one currency or commodity") #f)) + (reg-option + (gnc:make-number-range-option + gnc:*option-section-accounts* gnc:*option-name-auto-freeze-days* + "b" (N_ "Choose the number of days after which transactions will be read-only and cannot be edited anymore. This threshold is marked by a red line in the account register windows. If zero, all transactions can be edited and none are read-only.") + 0 ;; default + 0 ;; lower bound + 3650 ;; upper bound + 0 ;; number of decimals + 1 ;; step size + )) + ;; Budgeting Tab (reg-option diff --git a/src/engine/Makefile.am b/src/engine/Makefile.am index 2a312ccfca..3f55b14c2a 100644 --- a/src/engine/Makefile.am +++ b/src/engine/Makefile.am @@ -191,9 +191,11 @@ noinst_DATA = .scm-links if BUILDING_FROM_SVN # The generated file depends on various libqof headers. Out of -# laziness I only include one here - more might be needed +# laziness I only include a few here - more might be needed # subsequently. -QOFHEADERS = $(top_srcdir)/src/libqof/qof/qofbook.h +QOFHEADERS = \ + $(top_srcdir)/src/libqof/qof/qofbook.h \ + $(top_srcdir)/src/libqof/qof/qofbookslots.h swig-engine.c: engine.i $(top_srcdir)/src/base-typemaps.i \ $(QOFHEADERS) \ diff --git a/src/engine/engine.i b/src/engine/engine.i index f0a60489fd..70fd1dafe6 100644 --- a/src/engine/engine.i +++ b/src/engine/engine.i @@ -295,6 +295,7 @@ KvpValue * kvp_frame_get_slot_path_gslist (KvpFrame *frame, GSList *key_path); SET_ENUM("OPTION-SECTION-ACCOUNTS"); SET_ENUM("OPTION-NAME-TRADING-ACCOUNTS"); + SET_ENUM("OPTION-NAME-AUTO-FREEZE-DAYS"); SET_ENUM("OPTION-SECTION-BUDGETING"); SET_ENUM("OPTION-NAME-DEFAULT-BUDGET"); diff --git a/src/libqof/qof/qofbook.c b/src/libqof/qof/qofbook.c index 2e3492f540..666da1d091 100644 --- a/src/libqof/qof/qofbook.c +++ b/src/libqof/qof/qofbook.c @@ -641,6 +641,41 @@ qof_book_use_trading_accounts (const QofBook *book) return FALSE; } +gboolean qof_book_uses_autofreeze (const QofBook *book) +{ + g_assert(book); + return (qof_book_get_num_days_autofreeze(book) != 0); +} + +gint qof_book_get_num_days_autofreeze (const QofBook *book) +{ + kvp_value *kvp_val; + double tmp; + g_assert(book); + kvp_val = kvp_frame_get_slot_path (qof_book_get_slots (book), + KVP_OPTION_PATH, + OPTION_SECTION_ACCOUNTS, + OPTION_NAME_AUTO_FREEZE_DAYS, + NULL); + + if (kvp_val == NULL) + { + //g_warning("kvp_val for slot '%s' is NULL", OPTION_NAME_AUTO_FREEZE_DAYS); + return 0; + } + + tmp = kvp_value_get_double (kvp_val); + return (gint) tmp; +} + +GDate* qof_book_get_autofreeze_gdate (const QofBook *book) +{ + GDate* result = gnc_g_date_new_today(); + g_assert(book); + g_date_subtract_days(result, qof_book_get_num_days_autofreeze(book)); + return result; +} + const char* qof_book_get_string_option(const QofBook* book, const char* opt_name) { diff --git a/src/libqof/qof/qofbook.h b/src/libqof/qof/qofbook.h index f3a24b06bb..2d1e948393 100644 --- a/src/libqof/qof/qofbook.h +++ b/src/libqof/qof/qofbook.h @@ -248,6 +248,23 @@ 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 the auto-freeze feature should be used, otherwise + * FALSE. This is just a wrapper on get_num_days_autofreeze == 0. */ +gboolean qof_book_uses_autofreeze (const QofBook *book); + +/** Returns the number of days for auto-freeze transactions. If zero, + * the auto-freeze feature should be disabled (and uses_autofreeze + * returns FALSE). */ +gint qof_book_get_num_days_autofreeze (const QofBook *book); + +/** Returns the GDate that is the threshold for autofreeze. Any txn + * with posted-date lesser or equal to this date should be set to + * freeze. + * + * The returned object was allocated newly; the caller must + * g_date_free() the object afterwards. */ +GDate* qof_book_get_autofreeze_gdate (const QofBook *book); + /** Is the book shutting down? */ gboolean qof_book_shutting_down (const QofBook *book); diff --git a/src/libqof/qof/qofbookslots.h b/src/libqof/qof/qofbookslots.h index 448309549f..6ba04873d4 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_AUTO_FREEZE_DAYS N_("Day Threshold for Read-Only Transactions (red line)") #define OPTION_SECTION_BUDGETING N_("Budgeting") #define OPTION_NAME_DEFAULT_BUDGET N_("Default Budget") @@ -74,6 +75,7 @@ * KVP-OPTION-PATH * OPTION-SECTION-ACCOUNTS * OPTION-NAME-TRADING-ACCOUNTS + * OPTION-NAME-AUTO-FREEZE-DAYS * OPTION-SECTION-BUDGETING * OPTION-NAME-DEFAULT-BUDGET */ diff --git a/src/libqof/qof/test/test-qofbook.c b/src/libqof/qof/test/test-qofbook.c index d358d163c6..4080a6623a 100644 --- a/src/libqof/qof/test/test-qofbook.c +++ b/src/libqof/qof/test/test-qofbook.c @@ -387,6 +387,41 @@ test_book_use_trading_accounts( Fixture *fixture, gconstpointer pData ) } +static void +test_book_get_num_days_autofreeze( Fixture *fixture, gconstpointer pData ) +{ + const char *slot_path; + + /* create correct slot path */ + slot_path = (const char *) g_strconcat( KVP_OPTION_PATH, "/", OPTION_SECTION_ACCOUNTS, "/", OPTION_NAME_AUTO_FREEZE_DAYS, NULL ); + g_assert( slot_path != NULL ); + + g_test_message( "Testing default: No auto-freeze days are set" ); + g_assert( qof_book_uses_autofreeze( fixture-> book ) == FALSE ); + g_assert( qof_book_get_num_days_autofreeze( fixture-> book ) == 0 ); + + g_test_message( "Testing with incorrect slot path and some correct value - 17" ); + kvp_frame_set_double(qof_book_get_slots(fixture->book), OPTION_NAME_AUTO_FREEZE_DAYS, 17); + g_assert( qof_book_uses_autofreeze( fixture-> book ) == FALSE ); + g_assert( qof_book_get_num_days_autofreeze( fixture-> book ) == 0 ); + + g_test_message( "Testing when setting this correctly with some correct value - 17" ); + kvp_frame_set_double(qof_book_get_slots(fixture->book), slot_path, 17); + g_assert( qof_book_uses_autofreeze( fixture-> book ) == TRUE ); + g_assert( qof_book_get_num_days_autofreeze( fixture-> book ) == 17 ); + + g_test_message( "Testing when setting this correctly to zero again" ); + kvp_frame_set_double(qof_book_get_slots(fixture->book), slot_path, 0); + g_assert( qof_book_uses_autofreeze( fixture-> book ) == FALSE ); + g_assert( qof_book_get_num_days_autofreeze( fixture-> book ) == 0 ); + + g_test_message( "Testing when setting this correctly with some correct value - 32" ); + kvp_frame_set_double(qof_book_get_slots(fixture->book), slot_path, 32); + g_assert( qof_book_uses_autofreeze( fixture-> book ) == TRUE ); + g_assert( qof_book_get_num_days_autofreeze( fixture-> book ) == 32 ); + +} + static void test_book_mark_session_dirty( Fixture *fixture, gconstpointer pData ) { @@ -696,6 +731,7 @@ test_suite_qofbook ( void ) GNC_TEST_ADD( suitename, "increment and format counter", Fixture, NULL, setup, test_book_increment_and_format_counter, teardown ); GNC_TEST_ADD( suitename, "kvp changed", Fixture, NULL, setup, test_book_kvp_changed, teardown ); GNC_TEST_ADD( suitename, "use trading accounts", Fixture, NULL, setup, test_book_use_trading_accounts, teardown ); + GNC_TEST_ADD( suitename, "get autofreeze days", Fixture, NULL, setup, test_book_get_num_days_autofreeze, teardown ); GNC_TEST_ADD( suitename, "mark session dirty", Fixture, NULL, setup, test_book_mark_session_dirty, teardown ); GNC_TEST_ADD( suitename, "session dirty time", Fixture, NULL, setup, test_book_get_session_dirty_time, teardown ); GNC_TEST_ADD( suitename, "set dirty callback", Fixture, NULL, setup, test_book_set_dirty_cb, teardown );