Esempio n. 1
0
        /// <summary>
        /// Old DDay.iCal does it WRONG, because doesn't respect Timezones DST rules or offsets,
        /// just append the TZ to them but does no calculations, so all DST changes and offsets comes
        /// from the local machine.
        /// </summary>
        /// <returns></returns>
        static string DDayRecurrentExample(string tz)
        {
            // This time created is being used as the local time on the time zone later specified, so
            // is NOT the local machine time and is a different UTC value depending on the TZ
            var now   = new DateTime(2016, 1, 1, 12, 0, 0);
            var later = now.AddHours(1);

            var rrule = new DDay.iCal.RecurrencePattern(DDay.iCal.FrequencyType.Monthly, 1)
            {
                Count = 12
            };

            var e = new DDay.iCal.Event
            {
                DTStart = new DDay.iCal.iCalDateTime(now, tz),
                DTEnd   = new DDay.iCal.iCalDateTime(later, tz)
            };

            e.RecurrenceRules.Add(rrule);

            var calendar = new DDay.iCal.iCalendar();

            calendar.Events.Add(e);

            //var serializer = new CalendarSerializer(new SerializationContext());
            //return serializer.SerializeToString(calendar);

            var end = new DateTime(2017, 1, 1, 12, 0, 0);

            return(e.GetOccurrences(now, end).Aggregate("", (ret, a) =>
            {
                return ret + a.Period.StartTime.UTC.ToString() + "\n";
            }));
        }
Esempio n. 2
0
        public virtual List <DateRange> GetScheduleDateRanges(Schedule schedule, DateTime beginDateTime, DateTime endDateTime)
        {
            if (schedule == null)
            {
                return(new List <DateRange>());
            }

            var result = new List <DateRange>();

            DDay.iCal.Event calEvent = schedule.GetCalenderEvent();
            if (calEvent != null && calEvent.DTStart != null)
            {
                var occurrences = ScheduleICalHelper.GetOccurrences(calEvent, beginDateTime, endDateTime);
                result = occurrences
                         .Where(a =>
                                a.Period != null &&
                                a.Period.StartTime != null &&
                                a.Period.EndTime != null)
                         .Select(a => new DateRange
                {
                    Start = DateTime.SpecifyKind(a.Period.StartTime.Value, DateTimeKind.Local).AddMinutes(-schedule.CheckInStartOffsetMinutes ?? 0),
                    End   = DateTime.SpecifyKind(a.Period.EndTime.Value, DateTimeKind.Local)
                })
                         .ToList();
                // ensure the the datetime is DateTimeKind.Local since iCal returns DateTimeKind.UTC
            }
            return(result);
        }
Esempio n. 3
0
        /// <summary>
        /// Calculates the display title for an <see cref="AttendanceOccurrence"/>.
        /// </summary>
        /// <param name="occurrence">The <see cref="AttendanceOccurrence"/>.</param>
        private string GetOccurrenceTitle(AttendanceOccurrence occurrence)
        {
            bool hasTitle    = (!string.IsNullOrWhiteSpace(occurrence.Name));
            bool hasSchedule = (occurrence.Schedule != null);

            if (hasSchedule)
            {
                // This block is unnecessary if the event has a name (because the name will take priority over the schedule, anyway), but it
                // has been intentionally left in place to prevent anyone from creating an unintentional bug in the future, as it affects
                // the logic below.
                DDay.iCal.Event calendarEvent = occurrence.Schedule.GetCalendarEvent();
                if (calendarEvent == null)
                {
                    hasSchedule = false;
                }
            }

            if (hasTitle)
            {
                return(occurrence.Name);
            }
            else if (hasSchedule)
            {
                return(string.Format(
                           "{0} - {1}",
                           occurrence.Group.Name,
                           occurrence.Schedule.GetCalendarEvent().DTStart.Value.TimeOfDay.ToTimeString()));
            }
            else
            {
                return(occurrence.Group.Name);
            }
        }
Esempio n. 4
0
        public static string MakeEventUid(DDay.iCal.Event evt)
        {
            //var ticks = DateTime.Now.Ticks;
            //var randnum = Utils._random.Next();
            // return string.Format("{0}-{1}@{2}", ticks, randnum, ElmcityUtils.Configurator.appdomain);
            var summary_bytes = System.Text.Encoding.UTF8.GetBytes(evt.Summary.ToString());

            return(string.Format("{0}-{1}@{2}", Convert.ToBase64String(summary_bytes), evt.DTStart.Ticks, ElmcityUtils.Configurator.appdomain));
        }
Esempio n. 5
0
        public virtual DayOfWeek GetLastDayOfWeek(Schedule schedule, DateTime beginDateTime, DateTime endDateTime)
        {
            if (schedule == null)
            {
                return(DayOfWeek.Sunday);
            }

            DDay.iCal.Event calEvent = schedule.GetCalenderEvent();
            if (calEvent != null && calEvent.DTStart != null)
            {
                var occurrences = ScheduleICalHelper.GetOccurrences(calEvent, beginDateTime, endDateTime);
                return(occurrences
                       .FirstOrDefault(a =>
                                       a.Period != null &&
                                       a.Period.StartTime != null &&
                                       a.Period.EndTime != null)
                       .Period.StartTime.DayOfWeek);
                // ensure the the datetime is DateTimeKind.Local since iCal returns DateTimeKind.UTC
            }
            return(DayOfWeek.Sunday);
        }
Esempio n. 6
0
        public static DDay.iCal.Event AsDDayEvent(this IEvent Event)
        {
            var tEvt = new DDayEvent
                           {
                               DTStart = new DDay.iCal.iCalDateTime(Event.Date + Event.From),
                               DTEnd = new DDay.iCal.iCalDateTime(Event.Date + Event.Till)
                           };

            if (Event is RESTEvent)
                tEvt.Summary = String.Format("{0} {1}", ((RESTEvent)Event).TypeCode, Event.Code);
            else if (Event is Event)
            {
                string evtCode = (Event.Group != GroupID.Empty) ? string.Format("{0} Gruppe: {1}", Event.BasicCode, Event.Group) : Event.BasicCode;
                tEvt.Summary = evtCode;
            }

            tEvt.Location = String.Format("Raum {0}", Event.Room);
            tEvt.Priority = Event.Priority;
            tEvt.Description = String.Format("Raum {0} - Dozent: {1}", Event.Room, Event.Tutor);
            return tEvt;
        }
            /// <summary>
            /// Sets the DisplayTitle.
            /// </summary>
            private void GetOccurrenceTitle()
            {
                bool hasSchedule = (Occurrence.Schedule != null);

                DDay.iCal.Event calendarEvent = null;
                if (hasSchedule)
                {
                    calendarEvent = Occurrence.Schedule.GetCalendarEvent();
                    if (calendarEvent == null)
                    {
                        hasSchedule = false;
                    }
                }

                // Format date and time.
                if (hasSchedule)
                {
                    DisplayTitle = string.Format(
                        "{0} - {1}, {2}",
                        Occurrence.Group.Name,
                        Occurrence.OccurrenceDate.ToString("dddd, MMMM d, yyyy"),
                        Occurrence.Schedule.GetCalendarEvent().DTStart.Value.TimeOfDay.ToTimeString());
                }
                else
                {
                    DisplayTitle = string.Format(
                        "{0} - {1}",
                        Occurrence.Group.Name,
                        Occurrence.OccurrenceDate.ToString("dddd, MMMM d, yyyy"));
                }

                // Add Location title.
                if (Occurrence.Location != null)
                {
                    DisplayTitle = string.Format(
                        "{0} - {1}",
                        DisplayTitle,
                        Occurrence.Location.EntityStringValue);
                }
            }
        public static DDay.iCal.IEvent ConvertEvent(BaseEvent eventObj)
        {
            if (eventObj == null)
            {
                return(null);
            }

            var result = new DDay.iCal.Event();

            result.Summary = eventObj.Name;

            result.Location = string.Empty;

            result.Description = eventObj.Description;

            result.IsAllDay = eventObj.AllDayLong;

            result.UID = eventObj.Uid;

            result.Start = new DDay.iCal.iCalDateTime(eventObj.UtcStartDate, TimeZoneInfo.Utc.Id);

            result.End = new DDay.iCal.iCalDateTime(eventObj.UtcEndDate, TimeZoneInfo.Utc.Id);

            result.RecurrenceRules = new List <DDay.iCal.IRecurrencePattern>();

            var rrule = eventObj.RecurrenceRule.ToString(true);

            if (!string.IsNullOrEmpty(rrule))
            {
                result.RecurrenceRules.Add(new DDay.iCal.RecurrencePattern(rrule));
            }

            result.Status = (DDay.iCal.EventStatus)eventObj.Status;

            return(result);
        }
        public static DDay.iCal.IEvent CreateEvent(string name, string description, DateTime startUtcDate, DateTime endUtcDate, string repeatType, bool isAllDayLong, EventStatus status)
        {
            var evt = new DDay.iCal.Event
            {
                Summary         = name,
                Location        = string.Empty,
                Description     = description,
                IsAllDay        = isAllDayLong,
                DTStamp         = new DDay.iCal.iCalDateTime(DateTime.UtcNow, TimeZoneInfo.Utc.Id),
                Start           = new DDay.iCal.iCalDateTime(startUtcDate, TimeZoneInfo.Utc.Id),
                End             = new DDay.iCal.iCalDateTime(endUtcDate, TimeZoneInfo.Utc.Id),
                RecurrenceRules = new List <DDay.iCal.IRecurrencePattern>(),
                Status          = (DDay.iCal.EventStatus)status
            };

            var rrule = RecurrenceRule.Parse(repeatType).ToString(true);

            if (!string.IsNullOrEmpty(rrule))
            {
                evt.RecurrenceRules.Add(new DDay.iCal.RecurrencePattern(rrule));
            }

            return(evt);
        }
Esempio n. 10
0
        /// <summary>
        /// Executes the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        public virtual void Execute(IJobExecutionContext context)
        {
            JobDataMap dataMap   = context.JobDetail.JobDataMap;
            var        groupType = GroupTypeCache.Read(dataMap.GetString("GroupType").AsGuid());
            int        attendanceRemindersSent = 0;

            if (groupType.TakesAttendance && groupType.SendAttendanceReminder)
            {
                // Get the occurrence dates that apply
                var dates = new List <DateTime>();
                dates.Add(RockDateTime.Today);
                try
                {
                    string[] reminderDays = dataMap.GetString("SendReminders").Split(',');
                    foreach (string reminderDay in reminderDays)
                    {
                        if (reminderDay.Trim() != string.Empty)
                        {
                            var reminderDate = RockDateTime.Today.AddDays(0 - Convert.ToInt32(reminderDay));
                            if (!dates.Contains(reminderDate))
                            {
                                dates.Add(reminderDate);
                            }
                        }
                    }
                }
                catch { }

                var rockContext        = new RockContext();
                var groupService       = new GroupService(rockContext);
                var groupMemberService = new GroupMemberService(rockContext);
                var scheduleService    = new ScheduleService(rockContext);
                var attendanceService  = new AttendanceService(rockContext);

                var startDate = dates.Min();
                var endDate   = dates.Max().AddDays(1);

                // Find all 'occurrences' for the groups that occur on the affected dates
                var occurrences = new Dictionary <int, List <DateTime> >();
                foreach (var group in groupService
                         .Queryable("Schedule").AsNoTracking()
                         .Where(g =>
                                g.GroupTypeId == groupType.Id &&
                                g.IsActive &&
                                g.Schedule != null &&
                                g.Members.Any(m =>
                                              m.GroupMemberStatus == GroupMemberStatus.Active &&
                                              m.GroupRole.IsLeader &&
                                              m.Person.Email != null &&
                                              m.Person.Email != "")))
                {
                    // Add the group
                    occurrences.Add(group.Id, new List <DateTime>());

                    // Check for a iCal schedule
                    DDay.iCal.Event calEvent = group.Schedule.GetCalenderEvent();
                    if (calEvent != null)
                    {
                        // If schedule has an iCal schedule, get occurrences between first and last dates
                        foreach (var occurrence in calEvent.GetOccurrences(startDate, endDate))
                        {
                            var startTime = occurrence.Period.StartTime.Value;
                            if (dates.Contains(startTime.Date))
                            {
                                occurrences[group.Id].Add(startTime);
                            }
                        }
                    }
                    else
                    {
                        // if schedule does not have an iCal, then check for weekly schedule and calculate occurrences starting with first attendance or current week
                        if (group.Schedule.WeeklyDayOfWeek.HasValue)
                        {
                            foreach (var date in dates)
                            {
                                if (date.DayOfWeek == group.Schedule.WeeklyDayOfWeek.Value)
                                {
                                    var startTime = date;
                                    if (group.Schedule.WeeklyTimeOfDay.HasValue)
                                    {
                                        startTime = startTime.Add(group.Schedule.WeeklyTimeOfDay.Value);
                                    }
                                    occurrences[group.Id].Add(startTime);
                                }
                            }
                        }
                    }
                }

                // Remove any occurrences during group type exclusion date ranges
                foreach (var exclusion in groupType.GroupScheduleExclusions)
                {
                    if (exclusion.Start.HasValue && exclusion.End.HasValue)
                    {
                        foreach (var keyVal in occurrences)
                        {
                            foreach (var occurrenceDate in keyVal.Value.ToList())
                            {
                                if (occurrenceDate >= exclusion.Start.Value &&
                                    occurrenceDate < exclusion.End.Value.AddDays(1))
                                {
                                    keyVal.Value.Remove(occurrenceDate);
                                }
                            }
                        }
                    }
                }

                // Remove any 'occurrenes' that already have attendance data entered
                foreach (var occurrence in attendanceService
                         .Queryable().AsNoTracking()
                         .Where(a =>
                                a.StartDateTime >= startDate &&
                                a.StartDateTime < endDate &&
                                occurrences.Keys.Contains(a.GroupId.Value) &&
                                a.ScheduleId.HasValue)
                         .Select(a => new
                {
                    GroupId = a.GroupId.Value,
                    a.StartDateTime
                })
                         .Distinct()
                         .ToList())
                {
                    occurrences[occurrence.GroupId].RemoveAll(d => d.Date == occurrence.StartDateTime.Date);
                }

                // Get the groups that have occurrences
                var groupIds = occurrences.Where(o => o.Value.Any()).Select(o => o.Key).ToList();

                // Get the leaders of those groups
                var leaders = groupMemberService
                              .Queryable("Group,Person").AsNoTracking()
                              .Where(m =>
                                     groupIds.Contains(m.GroupId) &&
                                     m.GroupMemberStatus == GroupMemberStatus.Active &&
                                     m.GroupRole.IsLeader &&
                                     m.Person.Email != null &&
                                     m.Person.Email != "")
                              .ToList();

                // Loop through the leaders
                foreach (var leader in leaders)
                {
                    foreach (var group in occurrences.Where(o => o.Key == leader.GroupId))
                    {
                        var mergeObjects = Rock.Lava.LavaHelper.GetCommonMergeFields(null, leader.Person);
                        mergeObjects.Add("Person", leader.Person);
                        mergeObjects.Add("Group", leader.Group);
                        mergeObjects.Add("Occurrence", group.Value.Max());

                        var recipients = new List <RecipientData>();
                        recipients.Add(new RecipientData(leader.Person.Email, mergeObjects));

                        Email.Send(dataMap.GetString("SystemEmail").AsGuid(), recipients);
                        attendanceRemindersSent++;
                    }
                }
            }

            context.Result = string.Format("{0} attendance reminders sent", attendanceRemindersSent);
        }
        /// <summary>
        /// Gets occurrence data for the selected group
        /// </summary>
        /// <param name="group">The group.</param>
        /// <param name="fromDateTime">From date time.</param>
        /// <param name="toDateTime">To date time.</param>
        /// <param name="locationIds">The location ids.</param>
        /// <param name="scheduleIds">The schedule ids.</param>
        /// <param name="loadSummaryData">if set to <c>true</c> [load summary data].</param>
        /// <param name="campusId">The campus identifier.</param>
        /// <returns></returns>
        public List <ScheduleOccurrence> GetGroupOccurrences(Group group, DateTime?fromDateTime, DateTime?toDateTime,
                                                             List <int> locationIds, List <int> scheduleIds, bool loadSummaryData, int?campusId)
        {
            var occurrences = new List <ScheduleOccurrence>();

            if (group != null)
            {
                var rockContext       = (RockContext)this.Context;
                var attendanceService = new AttendanceService(rockContext);
                var scheduleService   = new ScheduleService(rockContext);
                var locationService   = new LocationService(rockContext);

                using (new Rock.Data.QueryHintScope(rockContext, QueryHintType.RECOMPILE))
                {
                    // Set up an 'occurrences' query for the group
                    var qry = attendanceService
                              .Queryable().AsNoTracking()
                              .Where(a => a.GroupId == group.Id);

                    // Filter by date range
                    if (fromDateTime.HasValue)
                    {
                        var fromDate = fromDateTime.Value.Date;
                        qry = qry.Where(a => DbFunctions.TruncateTime(a.StartDateTime) >= (fromDate));
                    }
                    if (toDateTime.HasValue)
                    {
                        var toDate = toDateTime.Value.Date;
                        qry = qry.Where(a => DbFunctions.TruncateTime(a.StartDateTime) < (toDate));
                    }

                    // Location Filter
                    if (locationIds.Any())
                    {
                        qry = qry.Where(a => locationIds.Contains(a.LocationId ?? 0));
                    }

                    // Schedule Filter
                    if (scheduleIds.Any())
                    {
                        qry = qry.Where(a => scheduleIds.Contains(a.ScheduleId ?? 0));
                    }

                    // Get the unique combination of location/schedule/date for the selected group
                    var occurrenceDates = qry
                                          .Select(a => new
                    {
                        a.LocationId,
                        a.ScheduleId,
                        Date = DbFunctions.TruncateTime(a.StartDateTime)
                    })
                                          .Distinct()
                                          .ToList();

                    // Get the locations for each unique location id
                    var selectedlocationIds = occurrenceDates.Select(o => o.LocationId).Distinct().ToList();

                    var locations = locationService
                                    .Queryable().AsNoTracking()
                                    .Where(l => selectedlocationIds.Contains(l.Id))
                                    .Select(l => new { l.Id, l.ParentLocationId, l.Name })
                                    .ToList();
                    var locationNames = new Dictionary <int, string>();
                    locations.ForEach(l => locationNames.Add(l.Id, l.Name));

                    // Get the parent location path for each unique location
                    var parentlocationPaths = new Dictionary <int, string>();
                    locations
                    .Where(l => l.ParentLocationId.HasValue)
                    .Select(l => l.ParentLocationId.Value)
                    .Distinct()
                    .ToList()
                    .ForEach(l => parentlocationPaths.Add(l, locationService.GetPath(l)));
                    var locationPaths = new Dictionary <int, string>();
                    locations
                    .Where(l => l.ParentLocationId.HasValue)
                    .ToList()
                    .ForEach(l => locationPaths.Add(l.Id, parentlocationPaths[l.ParentLocationId.Value]));

                    // Get the schedules for each unique schedule id
                    var selectedScheduleIds = occurrenceDates.Select(o => o.ScheduleId).Distinct().ToList();
                    var schedules           = scheduleService
                                              .Queryable().AsNoTracking()
                                              .Where(s => selectedScheduleIds.Contains(s.Id))
                                              .ToList();
                    var scheduleNames      = new Dictionary <int, string>();
                    var scheduleStartTimes = new Dictionary <int, TimeSpan>();
                    schedules
                    .ForEach(s =>
                    {
                        scheduleNames.Add(s.Id, s.Name);
                        scheduleStartTimes.Add(s.Id, s.StartTimeOfDay);
                    });

                    foreach (var occurrence in occurrenceDates.Where(o => o.Date.HasValue))
                    {
                        occurrences.Add(
                            new ScheduleOccurrence(
                                occurrence.Date.Value,
                                occurrence.ScheduleId.HasValue && scheduleStartTimes.ContainsKey(occurrence.ScheduleId.Value) ?
                                scheduleStartTimes[occurrence.ScheduleId.Value] : new TimeSpan(),
                                occurrence.ScheduleId,
                                occurrence.ScheduleId.HasValue && scheduleNames.ContainsKey(occurrence.ScheduleId.Value) ?
                                scheduleNames[occurrence.ScheduleId.Value] : string.Empty,
                                occurrence.LocationId,
                                occurrence.LocationId.HasValue && locationNames.ContainsKey(occurrence.LocationId.Value) ?
                                locationNames[occurrence.LocationId.Value] : string.Empty,
                                occurrence.LocationId.HasValue && locationPaths.ContainsKey(occurrence.LocationId.Value) ?
                                locationPaths[occurrence.LocationId.Value] : string.Empty
                                ));
                    }
                }

                // Load the attendance data for each occurrence
                if (loadSummaryData && occurrences.Any())
                {
                    var minDate       = occurrences.Min(o => o.Date);
                    var maxDate       = occurrences.Max(o => o.Date).AddDays(1);
                    var attendanceQry = attendanceService
                                        .Queryable().AsNoTracking()
                                        .Where(a =>
                                               a.GroupId.HasValue &&
                                               a.GroupId == group.Id &&
                                               a.StartDateTime >= minDate &&
                                               a.StartDateTime < maxDate &&
                                               a.PersonAlias != null &&
                                               a.PersonAliasId.HasValue)
                                        .Select(a => new
                    {
                        a.LocationId,
                        a.ScheduleId,
                        a.StartDateTime,
                        a.DidAttend,
                        a.DidNotOccur,
                        a.PersonAliasId,
                        PersonId = a.PersonAlias.PersonId
                    });

                    if (campusId.HasValue)
                    {
                        var familyGroupType = GroupTypeCache.Read(Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuid());
                        var campusQry       = new GroupMemberService(rockContext)
                                              .Queryable()
                                              .Where(g =>
                                                     g.Group != null &&
                                                     g.Group.GroupTypeId == familyGroupType.Id &&
                                                     g.Group.CampusId.HasValue &&
                                                     g.Group.CampusId.Value == campusId.Value
                                                     )
                                              .Select(m => m.PersonId);

                        attendanceQry = attendanceQry
                                        .Where(s => campusQry.Contains(s.PersonId));
                    }

                    var attendances = attendanceQry.ToList();

                    foreach (var summary in attendances
                             .GroupBy(a => new
                    {
                        a.LocationId,
                        a.ScheduleId,
                        Date = a.StartDateTime.Date
                    })
                             .Select(a => new
                    {
                        a.Key.LocationId,
                        a.Key.ScheduleId,
                        a.Key.Date,
                        DidAttendCount = a
                                         .Where(t => t.DidAttend.HasValue && t.DidAttend.Value)
                                         .Select(t => t.PersonAliasId.Value)
                                         .Distinct()
                                         .Count(),
                        DidNotOccurCount = a
                                           .Where(t => t.DidNotOccur.HasValue && t.DidNotOccur.Value)
                                           .Select(t => t.PersonAliasId.Value)
                                           .Distinct()
                                           .Count(),
                        TotalCount = a
                                     .Select(t => t.PersonAliasId)
                                     .Distinct()
                                     .Count()
                    }))
                    {
                        var occurrence = occurrences
                                         .Where(o =>
                                                o.ScheduleId.Equals(summary.ScheduleId) &&
                                                o.LocationId.Equals(summary.LocationId) &&
                                                o.Date.Equals(summary.Date))
                                         .FirstOrDefault();
                        if (occurrence != null)
                        {
                            occurrence.DidAttendCount   = summary.DidAttendCount;
                            occurrence.DidNotOccurCount = summary.DidNotOccurCount;
                            occurrence.TotalCount       = summary.TotalCount;
                        }
                    }
                }

                // Create any missing occurrences from the group's schedule (not location schedules)
                Schedule groupSchedule = null;
                if (group.ScheduleId.HasValue)
                {
                    groupSchedule = group.Schedule;
                    if (groupSchedule == null)
                    {
                        groupSchedule = new ScheduleService(rockContext).Get(group.ScheduleId.Value);
                    }
                }

                if (groupSchedule != null)
                {
                    var newOccurrences = new List <ScheduleOccurrence>();

                    var existingDates = occurrences
                                        .Where(o => o.ScheduleId.Equals(groupSchedule.Id))
                                        .Select(o => o.Date)
                                        .Distinct()
                                        .ToList();

                    var startDate = fromDateTime.HasValue ? fromDateTime.Value : RockDateTime.Today.AddMonths(-2);
                    var endDate   = toDateTime.HasValue ? toDateTime.Value : RockDateTime.Today.AddDays(1);

                    DDay.iCal.Event calEvent = groupSchedule.GetCalenderEvent();
                    if (calEvent != null)
                    {
                        // If schedule has an iCal schedule, get all the past occurrences
                        foreach (var occurrence in calEvent.GetOccurrences(startDate, endDate))
                        {
                            var scheduleOccurrence = new ScheduleOccurrence(
                                occurrence.Period.StartTime.Date, occurrence.Period.StartTime.TimeOfDay, groupSchedule.Id, groupSchedule.Name);
                            if (!existingDates.Contains(scheduleOccurrence.Date))
                            {
                                newOccurrences.Add(scheduleOccurrence);
                            }
                        }
                    }
                    else
                    {
                        // if schedule does not have an iCal, then check for weekly schedule and calculate occurrences starting with first attendance or current week
                        if (groupSchedule.WeeklyDayOfWeek.HasValue)
                        {
                            // default to start with date 2 months earlier
                            startDate = fromDateTime.HasValue ? fromDateTime.Value : RockDateTime.Today.AddMonths(-2);
                            if (existingDates.Any(d => d < startDate))
                            {
                                startDate = existingDates.Min();
                            }

                            // Back up start time to the correct day of week
                            while (startDate.DayOfWeek != groupSchedule.WeeklyDayOfWeek.Value)
                            {
                                startDate = startDate.AddDays(-1);
                            }

                            // Add the start time
                            if (groupSchedule.WeeklyTimeOfDay.HasValue)
                            {
                                startDate = startDate.Add(groupSchedule.WeeklyTimeOfDay.Value);
                            }

                            // Create occurrences up to current time
                            while (startDate < endDate)
                            {
                                if (!existingDates.Contains(startDate.Date))
                                {
                                    var scheduleOccurrence = new ScheduleOccurrence(startDate.Date, startDate.TimeOfDay, groupSchedule.Id, groupSchedule.Name);
                                    newOccurrences.Add(scheduleOccurrence);
                                }

                                startDate = startDate.AddDays(7);
                            }
                        }
                    }

                    if (newOccurrences.Any())
                    {
                        // Filter Exclusions
                        var groupType = GroupTypeCache.Read(group.GroupTypeId);
                        foreach (var exclusion in groupType.GroupScheduleExclusions)
                        {
                            if (exclusion.Start.HasValue && exclusion.End.HasValue)
                            {
                                foreach (var occurrence in newOccurrences.ToList())
                                {
                                    if (occurrence.Date >= exclusion.Start.Value &&
                                        occurrence.Date < exclusion.End.Value.AddDays(1))
                                    {
                                        newOccurrences.Remove(occurrence);
                                    }
                                }
                            }
                        }
                    }

                    foreach (var occurrence in newOccurrences)
                    {
                        occurrences.Add(occurrence);
                    }
                }
            }

            return(occurrences);
        }
Esempio n. 12
0
        public string RenderIcs(ZonelessEventStore eventstore, string view, int count, DateTime from, DateTime to, Dictionary<string,object> args)
        {
            eventstore = GetEventStore(eventstore, view, count, from, to);
            var ical = new DDay.iCal.iCalendar();
            Collector.AddTimezoneToDDayICal(ical, this.calinfo.tzinfo);
            var tzid = this.calinfo.tzinfo.Id;

            foreach (var evt in eventstore.events)
            {
                var ical_evt = new DDay.iCal.Event();
                ical_evt.Start = new DDay.iCal.iCalDateTime(evt.dtstart);
                ical_evt.Start.TZID = tzid;
                ical_evt.End = new DDay.iCal.iCalDateTime(evt.dtend);
                ical_evt.End.TZID = tzid;
                ical_evt.Summary = evt.title;
                ical_evt.Url = new Uri(evt.url);

                if (evt.description != null)
                    ical_evt.Description = evt.description + " " + evt.url;
                else
                    ical_evt.Description = evt.url;

                ical_evt.Description = evt.description;
                ical_evt.Location = evt.location;
                Collector.AddCategoriesFromCatString(ical_evt, evt.categories);
                ical.Children.Add(ical_evt);
            }

            var ics_text = Utils.SerializeIcalToIcs(ical);

            return ics_text;
        }
