public static void PublishRosterEvent(Guid itemId, int daysAhead) { var dataService = new RosterDataService(); var item = dataService.GetRosterEvent(itemId); if (item == null) { throw new Exception(string.Format("Roster with ID '{0}' does not exists!", itemId)); } if (!item.GetIsRecurrence()) { throw new Exception(string.Format("Unable to publish non recurrent Roster Event with ID '{0}'!", itemId)); } var wrListFields = new RosterConfigService().GetList(TableIDs.WORKING_ROSTERS).ListMetadataFields; var plannedRosterProps = item.RosterEventDictionary; var publishPeriodStart = DateTime.Today; var publishPeriodEnd = DateTime.Today.AddDays(daysAhead); var expandedEvents = RecurrenceItemExpander.Expand(new List <RosterEvent> { item }, null, publishPeriodStart, publishPeriodEnd, FieldNames.START_DATE, FieldNames.END_DATE, SPContext.Current.Web.RegionalSettings.TimeZone); var skipProps = new[] { FieldNames.START_DATE, FieldNames.END_DATE, FieldNames.RECURRENCE, FieldNames.ROSTER_EVENT_ID, FieldNames.ID, FieldNames.PARENT_ROSTER_ID }; var expandedRosterEvents = expandedEvents as IList <ExpandedRosterEvent> ?? expandedEvents.ToList(); publishPeriodStart = expandedRosterEvents.Min(expandedEvent => expandedEvent.StartDate); publishPeriodEnd = expandedRosterEvents.Max(expandedEvent => expandedEvent.StartDate); #region Get Working Rosters from period to avoid duplicates // get required fields var startDateFld = wrListFields.FirstOrDefault(itm => itm.InternalName == FieldNames.START_DATE); var endDateFld = wrListFields.FirstOrDefault(itm => itm.InternalName == FieldNames.END_DATE); var parentIdFld = wrListFields.FirstOrDefault(itm => itm.InternalName == FieldNames.PARENT_ROSTER_ID); var rEventIdFld = wrListFields.FirstOrDefault(itm => itm.InternalName == FieldNames.ROSTER_EVENT_ID); var qp = new QueryParams { SkipRows = 0, TakeRows = 500 }; qp.SelectCriteria.Add(startDateFld); qp.SelectCriteria.Add(rEventIdFld); qp.WhereCriteria.Add(new Tuple <ListMetadataField, CompareType, ConcateOperator, object, string> (parentIdFld, CompareType.Equal, ConcateOperator.And, itemId, null)); qp.WhereCriteria.Add(new Tuple <ListMetadataField, CompareType, ConcateOperator, object, string> (startDateFld, CompareType.LessOrEqual, ConcateOperator.And, publishPeriodEnd, null)); qp.WhereCriteria.Add(new Tuple <ListMetadataField, CompareType, ConcateOperator, object, string> (endDateFld, CompareType.MoreOrEqual, ConcateOperator.And, publishPeriodStart, null)); var existingWorkRosters = dataService.ListRosterEventProperties(TableIDs.WORKING_ROSTERS, qp); var existingKeys = existingWorkRosters.Select(wrProps => wrProps.FirstOrDefault(ff => ff.Key == FieldNames.START_DATE)).Select(stKey => (DateTime)stKey.Value).ToList(); #endregion foreach (var expEvent in expandedRosterEvents) { var startDate = expEvent.StartDate; var endDate = expEvent.EndDate; if (existingKeys.Contains(startDate)) { continue; } // this WorkingRoster instance already published var newRoEv = dataService.CreateRosterEvent(TableIDs.WORKING_ROSTERS, (int)RosterEventType.WorkingRosterEvent); newRoEv.RosterEventDictionary[FieldNames.START_DATE] = startDate; newRoEv.RosterEventDictionary[FieldNames.END_DATE] = endDate; newRoEv.RosterEventDictionary[FieldNames.END_DATE] = endDate; newRoEv.RosterEventDictionary[FieldNames.RECURRENCE] = null; newRoEv.RosterEventDictionary[FieldNames.PARENT_ROSTER_ID] = itemId; foreach (var propName in plannedRosterProps.Keys.Where(propName => !skipProps.Contains(propName))) { newRoEv.RosterEventDictionary[propName] = plannedRosterProps[propName]; } dataService.SaveRosterEvent(newRoEv, TableIDs.WORKING_ROSTERS); } }