r19463 - gnucash/trunk/src - Add new function gnc_sx_get_num_occur_daterange and unittests for this in test-sx.c.

Christian Stimming cstim at code.gnucash.org
Sun Aug 22 07:10:25 EDT 2010


Author: cstim
Date: 2010-08-22 07:10:25 -0400 (Sun, 22 Aug 2010)
New Revision: 19463
Trac: http://svn.gnucash.org/trac/changeset/19463

Modified:
   gnucash/trunk/src/app-utils/test/test-sx.c
   gnucash/trunk/src/engine/SchedXaction.c
   gnucash/trunk/src/engine/SchedXaction.h
Log:
Add new function gnc_sx_get_num_occur_daterange and unittests for this in test-sx.c.

Modified: gnucash/trunk/src/app-utils/test/test-sx.c
===================================================================
--- gnucash/trunk/src/app-utils/test/test-sx.c	2010-08-22 11:10:12 UTC (rev 19462)
+++ gnucash/trunk/src/app-utils/test/test-sx.c	2010-08-22 11:10:25 UTC (rev 19463)
@@ -12,22 +12,25 @@
 test_basic()
 {
     GncSxInstanceModel *model;
-    GDate *yesterday, *range_end_tomorrow;
-    SchedXaction *foo;
+    GDate yesterday, today, tomorrow, before_yesterday, after_tomorrow;
+    SchedXaction *one_sx;
 
-    yesterday = g_date_new();
-    g_date_clear(yesterday, 1);
-    g_date_set_time_t(yesterday, time(NULL));
-    g_date_subtract_days(yesterday, 1);
+    g_date_clear(&today, 1);
+    g_date_set_time_t(&today, time(NULL));
 
-    foo = add_daily_sx("foo", yesterday, NULL, NULL);
+    yesterday = today;
+    g_date_subtract_days(&yesterday, 1);
+    before_yesterday = yesterday;
+    g_date_subtract_days(&before_yesterday, 1);
+    tomorrow = today;
+    g_date_add_days(&tomorrow, 1);
+    after_tomorrow = tomorrow;
+    g_date_add_days(&after_tomorrow, 1);
 
-    range_end_tomorrow = g_date_new();
-    g_date_clear(range_end_tomorrow, 1);
-    g_date_set_time_t(range_end_tomorrow, time(NULL));
-    g_date_add_days(range_end_tomorrow, 1);
-    model = gnc_sx_get_instances(range_end_tomorrow, TRUE);
+    one_sx = add_daily_sx("foo", &yesterday, NULL, NULL);
 
+    model = gnc_sx_get_instances(&tomorrow, TRUE);
+
     {
         GncSxInstances *insts;
         GList *iter;
@@ -42,8 +45,17 @@
         }
     }
 
+    xaccSchedXactionSetEndDate(one_sx, &tomorrow);
+
+    do_test(gnc_sx_get_num_occur_daterange(one_sx, &before_yesterday, &before_yesterday) == 0, "0 occurrences before start");
+    do_test(gnc_sx_get_num_occur_daterange(one_sx, &today, &today) == 1, "1 occurrence today");
+    do_test(gnc_sx_get_num_occur_daterange(one_sx, &today, &tomorrow) == 2, "2 occurrence today and tomorrow");
+    do_test(gnc_sx_get_num_occur_daterange(one_sx, &yesterday, &tomorrow) == 3, "3 occurrences from yesterday to tomorrow");
+    do_test(gnc_sx_get_num_occur_daterange(one_sx, &tomorrow, &tomorrow) == 1, "1 occurrence tomorrow");
+    do_test(gnc_sx_get_num_occur_daterange(one_sx, &after_tomorrow, &after_tomorrow) == 0, "0 occurrence after the SX has ended");
+
     g_object_unref(G_OBJECT(model));
-    remove_sx(foo);
+    remove_sx(one_sx);
 }
 
 static void
@@ -58,6 +70,7 @@
     model = gnc_sx_get_instances(end, TRUE);
     do_test(g_list_length(model->sx_instance_list) == 0, "no instances");
     g_object_unref(G_OBJECT(model));