Esempio n. 13
0
 // in support of add-to-calendar
 public static string RenderEventAsIcs(string elmcity_id, string summary, string start, string end, string description, string location, string url)
 {
     try
     {
         var calinfo = Utils.AcquireCalinfo(elmcity_id);
         var tzname = calinfo.tzname;
         var tzid = calinfo.tzinfo.Id;
         var ical = new DDay.iCal.iCalendar();
         Collector.AddTimezoneToDDayICal(ical, Utils.TzinfoFromName(tzname));
         var evt = new DDay.iCal.Event();
         evt.Summary = summary;
         evt.Description = Utils.MakeAddToCalDescription(description, url, location);
         evt.Location = location;
         evt.Url = new Uri(url);
         var dtstart = DateTime.Parse(start);
         evt.Start = new DDay.iCal.iCalDateTime(dtstart, tzname);
         evt.Start.TZID = tzid;
         if (evt.End != null)
         {
             var dtend = DateTime.Parse(end);
             evt.End = new DDay.iCal.iCalDateTime(dtend, tzname);
             evt.End.TZID = tzid;
         }
         ical.Events.Add(evt);
         var serializer = new DDay.iCal.Serialization.iCalendar.iCalendarSerializer();
         return serializer.SerializeToString(ical);
     }
     catch (Exception e)
     {
         GenUtils.PriorityLogMsg("exception", "RenderEventAsIcs", e.Message);
         return "exception: " + e.Message;
     }
 }
