Exemple #1
0
        /// <summary>
        /// Shows the configuration dialog.
        /// </summary>
        private void ShowConfigurationDialog()
        {
            // even though it'll be in the background, show the roster (so it doesn't look like it disappeared)
            // also, since there will be postbacks, let's enable viewstate when the configuration dialog is showing
            PopulateRoster(ViewStateMode.Enabled);

            // don't do the live refresh when the configuration dialog is showing
            UpdateLiveRefreshConfiguration(false);

            RosterConfiguration rosterConfiguration = this.GetBlockUserPreference(UserPreferenceKey.RosterConfigurationJSON)
                                                      .FromJsonOrNull <RosterConfiguration>();

            if (rosterConfiguration == null)
            {
                rosterConfiguration = new RosterConfiguration();
            }

            gpGroups.SetValues(rosterConfiguration.PickedGroupIds ?? new int[0]);
            cbIncludeChildGroups.Checked = rosterConfiguration.IncludeChildGroups;
            UpdateIncludeChildGroupsVisibility();

            UpdateScheduleList();
            lbSchedules.SetValues(rosterConfiguration.ScheduleIds ?? new int[0]);

            UpdateLocationListFromSelectedSchedules();
            cblLocations.SetValues(rosterConfiguration.LocationIds ?? new int[0]);

            cbDisplayRole.Checked = rosterConfiguration.DisplayRole;

            mdRosterConfiguration.Show();
        }
Exemple #2
0
        /// <summary>
        /// Updates the configuration from URL.
        /// </summary>
        private void UpdateConfigurationFromUrl()
        {
            /* 2020-07-21 MDP
             * If PageParameters are used, we use the same behavior as the various Analytics blocks  which is
             * - Set UserPrefs from URL when first loaded, then Edit/Use/Save UserPrefs like usual
             */
            RosterConfiguration rosterConfiguration = this.GetBlockUserPreference(UserPreferenceKey.RosterConfigurationJSON)
                                                      .FromJsonOrNull <RosterConfiguration>() ?? new RosterConfiguration();

            if (this.PageParameter(PageParameterKey.GroupIds).IsNotNullOrWhiteSpace())
            {
                // if GroupIds is a page parameter, set GroupIds and IncludeChildGroups from the URL
                rosterConfiguration.PickedGroupIds = this.PageParameter(PageParameterKey.GroupIds).Split(',').AsIntegerList().ToArray();
            }

            if (this.PageParameter(PageParameterKey.IncludeChildGroups).IsNotNullOrWhiteSpace())
            {
                rosterConfiguration.IncludeChildGroups = this.PageParameter(PageParameterKey.IncludeChildGroups).AsBoolean();
            }

            if (this.PageParameter(PageParameterKey.LocationIds).IsNotNullOrWhiteSpace())
            {
                // if LocationIds is a page parameter, use that as the LocationIds
                rosterConfiguration.LocationIds = this.PageParameter(PageParameterKey.LocationIds).Split(',').AsIntegerList().ToArray();
            }

            if (this.PageParameter(PageParameterKey.ScheduleIds).IsNotNullOrWhiteSpace())
            {
                // if ScheduleIds is a page parameter, use that as the ScheduleIds
                rosterConfiguration.ScheduleIds = this.PageParameter(PageParameterKey.ScheduleIds).Split(',').AsIntegerList().ToArray();
            }

            // just in case URL updated any configuration, save it back to user preferences
            this.SetBlockUserPreference(UserPreferenceKey.RosterConfigurationJSON, rosterConfiguration.ToJson());
        }
Exemple #3
0
        /// <summary>
        /// Raises the <see cref="E:System.Web.UI.Control.Load" /> event.
        /// </summary>
        /// <param name="e">The <see cref="T:System.EventArgs" /> object that contains the event data.</param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            RockPage.AddCSSLink("~/Themes/Rock/Styles/group-scheduler.css", true);

            if (!this.IsPostBack)
            {
                UpdateConfigurationFromUrl();
                UpdateLiveRefreshConfiguration(this.GetAttributeValue(AttributeKey.EnableLiveRefresh).AsBoolean());

                RosterConfiguration rosterConfiguration = this.GetBlockUserPreference(UserPreferenceKey.RosterConfigurationJSON)
                                                          .FromJsonOrNull <RosterConfiguration>() ?? new RosterConfiguration();

                if (!rosterConfiguration.IsConfigured())
                {
                    ShowConfigurationDialog();
                }
                else
                {
                    PopulateRoster();
                }
            }
            else
            {
                HandleCustomPostbackEvents();
            }
        }