+    g_date_free(end);
     success("empty");
 }
 

Modified: gnucash/trunk/src/engine/SchedXaction.c
===================================================================
--- gnucash/trunk/src/engine/SchedXaction.c	2010-08-22 11:10:12 UTC (rev 19462)
+++ gnucash/trunk/src/engine/SchedXaction.c	2010-08-22 11:10:25 UTC (rev 19463)
@@ -689,7 +689,70 @@
     }
 }
 
+gint gnc_sx_get_num_occur_daterange(const SchedXaction *sx, const GDate* start_date, const GDate* end_date)
+{
+    gint result = 0;
+    SXTmpStateData *tmpState;
 
+    /* SX still active? If not, return now. */
+    if ((xaccSchedXactionHasOccurDef(sx)
+         && xaccSchedXactionGetRemOccur(sx) <= 0)
+        || (xaccSchedXactionHasEndDate(sx)
+            && g_date_compare(xaccSchedXactionGetEndDate(sx), start_date) < 0))
+    {
+        return result;
+    }
+
+    tmpState = gnc_sx_create_temporal_state (sx);
+
+    /* No valid date? SX has never occurred so far. */
+    if (!g_date_valid(&tmpState->last_date))
+    {
+        /* SX has never occurred so far */
+        gnc_sx_incr_temporal_state (sx, tmpState);
+        if (xaccSchedXactionHasOccurDef(sx) && tmpState->num_occur_rem <= 0)
+        {
+            gnc_sx_destroy_temporal_state (tmpState);
+            return result;
+        }
+    }
+
+    /* Increase the tmpState until we are in our interval of
+     * interest. Only calculate anything if the sx hasn't already
+     * ended. */
+    while (g_date_compare(&tmpState->last_date, start_date) < 0)
+    {
+        gnc_sx_incr_temporal_state (sx, tmpState);
+        if (xaccSchedXactionHasOccurDef(sx) && tmpState->num_occur_rem <= 0)
+        {
+            gnc_sx_destroy_temporal_state (tmpState);
+            return result;
+        }
+    }
+
+    /* Now we are in our interval of interest. Increment the
+     * occurrence date until we are beyond the end of our interval. */
+    while ((g_date_compare(&tmpState->last_date, end_date) <= 0)
+           && (!xaccSchedXactionHasEndDate(sx)
+               || g_date_compare(&tmpState->last_date, xaccSchedXactionGetEndDate(sx)) <= 0))
+    {
+        ++result;
+        gnc_sx_incr_temporal_state (sx, tmpState);
+        /* Make sure to check for invalid dates here: It means the SX
+         * has ended. */
+        if (!g_date_valid(&tmpState->last_date)
+            || (xaccSchedXactionHasOccurDef(sx)
+                && tmpState->num_occur_rem <= 0))
+        {
+            break;
+        }
+    }
+
+    gnc_sx_destroy_temporal_state (tmpState);
+    return result;
+}
+
+
 KvpValue *
 xaccSchedXactionGetSlot( const SchedXaction *sx, const char *slot )
 {

Modified: gnucash/trunk/src/engine/SchedXaction.h
===================================================================
--- gnucash/trunk/src/engine/SchedXaction.h	2010-08-22 11:10:12 UTC (rev 19462)
+++ gnucash/trunk/src/engine/SchedXaction.h	2010-08-22 11:10:25 UTC (rev 19463)
@@ -189,6 +189,10 @@
 gint xaccSchedXactionGetRemOccur( const SchedXaction *sx );
 void xaccSchedXactionSetRemOccur( SchedXaction *sx, gint numRemain );
 
+/** Calculates and returns the number of occurrences of the given SX
+ * in the given date range (inclusive). */
+gint gnc_sx_get_num_occur_daterange(const SchedXaction *sx, const GDate* start_date, const GDate* end_date);
+
 /** \brief Get the instance count.
  *
  *   This is incremented by one for every created



More information about the gnucash-changes mailing list