/// <summary> /// Determines if the Filter /// </summary> /// <returns></returns> private bool HasFilterErrors() { CampusCache campus = GetCampusFromContext(); if (campus == null) { nbWarning.Text = "Please select a Campus."; nbWarning.NotificationBoxType = NotificationBoxType.Warning; nbWarning.Visible = true; return(true); } if (!campus.LocationId.HasValue) { nbWarning.Text = "This campus does not have any locations."; nbWarning.NotificationBoxType = NotificationBoxType.Warning; nbWarning.Visible = true; return(true); } // If ShowAllAreas is false, the CheckinAreaFilter is required. if (this.GetAttributeValue(AttributeKey.ShowAllAreas).AsBoolean() == false) { var checkinAreaFilter = CheckinManagerHelper.GetCheckinAreaFilter(this); if (checkinAreaFilter == null) { if (NavigateToLinkedPage(AttributeKey.AreaSelectPage)) { // We are navigating to get the Area Filter which will get the Area cookie. return(true); } else { nbWarning.Text = "The 'Area Select Page' Block Attribute must be defined."; nbWarning.NotificationBoxType = NotificationBoxType.Warning; nbWarning.Visible = true; return(true); } } } return(false); }
/// <summary> /// Gets the attendees. /// </summary> private IList <RosterAttendee> GetAttendees(RockContext rockContext) { var startDateTime = RockDateTime.Today; CampusCache campusCache = GetCampusFromContext(); DateTime currentDateTime; if (campusCache != null) { currentDateTime = campusCache.CurrentDateTime; } else { currentDateTime = RockDateTime.Now; } // Get all Attendance records for the current day and location var attendanceQuery = new AttendanceService(rockContext).Queryable().Where(a => a.StartDateTime >= startDateTime && a.DidAttend == true && a.StartDateTime <= currentDateTime && a.PersonAliasId.HasValue && a.Occurrence.GroupId.HasValue && a.Occurrence.ScheduleId.HasValue && a.Occurrence.LocationId.HasValue && a.Occurrence.ScheduleId.HasValue); if (campusCache != null) { // limit locations (rooms) to locations within the selected campus var campusLocationIds = new LocationService(rockContext).GetAllDescendentIds(campusCache.LocationId.Value).ToList(); attendanceQuery = attendanceQuery.Where(a => campusLocationIds.Contains(a.Occurrence.LocationId.Value)); } var selectedScheduleIds = lbSchedules.SelectedValues.AsIntegerList().Where(a => a > 0).ToList(); var selectedGroupIds = GetSelectedGroupIds(); if (selectedScheduleIds.Any()) { attendanceQuery = attendanceQuery.Where(a => selectedScheduleIds.Contains(a.Occurrence.ScheduleId.Value)); } if (selectedGroupIds.Any()) { if (cbIncludeChildGroups.Checked) { var groupService = new GroupService(rockContext); foreach (var groupId in selectedGroupIds.ToList()) { var childGroupIds = groupService.GetAllDescendentGroupIds(groupId, false); selectedGroupIds.AddRange(childGroupIds); } } attendanceQuery = attendanceQuery.Where(a => selectedGroupIds.Contains(a.Occurrence.GroupId.Value)); } else { var checkinAreaFilter = CheckinManagerHelper.GetCheckinAreaFilter(this); if (checkinAreaFilter != null) { // if there is a checkin area filter, limit to groups within the selected check-in area var checkinAreaGroupTypeIds = new GroupTypeService(rockContext).GetCheckinAreaDescendants(checkinAreaFilter.Id).Select(a => a.Id).ToList(); selectedGroupIds = new GroupService(rockContext).Queryable().Where(a => checkinAreaGroupTypeIds.Contains(a.GroupTypeId)).Select(a => a.Id).ToList(); attendanceQuery = attendanceQuery.Where(a => selectedGroupIds.Contains(a.Occurrence.GroupId.Value)); } } RosterStatusFilter rosterStatusFilter = this.GetAttributeValue(AttributeKey.FilterBy).ConvertToEnumOrNull <RosterStatusFilter>() ?? RosterStatusFilter.CheckedIn; attendanceQuery = CheckinManagerHelper.FilterByRosterStatusFilter(attendanceQuery, rosterStatusFilter); var attendanceList = RosterAttendeeAttendance.Select(attendanceQuery).ToList(); attendanceList = CheckinManagerHelper.FilterByActiveCheckins(currentDateTime, attendanceList); attendanceList = attendanceList.Where(a => a.Person != null).ToList(); if (tbSearch.Text.IsNotNullOrWhiteSpace()) { // search by name var searchValue = tbSearch.Text; // ignore the result of reversed (LastName, FirstName vs FirstName LastName bool reversed; var personIds = new PersonService(rockContext) .GetByFullName(searchValue, false, false, false, out reversed) .AsNoTracking() .Select(a => a.Id) .ToList(); attendanceList = attendanceList.Where(a => personIds.Contains(a.PersonId)).ToList(); } var attendees = RosterAttendee.GetFromAttendanceList(attendanceList); return(attendees); }
/// <summary> /// Shows the filters. /// </summary> private void BindFilter() { ScheduleService scheduleService = new ScheduleService(new RockContext()); var customSettings = CheckinManagerHelper.GetCheckinManagerConfigurationFromCookie().CustomSettings; var scheduleIdsFilter = customSettings.GetValueOrNull(CustomSettingKey.EnRouteScheduleIdsFilter); var pickedGroupIdsFilter = customSettings.GetValueOrNull(CustomSettingKey.EnRoutePickedGroupIdsFilter); var includeChildGroupsFilter = customSettings.GetValueOrNull(CustomSettingKey.EnRouteIncludeChildGroupsFilter); var selectedScheduleIds = scheduleIdsFilter.SplitDelimitedValues().AsIntegerList(); // limit Schedules to ones that are Active, have a CheckInStartOffsetMinutes, and are Named schedules var scheduleQry = scheduleService.Queryable().Where(a => a.IsActive && a.CheckInStartOffsetMinutes != null && a.Name != null && a.Name != string.Empty); var scheduleList = scheduleQry.ToList().OrderBy(a => a.Name).ToList(); var sortedScheduleList = scheduleList.OrderByOrderAndNextScheduledDateTime(); lbSchedules.Items.Clear(); foreach (var schedule in sortedScheduleList) { var listItem = new ListItem(); if (schedule.Name.IsNotNullOrWhiteSpace()) { listItem.Text = schedule.Name; } else { listItem.Text = schedule.FriendlyScheduleText; } listItem.Value = schedule.Id.ToString(); listItem.Selected = selectedScheduleIds.Contains(schedule.Id); lbSchedules.Items.Add(listItem); } IEnumerable <CheckinAreaPath> checkinAreasPaths; var checkinAreaFilter = CheckinManagerHelper.GetCheckinAreaFilter(this); if (checkinAreaFilter != null) { checkinAreasPaths = new GroupTypeService(new RockContext()).GetCheckinAreaDescendantsPath(checkinAreaFilter.Id); } else { checkinAreasPaths = new GroupTypeService(new RockContext()).GetAllCheckinAreaPaths(); } var checkinGroupTypeIdsToShow = checkinAreasPaths.Select(a => a.GroupTypeId).Distinct().ToList(); gpGroups.IncludedGroupTypeIds = checkinGroupTypeIdsToShow; var selectedGroupIds = pickedGroupIdsFilter.SplitDelimitedValues().AsIntegerList(); gpGroups.SetValues(selectedGroupIds); if (GetAttributeValue(AttributeKey.AlwaysShowChildGroups).AsBoolean()) { cbIncludeChildGroups.Visible = false; lblIncludeChildGroups.Visible = true; cbIncludeChildGroups.Checked = true; } else { cbIncludeChildGroups.Visible = true; lblIncludeChildGroups.Visible = false; cbIncludeChildGroups.Checked = includeChildGroupsFilter.AsBoolean(); } }
/// <summary> /// Binds the grid. /// </summary> private void BindGrid() { if (HasFilterErrors()) { return; } var checkinAreaFilter = CheckinManagerHelper.GetCheckinAreaFilter(this); CampusCache campus = GetCampusFromContext(); var selectedScheduleIds = lbSchedules.SelectedValues.AsIntegerList(); if (selectedScheduleIds.Any()) { btnShowFilter.AddCssClass("criteria-exists bg-warning"); } else { btnShowFilter.RemoveCssClass("criteria-exists bg-warning"); } CheckinManagerHelper.SaveRoomListFilterToCookie(selectedScheduleIds.ToArray()); var rockContext = new RockContext(); var groupService = new GroupService(rockContext); var groupTypeService = new GroupTypeService(rockContext); IEnumerable <CheckinAreaPath> checkinAreaPaths; if (checkinAreaFilter != null) { checkinAreaPaths = groupTypeService.GetCheckinAreaDescendantsPath(checkinAreaFilter.Id); } else { checkinAreaPaths = groupTypeService.GetAllCheckinAreaPaths(); } var selectedGroupTypeIds = checkinAreaPaths.Select(a => a.GroupTypeId).Distinct().ToArray(); var groupLocationService = new GroupLocationService(rockContext); var groupLocationsQuery = groupLocationService.Queryable() .Where(gl => selectedGroupTypeIds.Contains(gl.Group.GroupTypeId) && gl.Group.IsActive && (!gl.Group.IsArchived)); var parentLocationIdParameter = PageParameter(PageParameterKey.ParentLocationId).AsIntegerOrNull(); var locationIdParameter = PageParameter(PageParameterKey.LocationId).AsIntegerOrNull(); var locationGridField = gRoomList.ColumnsOfType <RockLiteralField>().FirstOrDefault(a => a.ID == "lRoomName"); if (locationGridField != null && !locationGridField.Visible) { locationGridField.Visible = true; } List <int> locationIds; if (locationIdParameter.HasValue) { // If LocationId is specified in the URL, list only items for the specified location. // Also, hide the Location Grid Column and set the PanelTitle as the location's name // This will take precedence over the selected campus+locations and/or <seealso cref="ParentLocationId"/> var locationService = new LocationService(rockContext); lPanelTitle.Text = locationService.GetSelect(locationIdParameter.Value, s => s.Name); locationIds = new List <int>(); locationIds.Add(locationIdParameter.Value); if (locationGridField != null) { // since a LocationId parameter was specified, the LocationGrid field doesn't need to be shown locationGridField.Visible = false; } } else if (parentLocationIdParameter.HasValue) { // If parentLocationId is specified, show the direct (first level) child locations of the specified ParentLocationId. // This will take precedence over the selected campus+locations. var locationService = new LocationService(rockContext); locationIds = locationService.Queryable() .Where(a => a.ParentLocationId.HasValue && a.ParentLocationId.Value == parentLocationIdParameter.Value) .Select(a => a.Id).ToList(); lPanelTitle.Text = string.Format("{0} Child Locations", locationService.GetSelect(parentLocationIdParameter.Value, s => s.Name)); } else { // Limit locations (rooms) to locations within the selected campus. locationIds = new LocationService(rockContext).GetAllDescendentIds(campus.LocationId.Value).ToList(); locationIds.Add(campus.LocationId.Value, true); lPanelTitle.Text = "Room List"; } groupLocationsQuery = groupLocationsQuery.Where(a => locationIds.Contains(a.LocationId)); if (selectedScheduleIds.Any()) { groupLocationsQuery = groupLocationsQuery.Where(a => a.Schedules.Any(s => s.IsActive && s.CheckInStartOffsetMinutes.HasValue && selectedScheduleIds.Contains(s.Id))); } else { groupLocationsQuery = groupLocationsQuery.Where(a => a.Schedules.Any(s => s.IsActive && s.CheckInStartOffsetMinutes.HasValue)); } var groupLocationList = groupLocationsQuery.Select(a => new GroupLocationInfo { LocationId = a.LocationId, LocationName = a.Location.Name, ParentGroupId = a.Group.ParentGroupId, ParentGroupName = a.Group.ParentGroup.Name, GroupId = a.Group.Id, GroupName = a.Group.Name, GroupTypeId = a.Group.GroupTypeId }).ToList(); var startDateTime = RockDateTime.Today; DateTime currentDateTime; if (campus != null) { currentDateTime = campus.CurrentDateTime; } else { currentDateTime = RockDateTime.Now; } // Get all Attendance records for the current day and location. var attendanceQuery = new AttendanceService(rockContext).Queryable().Where(a => a.StartDateTime >= startDateTime && a.DidAttend == true && a.StartDateTime <= currentDateTime && a.PersonAliasId.HasValue && a.Occurrence.GroupId.HasValue && a.Occurrence.LocationId.HasValue && a.Occurrence.ScheduleId.HasValue); // Limit attendances (rooms) to the groupLocations' LocationId and GroupIds that we'll be showing var groupLocationLocationIds = groupLocationList.Select(a => a.LocationId).Distinct().ToList(); var groupLocationGroupsIds = groupLocationList.Select(a => a.GroupId).Distinct().ToList(); attendanceQuery = attendanceQuery.Where(a => groupLocationLocationIds.Contains(a.Occurrence.LocationId.Value) && groupLocationGroupsIds.Contains(a.Occurrence.GroupId.Value)); attendanceQuery = attendanceQuery.Where(a => selectedGroupTypeIds.Contains(a.Occurrence.Group.GroupTypeId)); if (selectedScheduleIds.Any()) { attendanceQuery = attendanceQuery.Where(a => selectedScheduleIds.Contains(a.Occurrence.ScheduleId.Value)); } var rosterAttendeeAttendanceList = RosterAttendeeAttendance.Select(attendanceQuery).ToList(); var groupTypeIdsWithAllowCheckout = selectedGroupTypeIds .Select(a => GroupTypeCache.Get(a)) .Where(a => a != null) .Where(gt => gt.GetCheckInConfigurationAttributeValue(Rock.SystemKey.GroupTypeAttributeKey.CHECKIN_GROUPTYPE_ALLOW_CHECKOUT).AsBoolean()) .Select(a => a.Id) .Distinct().ToList(); var groupTypeIdsWithEnablePresence = selectedGroupTypeIds .Select(a => GroupTypeCache.Get(a)) .Where(a => a != null) .Where(gt => gt.GetCheckInConfigurationAttributeValue(Rock.SystemKey.GroupTypeAttributeKey.CHECKIN_GROUPTYPE_ENABLE_PRESENCE).AsBoolean()) .Select(a => a.Id) .Distinct(); var scheduleIds = rosterAttendeeAttendanceList.Select(a => a.ScheduleId.Value).Distinct().ToList(); var scheduleList = new ScheduleService(rockContext).GetByIds(scheduleIds).ToList(); var scheduleIdsWasScheduleOrCheckInActiveForCheckOut = new HashSet <int>(scheduleList.Where(a => a.WasScheduleOrCheckInActiveForCheckOut(currentDateTime)).Select(a => a.Id).ToList()); rosterAttendeeAttendanceList = rosterAttendeeAttendanceList.Where(a => { var allowCheckout = groupTypeIdsWithAllowCheckout.Contains(a.GroupTypeId); if (!allowCheckout) { /* * If AllowCheckout is false, remove all Attendees whose schedules are not currently active. Per the 'WasSchedule...ActiveForCheckOut()' * method below: "Check-out can happen while check-in is active or until the event ends (start time + duration)." This will help to keep * the list of 'Present' attendees cleaned up and accurate, based on the room schedules, since the volunteers have no way to manually mark * an Attendee as 'Checked-out'. * * If, on the other hand, AllowCheckout is true, it will be the volunteers' responsibility to click the [Check-out] button when an * Attendee leaves the room, in order to keep the list of 'Present' Attendees in order. This will also allow the volunteers to continue * 'Checking-out' Attendees in the case that the parents are running late in picking them up. */ return(scheduleIdsWasScheduleOrCheckInActiveForCheckOut.Contains(a.ScheduleId.Value)); } else { return(true); } }).ToList(); var attendancesByLocationId = rosterAttendeeAttendanceList .GroupBy(a => a.LocationId.Value).ToDictionary(k => k.Key, v => v.ToList()); _attendancesByLocationIdAndGroupId = attendancesByLocationId.ToDictionary( k => k.Key, v => v.Value.GroupBy(x => x.GroupId.Value).ToDictionary(x => x.Key, xx => xx.ToList())); _checkinAreaPathsLookupByGroupTypeId = checkinAreaPaths.ToDictionary(k => k.GroupTypeId, v => v); _showOnlyParentGroup = this.GetAttributeValue(AttributeKey.ShowOnlyParentGroup).AsBoolean(); var roomList = new List <RoomInfo>(); foreach (var groupLocation in groupLocationList) { AddToRoomList(roomList, groupLocation); } List <RoomInfo> sortedRoomList; if (_showOnlyParentGroup) { sortedRoomList = roomList.OrderBy(a => a.LocationName).ToList(); } else { sortedRoomList = new List <RoomInfo>(); sortedRoomList.AddRange(roomList.OfType <RoomInfoByGroup>().OrderBy(a => a.LocationName).ThenBy(a => a.GroupName).ToList()); } var checkedInCountField = gRoomList.ColumnsOfType <RockLiteralField>().FirstOrDefault(a => a.ID == "lCheckedInCount"); var presentCountField = gRoomList.ColumnsOfType <RockLiteralField>().FirstOrDefault(a => a.ID == "lPresentCount"); var checkedOutCountField = gRoomList.ColumnsOfType <RockLiteralField>().FirstOrDefault(a => a.ID == "lCheckedOutCount"); checkedOutCountField.Visible = groupTypeIdsWithAllowCheckout.Any(); // Always show Present Count regardless of the 'Enable Presence' setting. (A person gets automatically marked present if 'Enable Presence' is disabled.) presentCountField.Visible = true; if (groupTypeIdsWithEnablePresence.Any()) { // Presence is enabled, so records could be in the 'Checked-in' state // and Present column should be labeled 'Present'. checkedInCountField.Visible = true; presentCountField.HeaderText = "Present"; } else { // https://app.asana.com/0/0/1199637795718017/f // 'Enable Presence' is disabled, so a person automatically gets marked present. // So, no records will be in the 'Checked-In (but no present)' state. // Also, a user thinks of 'Present' as 'Checked-In' if they don't use the 'Enable Presence' feature checkedInCountField.Visible = false; presentCountField.HeaderText = "Checked-In"; } if (_showOnlyParentGroup) { gRoomList.DataKeyNames = new string[1] { "LocationId" }; } else { gRoomList.DataKeyNames = new string[2] { "LocationId", "GroupId" }; } gRoomList.DataSource = sortedRoomList; gRoomList.DataBind(); }