Wednesday, 2 May 2012

SharePoint 2007: Birthday web part "datenoyear" issues

We built a Birthday webpart that returns the first x birthdays starting today.
The Birthday profile field, is type "datenoyear". What I noticed is that this field includes the year that you fill in the birthday date. For instance for "18 January" it will fill in 1/18/2009.

The problems lays on birthdays that the users inserted back in 2007 & 2008. Their birthdays are queried according to the query below:
            query.Append(birthdayField);
            query.Append("\" >= GETGMTDATE() ) ");
            query.Append("ORDER BY \"");
            query.Append(birthdayField);
            query.Append( "\"</QueryText>" );

Because some functions like MONTH() or DAY(), do not work in MOSS FullTextSqlQuery, one of the ways to get around this was creating a scheduled task that updates birthdays every week, before a full indexing crawll happens.

This script was developed by a colleague at TamTam (Peter Geritsen), I added code, to update to the following year birthdays previously to the current day, so that in the last months of a year shows birthdays of the following year.

CODE (posible to download, see BrithdayReset_SourceCode.zip file in this post):

...
UserProfileManager profileManager = new UserProfileManager(context);
                    IEnumerator profileEnumerator = profileManager.GetEnumerator();
                    int countUpdated = 0;
                    while (profileEnumerator.MoveNext())
                    {
                        UserProfile profile = profileEnumerator.Current as UserProfile;

                        if (profile[birthdayFieldName].Count != 0)
                        {
                            DateTime birthday = (DateTime)profile[birthdayFieldName].Value;

                            //if (birthday <= DateTime.Now.AddDays(-1))
                            int yearDiff = DateTime.Now.Year - birthday.Year;
                            if (yearDiff != 0)
                            {
                                // set year to this year
                                birthday = birthday.AddYears(yearDiff);
                                profile[birthdayFieldName].Value = birthday;
                                Console.WriteLine("Birthday of {0} changed to: {1}", profile["PreferredName"].Value, birthday.ToShortDateString() + " : " + birthday.ToString());
                                countUpdated++;
                            }

                            //if the birthday has already been, must update it to the following year.
                            //This prevents from birthdays of the following next year by the last weeks of the year not showing.
                            if(DateTime.Compare(birthday, DateTime.Now)<0)
                            {
                                birthday = birthday.AddYears(1);
                                profile[birthdayFieldName].Value = birthday;
                                Console.WriteLine("Birthday of {0} changed to: {1}", profile["PreferredName"].Value, birthday.ToShortDateString() + " : " + birthday.ToString());
                                countUpdated++;
                            }

                            profile.Commit();   
                        }
                    }

...

Run the script:
BirthdayReset fieldName PortalURL
You can make it a scheduled task in Control Panel to happen periodically

NOTE:
Architecturaly it is more "elegant" to create a TimerJob that will run this code periodically.

Download Source Code:
BirthdayReset_SourceCode.zip (1.3 MB)


No comments: