I'm currently working on a solution which allows users to book a room for a meeting at a given time, with the option to make their meeting recurring using the calendar component that I'm exposing on the client side. Obviously in this scenario I don't want to allow any conflicts - one room cannot be double-booked.
I have a working solution that checks to make sure an event with only a single instance does not conflict with any other event on the calendar, but realized that this doesn't exactly work for the use case wherein the new meeting is also recurring (the other meetings in the series aren't checked to see if they conflict with other meetings).
My current plan is to expand out the new meeting with recurrence to all occurrences for X amount of time, and then check each of those occurrences to make sure there are no conflicts (as below):
bool available = true;
// Get all meetings for this conference room
var allMeetings = ...
// Create an ICalendar object
Calendar calendar = new Calendar();
// Add this new meeting to the calendar
var newMeetingEvent = calendar.Create<Event>();
newMeetingEvent.Start = new CalDateTime(meeting.StartTime, _timezone);
newMeetingEvent.End = new CalDateTime(meeting.EndTime, _timezone);
if (!string.IsNullOrEmpty(meeting.RecurrenceRule))
{
newMeetingEvent.RecurrenceRules.Add(new RecurrencePattern(meeting.RecurrenceRule));
}
calendar.Events.Add(newMeetingEvent);
foreach (var m in allMeetings)
{
// Create an ICalendar Event
var calEvent = calendar.Create<Event>();
calEvent.Start = new CalDateTime(m.StartTime, _timezone);
calEvent.End = new CalDateTime(m.EndTime, _timezone);
if (!string.IsNullOrEmpty(m.RecurrenceRule))
{
calEvent.RecurrenceRules.Add(new RecurrencePattern(m.RecurrenceRule));
}
calendar.Events.Add(calEvent);
}
// Expand the new meeting out over 10 years and check to make sure there are no collisions
var newMeetingOccurrences = newMeetingEvent.GetOccurrences(newMeetingEvent.DtStart, newMeetingEvent.DtStart.AddYears(10)).ToList();
foreach (var o in newMeetingOccurrences)
{
var occurrences = calendar.GetOccurrences(o.Period.StartTime, o.Period.EndTime);
if (occurrences.Count > 1)
{
available = false;
break;
}
}
Is there a better or alternative way to check for conflicts like this? This works and is acceptable, and won't always end up evaluating 3500 instances, but it doesn't seem like the most elegant solution.