Sunday, August 17, 2008

PeopleSoft/Calendar Integration

Last week three different people asked me if it was possible to integrate PeopleSoft with a calendar management program (Microsoft Outlook, to be specific). Whether you are trying to create appointments for HRMS Enterprise Learning classes, ELM training classes, or eRecruiting interviews, the solution is the same. Since most calendar programs support the iCalendar (ics) format and since iCalendar files are text files, we can generate appointments from PeopleSoft IScripts and serve those as file downloads. As a starting point, we can copy the event example from the iCalendar RFC:

PRODID:-//hacksw/handcal//NONSGML v1.0//EN
SUMMARY:Bastille Day Party

Modifying this a little, we can convert it to an HTML object with bind parameters:

PRODID:-//My Company//PeopleCode vCal 1.0//EN

We can serve this text to a client browser using an IScript that looks something like:

Function IScript_GetICalendarEvent
Local DateTime &startTime;
Local DateTime &endTime;
Local DateTime &tempTime;
Local string &startTimeUTC;
Local string &endTimeUTC;
Local string &eventTitle;

REM ** TODO: Initialize date and title variables from database;

REM ** change time zone to your time zone;
&tempTime = DateTimeToTimeZone(&startTime, "PST", "UTC");
&startTimeUTC = DateTimeToLocalizedString(&tempTime, "yyyyMMdd'T'HHmmss'Z'");

&tempTime = DateTimeToTimeZone(&endTime, "PST", "UTC");
&endTimeUTC = DateTimeToLocalizedString(&tempTime, "yyyyMMdd'T'HHmmss'Z'");

%Response.WriteLine(GetHTMLText(HTML.ICAL_EVT, &startTimeUTC, &endTimeUTC, &eventTitle);

All you have to do is fetch your event data from the database and provide your users with a means to access this IScript. If you want your users to be able to access this IScript from a workflow event, then modify your e-mail workflow template to include a link to this IScript. Likewise, if you want your users to be able to download a calendar event from a page, add a link for this IScript to that page. When creating a link to this IScript, be sure to include all the keys required to fetch the event's data from your database.

If you study the iCalendar RFC, you will notice that it also includes a specification for tasks. You could modify this example to add tasks for voucher due dates, etc. I'll leave the possibilities and implementation to your imagination.

This example is only meant to be a starting point. Since iCalendar support has many potential uses in PeopleSoft, I would create a reusable App Class API for rendering iCalendar (ics) files.

DateTimeToTimeZone with Invalid Timezone

I've been working on a PeopleCode App Class API for creating iCalendar files. To convert from an event's time zone to the iCalendar UTC format, I've been using the PeopleCode DateTimeToTimeZone function. I was curious what would happen if I used an invalid time zone value for the source time zone parameter. I thought the function would throw an error. Instead, the function performs the conversion, but uses the base time zone as the source time zone. The function will also use the base time zone if you pass in an invalid time zone for the destination time zone. In fact, if you pass in an invalid time zone for both the source and destination time zone, then this function will not perform a conversion. Instead, it will return the same value as the OldDateTime parameter.

Since it is Summer, I thought I would try passing PDT and EDT. Of course, I expected a 3 hour difference between the 2 time zones. I was shocked to see the same results for both time zones. It was this test that clued me in to this base time zone behavior. Just to confirm, I tried JJM, 123456, PST, EST, and EET. JJM, 123456, and PST all returned the same result, the base time zone value (PST is my base time zone). EST and EET returned the expected values corresponding to those time zones.

Just in case you are working on your own ics calendar integration and are wondering how to format dates, here is the code I'm using:

Function formatDateTimeToUTC (&dttm as DateTime, &timezone as String) Returns String
Local datetime &tempTime = DateTimeToTimeZone(&dttm, &timezone, "UTC");

Return Year(&tempTime) | NumberToDisplayString("%02", Month(&tempTime)) | NumberToDisplayString("%02", Day(&tempTime)) | "T" | NumberToDisplayString("%02", Hour(&tempTime)) | NumberToDisplayString("%02", Minute(&tempTime)) | NumberToDisplayString("%02", Second(&tempTime)) | "Z";