When a user add a new recurrence event to a calendar I want to check if any of the recurrences overlap with events already in the calendar.
I saw the property Recurrences Data
and its XML but I didn't find a way to translate that value to dates I can test against the events dates on the calendar.
So, is there a way to expand the recurrences of an event in the ItemAdding event receiver of a calendar?
Edit
I manage to get all recurrencies for the item in the ItemAdded event. This is the code I'm using (some code omitted for brevity):
DateTime _dtAux = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
query.ExpandRecurrence = true;
// Get all events (and all recurrencies)
query.Query = String.Format(@"<Where>
<DateRangesOverlap>
<FieldRef Name='EventDate' />;
<FieldRef Name='EndDate' />
<FieldRef Name='RecurrenceID' />
<Value Type='DateTime'><Year /></Value>
</DateRangesOverlap>
</Where>");
query.CalendarDate = _dtAux;
SPListItemCollection existing_events = calendar.GetItems(query);
// Loop trough all the recurrencies of the item added (where clause)
foreach (var itemAdded in existing_events.Cast<SPListItem>().Where(x => Convert.ToInt64(x["ID"]) == properties.ListItemId))
{
if (properties.Cancel)
{
break;
}
DateTime _itemAddedStart = DateTime.Parse(itemAdded["EventDate"].ToString(), null, System.Globalization.DateTimeStyles.RoundtripKind);
DateTime _itemAddedEnd = DateTime.Parse(itemAdded["EndDate"].ToString(), null, System.Globalization.DateTimeStyles.RoundtripKind);
// Loop trough all the itens in the calendar except the item added (where clause)
foreach (var item in existing_events.Cast<SPListItem>().Where(x => Convert.ToInt64(x["ID"]) != properties.ListItemId))
{
DateTime _itemStart = DateTime.Parse(item["EventDate"].ToString(), null, System.Globalization.DateTimeStyles.RoundtripKind);
DateTime _itemEnd = DateTime.Parse(item["EndDate"].ToString(), null, System.Globalization.DateTimeStyles.RoundtripKind);
// Verify if the dates overlap
if (_itemAddedStart < _itemEnd && _itemStart < _itemAddedEnd)
{
properties.Cancel = true;
properties.ErrorMessage += "Não foi possível salvar o agendamento, pois um agendamento já foi feito nesta mesma data. <BR><BR>";
properties.ErrorMessage += String.Format("Evento: {0} <BR> Hora de Início: {1} <BR> Hora de Término: {2} <BR><BR>", item["Title"], item["EventDate"], item["EndDate"]);
properties.ErrorMessage += "Por favor, volte e escolha uma nova data para o agendamento.";
// Delete List item
SPListItem itemToDelete = calendar.GetItemById(properties.ListItemId);
itemToDelete.Delete();
break;
}
}
}
Now if I delete the item it continues to appear in the calendar and the properties.ErrorMessage
doesn't display. Just after a refresh on the page it goes away (still no message).
Any ideas on how to make the item vanish after beign deleted?