GnuCash 2.4.99
Recurrence.h
00001 /* Recurrence.h:
00002  *
00003  *   A Recurrence represents the periodic occurrence of dates, with a
00004  *   beginning point.  For example, "Every Friday, beginning April 15,
00005  *   2005" or "The 1st of every 3rd month, beginning April 1, 2001."
00006  *
00007  *   Technically, a Recurrence can also represent certain useful
00008  *   "almost periodic" date sequences.  For example, "The last day of
00009  *   every month, beginning Feb. 28, 2005."
00010  *
00011  *   The main operation you can perform on a Recurrence is to find the
00012  *   earliest date in the sequence of occurrences that is after some
00013  *   specified date (often the "previous" occurrence).
00014  *
00015  *   In addition, you can use a GList of Recurrences to represent a
00016  *   sequence containing all the dates in each Recurrence in the list,
00017  *   and perform the same "next instance" computation for this
00018  *   sequence.
00019  *
00020  * Copyright (C) 2005, Chris Shoemaker <c.shoemaker@cox.net>
00021  *
00022  * This program is free software; you can redistribute it and/or
00023  * modify it under the terms of the GNU General Public License as
00024  * published by the Free Software Foundation; either version 2 of
00025  * the License, or (at your option) any later version.
00026  *
00027  * This program is distributed in the hope that it will be useful,
00028  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00029  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00030  * GNU General Public License for more details.
00031  *
00032  * You should have received a copy of the GNU General Public License
00033  * along with this program; if not, contact:
00034  *
00035  * Free Software Foundation           Voice:  +1-617-542-5942
00036  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
00037  * Boston, MA  02110-1301,  USA       gnu@gnu.org
00038  */
00039 
00040 #ifndef RECURRENCE_H
00041 #define RECURRENCE_H
00042 
00043 #include <glib.h>
00044 #include "Account.h"
00045 #include "gnc-numeric.h"
00046 
00047 typedef enum
00048 {
00049     PERIOD_ONCE,         /* Not a true period at all, but convenient here. */
00050     PERIOD_DAY,
00051     PERIOD_WEEK,
00052     PERIOD_MONTH,
00053     PERIOD_END_OF_MONTH, /* This is actually a period plus a phase. */
00054     PERIOD_NTH_WEEKDAY,  /* Also a phase, e.g. Second Tueday.       */
00055     PERIOD_LAST_WEEKDAY, /* Also a phase. */
00056     PERIOD_YEAR,
00057     NUM_PERIOD_TYPES,
00058     PERIOD_INVALID = -1,
00059 } PeriodType;
00060 
00061 typedef enum
00062 {
00063     WEEKEND_ADJ_NONE,
00064     WEEKEND_ADJ_BACK,    /* Previous weekday */
00065     WEEKEND_ADJ_FORWARD, /* Next weekday */
00066     NUM_WEEKEND_ADJS,
00067     WEEKEND_ADJ_INVALID = -1,
00068 } WeekendAdjust;
00069 
00070 /* Recurrences represent both the phase and period of a recurring event. */
00071 
00072 typedef struct
00073 {
00074     GDate start;         /* First date in the recurrence; specifies phase. */
00075     PeriodType ptype;    /* see PeriodType enum */
00076     guint16 mult;        /* a period multiplier */
00077     WeekendAdjust wadj;  /* see WeekendAdjust enum */
00078 } Recurrence;
00079 
00080 
00081 /* recurrenceSet() will enforce internal consistency by overriding
00082    inconsistent inputs so that 'r' will _always_ end up being a valid
00083    recurrence.
00084 
00085      - if the period type is invalid, PERIOD_MONTH is used.
00086 
00087      - if the period type is PERIOD_ONCE, then mult is ignored,
00088        otherwise, if mult is zero, then mult of 1 is used.
00089 
00090      - if the date is invalid, the current date is used.
00091 
00092      - if the period type specifies phase, the date is made to agree
00093        with that phase:
00094 
00095          - for PERIOD_END_OF_MONTH, the last day of date's month is used.
00096 
00097          - for PERIOD_NTH_WEEKDAY, a fifth weekday converts to a
00098            PERIOD_LAST_WEEKDAY
00099 
00100          - for PERIOD_LAST_WEEKDAY, the last day in date's month with
00101            date's day-of-week is used.
00102 
00103 */
00104 void recurrenceSet(Recurrence *r, guint16 mult, PeriodType pt,
00105                    const GDate *date, WeekendAdjust wadj);
00106 
00107 /* get the fields */
00108 PeriodType recurrenceGetPeriodType(const Recurrence *r);
00109 guint recurrenceGetMultiplier(const Recurrence *r);
00110 GDate recurrenceGetDate(const Recurrence *r);
00111 WeekendAdjust recurrenceGetWeekendAdjust(const Recurrence *r);
00112 
00113 /* Get the occurence immediately after refDate.
00114  *
00115  * This function has strict and precise post-conditions:
00116  *
00117  * Given a valid recurrence and a valid 'refDate', 'nextDate' will be
00118  * *IN*valid IFF the period_type is PERIOD_ONCE, and 'refDate' is
00119  * later-than or equal to the single occurrence (start_date).
00120  *
00121  * A valid 'nextDate' will _always_ be:
00122  *    - strictly later than the 'refDate', AND
00123  *    - later than or equal to the start date of the recurrence, AND
00124  *    - exactly an integral number of periods away from the start date
00125  *
00126  * Furthermore, there will be no date _earlier_ than 'nextDate' for
00127  * which the three things above are true.
00128  *
00129  */
00130 void recurrenceNextInstance(const Recurrence *r, const GDate *refDate,
00131                             GDate *nextDate);
00132 
00133 /* Zero-based.  n == 1 gets the instance after the start date. */
00134 void recurrenceNthInstance(const Recurrence *r, guint n, GDate *date);
00135 
00136 /* Get a time coresponding to the beginning (or end if 'end' is true)
00137    of the nth instance of the recurrence. Also zero-based. */
00138 time_t recurrenceGetPeriodTime(const Recurrence *r, guint n, gboolean end);
00139 
00144 gnc_numeric recurrenceGetAccountPeriodValue(const Recurrence *r,
00145         Account *acct, guint n);
00146 
00148 void recurrenceListNextInstance(const GList *r, const GDate *refDate,
00149                                 GDate *nextDate);
00150 
00151 /* These four functions are only for xml storage, not user presentation. */
00152 gchar *recurrencePeriodTypeToString(PeriodType pt);
00153 PeriodType recurrencePeriodTypeFromString(const gchar *str);
00154 gchar *recurrenceWeekendAdjustToString(WeekendAdjust wadj);
00155 WeekendAdjust recurrenceWeekendAdjustFromString(const gchar *str);
00156 
00157 /* For debugging.  Caller owns the returned string.  Not intl. */
00158 gchar *recurrenceToString(const Recurrence *r);
00159 gchar *recurrenceListToString(const GList *rlist);
00160 
00162 gboolean recurrenceListIsSemiMonthly(GList *recurrences);
00164 gboolean recurrenceListIsWeeklyMultiple(const GList *recurrences);
00165 
00178 gchar *recurrenceListToCompactString(GList *recurrence_list);
00179 
00181 int recurrenceCmp(Recurrence *a, Recurrence *b);
00182 int recurrenceListCmp(GList *a, GList *b);
00183 
00184 void recurrenceListFree(GList **recurrence);
00185 
00186 #endif  /* RECURRENCE_H */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines