Service Calendar is a key component used in Field service for scheduling the work. Anyway, Calendar alone can be used for many different usages since its showing the working hours/ availability of a User. Here I am illustrating how to pro-grammatically access the calendar.
First of all, lets see how to set users availability in the calendar. In order to make it simple I am going to set if someone is available in given day or not. (not going into different time slots, which is also possible). Go to any
User and go to
Work Hours. Then go to
New Weekly Schedule as below;
Please set the schedule as you wish in the resulting pane as below; Since I am interested in daily basis, I select 24 hours.
Once save you will see calendar been updated.
Now, this is the code snippet to check the availability of the User through calendar;
public static bool IsUserAvailable(IOrganizationService OrganizationService, Guid UserId)
{
bool isUserAvailable = false;
QueryScheduleRequest scheduleRequest = new QueryScheduleRequest
{
ResourceId = UserId,
Start = DateTimeUtility.RetrieveLocalTimeFromUTCTime(OrganizationService, DateTime.Now),
End = DateTimeUtility.RetrieveLocalTimeFromUTCTime(OrganizationService, DateTime.Now.AddSeconds(5)),
TimeCodes = new TimeCode[] { TimeCode.Available }
};
QueryScheduleResponse scheduleResponse = (QueryScheduleResponse)OrganizationService.Execute(scheduleRequest);
if (scheduleResponse.TimeInfos.Length > 0)
isUserAvailable = true;
return isUserAvailable;
}
You may notice that I am passing the local time in
QueryScheduleRequest in above code since I am setting the local time zone in the Calendar also. I am also giving here the methods to be be used in time conversions;
internal static DateTime RetrieveLocalTimeFromUTCTime(IOrganizationService service, DateTime utcTime)
{
return RetrieveLocalTimeFromUTCTime(utcTime, RetrieveCurrentUsersSettings(service), service);
}
internal static int? RetrieveCurrentUsersSettings(IOrganizationService service)
{
var currentUserSettings = service.RetrieveMultiple(
new QueryExpression("usersettings")
{
ColumnSet = new ColumnSet("timezonecode"),
Criteria = new FilterExpression
{
Conditions =
{
new ConditionExpression("systemuserid", ConditionOperator.EqualUserId)
}
}
}).Entities[0].ToEntity<Entity>();
return (int?)currentUserSettings.Attributes["timezonecode"];
}
internal static DateTime RetrieveLocalTimeFromUTCTime(DateTime utcTime, int? timeZoneCode, IOrganizationService service)
{
if (!timeZoneCode.HasValue)
return DateTime.Now;
var request = new LocalTimeFromUtcTimeRequest
{
TimeZoneCode = timeZoneCode.Value,
UtcTime = utcTime.ToUniversalTime()
};
var response = (LocalTimeFromUtcTimeResponse)service.Execute(request);
return response.LocalTime;
}
Hope this helps!