Exemple #4
0
        /// <summary>
        /// Handles the SaveClick event of the mdRosterConfiguration control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        protected void mdRosterConfiguration_SaveClick(object sender, EventArgs e)
        {
            RosterConfiguration rosterConfiguration = this.GetBlockUserPreference(UserPreferenceKey.RosterConfigurationJSON)
                                                      .FromJsonOrNull <RosterConfiguration>();

            if (rosterConfiguration == null)
            {
                rosterConfiguration = new RosterConfiguration();
            }

            rosterConfiguration.PickedGroupIds     = gpGroups.SelectedValuesAsInt().ToArray();
            rosterConfiguration.IncludeChildGroups = cbIncludeChildGroups.Checked;
            rosterConfiguration.LocationIds        = cblLocations.SelectedValuesAsInt.ToArray();
            rosterConfiguration.ScheduleIds        = lbSchedules.SelectedValuesAsInt.ToArray();
            rosterConfiguration.DisplayRole        = cbDisplayRole.Checked;

            this.SetBlockUserPreference(UserPreferenceKey.RosterConfigurationJSON, rosterConfiguration.ToJson());
            mdRosterConfiguration.Hide();

            UpdateLiveRefreshConfiguration(this.GetAttributeValue(AttributeKey.EnableLiveRefresh).AsBoolean());
            PopulateRoster();
        }
Exemple #5
0
        /// <summary>
        /// Populates the roster.
        /// In cases where there won't be a postback, we can disable view state. The only time we need viewstate is when the Configuration Dialog
        /// is showing.
        /// </summary>
        private void PopulateRoster(ViewStateMode viewStateMode = ViewStateMode.Disabled)
        {
            RosterConfiguration rosterConfiguration = this.GetBlockUserPreference(UserPreferenceKey.RosterConfigurationJSON)
                                                      .FromJsonOrNull <RosterConfiguration>() ?? new RosterConfiguration();

            if (!rosterConfiguration.IsConfigured())
            {
                return;
            }

            int[]      scheduleIds    = rosterConfiguration.ScheduleIds;
            int[]      locationIds    = rosterConfiguration.LocationIds;
            List <int> pickedGroupIds = rosterConfiguration.PickedGroupIds.ToList();

            var allGroupIds = new List <int>();

            allGroupIds.AddRange(pickedGroupIds);

            var rockContext = new RockContext();

            // Only use teh ShowChildGroups option when there is 1 group selected
            if (rosterConfiguration.IncludeChildGroups && pickedGroupIds.Count == 1)
            {
                // if there is exactly one groupId we can avoid a 'Contains' (Contains has a small performance impact)
                var parentGroupId = pickedGroupIds[0];
                var groupService  = new GroupService(rockContext);

                // just the first level of child groups, not all decendants
                var childGroupIds = groupService.Queryable().Where(a => a.ParentGroupId == parentGroupId).Select(a => a.Id).ToList();
                allGroupIds.AddRange(childGroupIds);
            }

            allGroupIds = allGroupIds.Distinct().ToList();

            var attendanceOccurrenceService = new AttendanceOccurrenceService(rockContext);

            // An OccurrenceDate probably won't be included in the URL, but just in case
            DateTime?occurrenceDate = this.PageParameter(PageParameterKey.OccurrenceDate).AsDateTime();

            if (!occurrenceDate.HasValue)
            {
                occurrenceDate = RockDateTime.Today;
            }

            // only show occurrences for the current day
            var attendanceOccurrenceQuery = attendanceOccurrenceService
                                            .Queryable()
                                            .Where(a => a.ScheduleId.HasValue && a.LocationId.HasValue && a.GroupId.HasValue)
                                            .WhereDeducedIsActive()
                                            .Where(a =>
                                                   allGroupIds.Contains(a.GroupId.Value) &&
                                                   a.OccurrenceDate == occurrenceDate &&
                                                   scheduleIds.Contains(a.ScheduleId.Value));

            // if specific locations are specified, use those, otherwise just show all
            if (locationIds.Any())
            {
                attendanceOccurrenceQuery = attendanceOccurrenceQuery.Where(a => locationIds.Contains(a.LocationId.Value));
            }

            // limit attendees to ones that schedules (or are checked-in regardless of being scheduled)
            var confirmedAttendancesForOccurrenceQuery = attendanceOccurrenceQuery
                                                         .SelectMany(a => a.Attendees)
                                                         .Include(a => a.PersonAlias.Person)
                                                         .Include(a => a.Occurrence.Group.Members)
                                                         .WhereScheduledOrCheckedIn();

            var confirmedScheduledIndividualsForOccurrenceId = confirmedAttendancesForOccurrenceQuery
                                                               .AsNoTracking()
                                                               .ToList()
                                                               .GroupBy(a => a.OccurrenceId)
                                                               .ToDictionary(
                k => k.Key,
                v => v.Select(a => new ScheduledIndividual
            {
                ScheduledAttendanceItemStatus = Attendance.GetScheduledAttendanceItemStatus(a.RSVP, a.ScheduledToAttend),
                Person             = a.PersonAlias.Person,
                GroupMember        = a.Occurrence.Group.Members.FirstOrDefault(gm => gm.PersonId == a.PersonAlias.PersonId),
                CurrentlyCheckedIn = a.DidAttend == true
            })
                .ToList());

            List <AttendanceOccurrence> attendanceOccurrenceList = attendanceOccurrenceQuery
                                                                   .Include(a => a.Schedule)
                                                                   .Include(a => a.Attendees)
                                                                   .Include(a => a.Group)
                                                                   .Include(a => a.Location)
                                                                   .AsNoTracking()
                                                                   .ToList()
                                                                   .OrderBy(a => a.OccurrenceDate)
                                                                   .ThenBy(a => a.Schedule.Order)
                                                                   .ThenBy(a => a.Schedule.GetNextStartDateTime(a.OccurrenceDate))
                                                                   .ThenBy(a => a.Location.Name)
                                                                   .ToList();

            var occurrenceRosterInfoList = new List <OccurrenceRosterInfo>();

            foreach (var attendanceOccurrence in attendanceOccurrenceList)
            {
                var scheduleDate         = attendanceOccurrence.Schedule.GetNextStartDateTime(attendanceOccurrence.OccurrenceDate);
                var scheduledIndividuals = confirmedScheduledIndividualsForOccurrenceId.GetValueOrNull(attendanceOccurrence.Id);

                if ((scheduleDate == null) || (scheduleDate.Value.Date != attendanceOccurrence.OccurrenceDate))
                {
                    // scheduleDate can be later than the OccurrenceDate (or null) if there are exclusions that cause the schedule
                    // to not occur on the occurrence date. In this case, don't show the roster unless there are somehow individuals
                    // scheduled for this occurrence.
                    if (scheduledIndividuals == null || !scheduledIndividuals.Any())
                    {
                        // no scheduleDate and no scheduled individuals, so continue on to the next attendanceOccurrence
                        continue;
                    }
                }

                var occurrenceRosterInfo = new OccurrenceRosterInfo
                {
                    Group                = attendanceOccurrence.Group,
                    Location             = attendanceOccurrence.Location,
                    Schedule             = attendanceOccurrence.Schedule,
                    ScheduleDate         = scheduleDate,
                    ScheduledIndividuals = scheduledIndividuals
                };

                occurrenceRosterInfoList.Add(occurrenceRosterInfo);
            }

            var mergeFields = LavaHelper.GetCommonMergeFields(this.RockPage);

            mergeFields.Add("OccurrenceList", occurrenceRosterInfoList);
            mergeFields.Add("DisplayRole", rosterConfiguration.DisplayRole);
            mergeFields.Add("OccurrenceDate", occurrenceDate);
            var rosterLavaTemplate = this.GetAttributeValue(AttributeKey.RosterLavaTemplate);

            var rosterHtml = rosterLavaTemplate.ResolveMergeFields(mergeFields);

            // by default, let's disable viewstate (except for when the configuration dialog is showing)
            lOccurrenceRosterHTML.ViewStateMode = viewStateMode;
            lOccurrenceRosterHTML.Text          = rosterHtml;
        }