Ejemplo n.º 1
0
        /// <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();
        }
Ejemplo n.º 2
0
        /// <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);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Gets the attendees.
        /// </summary>
        private IList <RosterAttendee> GetAttendees(RockContext rockContext)
        {
            var         startDateTime = RockDateTime.Today;
            CampusCache campusCache   = CampusCache.Get(CurrentCampusId);
            DateTime    currentDateTime;

            if (campusCache != null)
            {
                currentDateTime = campusCache.CurrentDateTime;
            }
            else
            {
                currentDateTime = RockDateTime.Now;
            }

            // Get all Attendance records for the current day
            var attendanceQuery = new AttendanceService(rockContext)
                                  .Queryable()
                                  .Include(a => a.AttendanceCode)
                                  .Include(a => a.PersonAlias.Person)
                                  .Include(a => a.Occurrence.Schedule)
                                  .Include(a => a.Occurrence.Group)
                                  .Include(a => a.Occurrence.Location)
                                  .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);

            attendanceQuery = attendanceQuery.Where(a => a.DidAttend == true);

            // Do the person search
            var        personService = new PersonService(rockContext);
            List <int> personIds     = null;

            // ignore the result of reversed (LastName, FirstName vs FirstName LastName
            bool reversed = false;

            string searchValue = tbSearch.Text.Trim();

            if (searchValue.IsNullOrWhiteSpace())
            {
                personIds = new List <int>();
            }
            else
            {
                // If searching by code is enabled, first search by the code
                if (GetAttributeValue(AttributeKey.SearchByCode).AsBoolean())
                {
                    var dayStart = RockDateTime.Today;
                    personIds = new AttendanceService(rockContext)
                                .Queryable().Where(a =>
                                                   a.StartDateTime >= dayStart &&
                                                   a.StartDateTime <= currentDateTime &&
                                                   a.AttendanceCode.Code == searchValue)
                                .Select(a => a.PersonAlias.PersonId)
                                .Distinct().ToList();
                }

                if (personIds == null || !personIds.Any())
                {
                    // If searching by code was disabled or nobody was found with code, search by name
                    personIds = personService
                                .GetByFullName(searchValue, false, false, false, out reversed)
                                .AsNoTracking()
                                .Select(a => a.Id)
                                .ToList();
                }
            }

            IList <RosterAttendee> attendees;

            if (personIds.Any())
            {
                // Get *all* of today's transactions.
                // Not sure why we aren't filtering by PersonIds yet, but
                // it could be to make performance more consistent in case the PersonQuery is complex.
                var attendanceQueryList = RosterAttendeeAttendance.Select(attendanceQuery).ToList();

                // join (in memory) matching person ids and attendances
                var peopleAttendances = personIds
                                        .GroupJoin(
                    attendanceQueryList,
                    pId => pId,
                    a => a.PersonId,
                    (p, a) => a)
                                        .SelectMany(a => a)
                                        .Distinct()
                                        .ToList();

                attendees = RosterAttendee.GetFromAttendanceList(peopleAttendances);
            }
            else
            {
                // no matching persons, so return empty list
                attendees = new List <RosterAttendee>();
            }

            return(attendees);
        }