Esempio n. 14
0
        public static DDay.iCal.Event SyncICalEvent(
            ESpace.Occurrence eSpaceOccurrence,
            Schedule rockSchedule,
            out bool changed
            )
        {
            changed = false;

            var iCalEvent = rockSchedule.GetCalendarEvent();

            if (iCalEvent == null)
            {
                iCalEvent = new DDay.iCal.Event();
                changed   = true;
            }

            // Check for any recurrence dates
            if (iCalEvent.RecurrenceDates.Any())
            {
                iCalEvent.RecurrenceDates = null;
                changed = true;
            }

            // Check for any exception dates
            if (iCalEvent.ExceptionDates.Any())
            {
                iCalEvent.ExceptionDates = null;
                changed = true;
            }

            // Check for any recurrence rules
            if (iCalEvent.RecurrenceRules.Any())
            {
                iCalEvent.RecurrenceRules = null;
                changed = true;
            }

            // Check for any exception rules
            if (iCalEvent.ExceptionRules.Any())
            {
                iCalEvent.ExceptionRules = null;
                changed = true;
            }

            // Update the start date
            if (eSpaceOccurrence.EventStart.HasValue)
            {
                var startICalDate = new DDay.iCal.iCalDateTime(eSpaceOccurrence.EventStart.Value);
                if (iCalEvent.Start != startICalDate)
                {
                    iCalEvent.Start = startICalDate;
                    changed         = true;
                }
            }

            // Update the end date
            if (eSpaceOccurrence.EventEnd.HasValue)
            {
                var endICalDate = new DDay.iCal.iCalDateTime(eSpaceOccurrence.EventEnd.Value);
                if (iCalEvent.End != endICalDate)
                {
                    iCalEvent.End = endICalDate;
                    changed       = true;
                }
            }

            // Update IsAllDay
            var isAllDay = eSpaceOccurrence.IsAllDay ?? false;

            if (iCalEvent.IsAllDay != isAllDay)
            {
                iCalEvent.IsAllDay = isAllDay;
                changed            = true;
            }

            return(iCalEvent);
        }
        /// <summary>
        /// Gets occurrence data for the selected group
        /// </summary>
        /// <param name="group">The group.</param>
        /// <param name="loadAttendanceData">if set to <c>true</c> [load attendance data].</param>
        /// <returns></returns>
        public List <ScheduleOccurrence> GetGroupOccurrences(Group group, bool loadAttendanceData = true)
        {
            var occurrences = new List <ScheduleOccurrence>();

            if (group != null)
            {
                var rockContext = (RockContext)this.Context;

                var attendanceService = new AttendanceService(rockContext);

                var uniqueStartDates = attendanceService
                                       .Queryable().AsNoTracking()
                                       .Where(a => a.GroupId == group.Id)
                                       .Select(a => a.StartDateTime)
                                       .Distinct()
                                       .ToList()
                                       .Select(dt => dt.Date)
                                       .Distinct()
                                       .ToList();

                Schedule schedule = null;
                if (group.ScheduleId.HasValue)
                {
                    schedule = group.Schedule;
                    if (schedule == null)
                    {
                        schedule = new ScheduleService(rockContext).Get(group.ScheduleId.Value);
                    }
                }

                if (schedule != null)
                {
                    var endDate = RockDateTime.Today.AddDays(1);

                    DDay.iCal.Event calEvent = schedule.GetCalenderEvent();
                    if (calEvent != null)
                    {
                        // If schedule has an iCal schedule, get all the past occurrences
                        foreach (var occurrence in calEvent.GetOccurrences(DateTime.MinValue, endDate))
                        {
                            occurrences.Add(new ScheduleOccurrence(occurrence, schedule.Id));
                        }
                    }
                    else
                    {
                        // if schedule does not have an iCal, then check for weekly schedule and calculate occurrences starting with first attendance or current week
                        if (schedule.WeeklyDayOfWeek.HasValue)
                        {
                            // default to start with date 2 months earlier
                            DateTime startDateTime = RockDateTime.Today.AddMonths(-2);
                            if (uniqueStartDates.Any(d => d < startDateTime))
                            {
                                startDateTime = uniqueStartDates.Min();
                            }

                            // Back up start time to the correct day of week
                            while (startDateTime.DayOfWeek != schedule.WeeklyDayOfWeek.Value)
                            {
                                startDateTime = startDateTime.AddDays(-1);
                            }

                            // Add the start time
                            if (schedule.WeeklyTimeOfDay.HasValue)
                            {
                                startDateTime = startDateTime.Add(schedule.WeeklyTimeOfDay.Value);
                            }

                            // Create occurrences up to current time
                            while (startDateTime < endDate)
                            {
                                occurrences.Add(new ScheduleOccurrence(startDateTime, startDateTime.AddDays(1), schedule.Id));
                                startDateTime = startDateTime.AddDays(7);
                            }
                        }
                    }
                }

                // Add occurrences for any attendance dates that do not fall into a logical occurrence based on the schedule
                var occurrenceDates = occurrences.Select(o => o.StartDateTime.Date).ToList();
                foreach (var date in uniqueStartDates.Where(d => !occurrenceDates.Contains(d)))
                {
                    occurrences.Add(new ScheduleOccurrence(date, date.AddDays(1)));
                }

                if (occurrences.Any())
                {
                    // Filter Exclusions
                    var groupType = GroupTypeCache.Read(group.GroupTypeId);
                    foreach (var exclusion in groupType.GroupScheduleExclusions)
                    {
                        if (exclusion.Start.HasValue && exclusion.End.HasValue)
                        {
                            foreach (var occurrence in occurrences.ToList())
                            {
                                if (occurrence.StartDateTime >= exclusion.Start.Value &&
                                    occurrence.StartDateTime < exclusion.End.Value.AddDays(1))
                                {
                                    occurrences.Remove(occurrence);
                                }
                            }
                        }
                    }


                    if (loadAttendanceData)
                    {
                        var minStartValue = occurrences.Min(o => o.StartDateTime);
                        var maxEndValue   = occurrences.Max(o => o.EndDateTime);

                        var attendanceQry = attendanceService
                                            .Queryable("PersonAlias").AsNoTracking()
                                            .Where(a =>
                                                   a.GroupId == group.Id &&
                                                   a.StartDateTime >= minStartValue &&
                                                   a.StartDateTime < maxEndValue);

                        var attendanceData = attendanceQry.ToList();

                        foreach (var occurrence in occurrences)
                        {
                            occurrence.Attendance = attendanceData
                                                    .Where(a =>
                                                           a.StartDateTime >= occurrence.StartDateTime &&
                                                           a.StartDateTime < occurrence.EndDateTime)
                                                    .ToList();
                        }
                    }
                }
            }

            return(occurrences);
        }