Esempio n. 1
0
        /// <summary>
        /// Updates the group member requirement result.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="personId">The person identifier.</param>
        /// <param name="groupId">The group identifier.</param>
        /// <param name="meetsGroupRequirement">The meets group requirement.</param>
        public void UpdateGroupMemberRequirementResult(RockContext rockContext, int personId, int groupId, MeetsGroupRequirement meetsGroupRequirement)
        {
            GroupRequirement groupRequirement = this;
            var currentDateTime = RockDateTime.Now;
            GroupMemberRequirementService groupMemberRequirementService = new GroupMemberRequirementService(rockContext);
            var groupMemberService = new GroupMemberService(rockContext);
            var groupMemberQry     = groupMemberService.Queryable(true).Where(a => a.PersonId == personId && a.GroupId == groupId &&
                                                                              (
                                                                                  (groupRequirement.GroupId.HasValue && groupRequirement.GroupId == a.GroupId)
                                                                                  ||
                                                                                  (groupRequirement.GroupTypeId.HasValue && groupRequirement.GroupTypeId == a.Group.GroupTypeId)
                                                                              ));

            if (this.GroupRoleId != null)
            {
                groupMemberQry = groupMemberQry.Where(a => a.GroupRoleId == this.GroupRoleId);
            }

            foreach (var groupMemberId in groupMemberQry.Select(a => a.Id))
            {
                var groupMemberRequirement = groupMemberRequirementService.Queryable().Where(a => a.GroupMemberId == groupMemberId && a.GroupRequirementId == groupRequirement.Id).FirstOrDefault();
                if (groupMemberRequirement == null)
                {
                    groupMemberRequirement = new GroupMemberRequirement();
                    groupMemberRequirement.GroupMemberId      = groupMemberId;
                    groupMemberRequirement.GroupRequirementId = groupRequirement.Id;
                    groupMemberRequirementService.Add(groupMemberRequirement);
                }

                groupMemberRequirement.LastRequirementCheckDateTime = currentDateTime;

                if ((meetsGroupRequirement == MeetsGroupRequirement.Meets) || (meetsGroupRequirement == MeetsGroupRequirement.MeetsWithWarning))
                {
                    // they meet the requirement so update the Requirement Met Date/Time
                    groupMemberRequirement.RequirementMetDateTime  = currentDateTime;
                    groupMemberRequirement.RequirementFailDateTime = null;
                }
                else
                {
                    // they don't meet the requirement so set the Requirement Met Date/Time to null
                    groupMemberRequirement.RequirementMetDateTime  = null;
                    groupMemberRequirement.RequirementFailDateTime = currentDateTime;
                }

                if (meetsGroupRequirement == MeetsGroupRequirement.MeetsWithWarning)
                {
                    if (!groupMemberRequirement.RequirementWarningDateTime.HasValue)
                    {
                        // they have a warning for the requirement, and didn't have a warning already
                        groupMemberRequirement.RequirementWarningDateTime = currentDateTime;
                    }
                }
                else
                {
                    // no warning, so set to null
                    groupMemberRequirement.RequirementWarningDateTime = null;
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// If Group has GroupRequirements, will calculate and update the GroupMemberRequirements for the GroupMember, then save the changes to the database
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="saveChanges">if set to <c>true</c> [save changes].</param>
        public void CalculateRequirements(RockContext rockContext, bool saveChanges = true)
        {
            // recalculate and store in the database if the groupmember isn't new or changed
            var groupMemberRequirementsService = new GroupMemberRequirementService(rockContext);
            var group = this.Group ?? new GroupService(rockContext).Queryable("GroupRequirements").FirstOrDefault(a => a.Id == this.GroupId);

            if (!group.GetGroupRequirements(rockContext).Any())
            {
                // group doesn't have requirements so no need to calculate
                return;
            }

            var updatedRequirements = group.PersonMeetsGroupRequirements(rockContext, this.PersonId, this.GroupRoleId);

            foreach (var updatedRequirement in updatedRequirements)
            {
                updatedRequirement.GroupRequirement.UpdateGroupMemberRequirementResult(rockContext, updatedRequirement.PersonId, this.GroupId, updatedRequirement.MeetsGroupRequirement);
            }

            if (saveChanges)
            {
                rockContext.SaveChanges();
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Returns a list of each person and their GroupRequiremnt status for this group requirement
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="personQry">A qry containing the people whose requirements should be checked</param>
        /// <param name="groupRoleId">The group role identifier.</param>
        /// <returns></returns>
        public IEnumerable <PersonGroupRequirementStatus> PersonQueryableMeetsGroupRequirement(RockContext rockContext, IQueryable <Person> personQry, int?groupRoleId)
        {
            if ((this.GroupRoleId != null) && (groupRoleId != null) && (this.GroupRoleId != groupRoleId))
            {
                // if this GroupRequirement is for a specific role, the groupRole we are checking for is something different
                var result = personQry.ToList().Select(a =>
                                                       new PersonGroupRequirementStatus
                {
                    PersonId              = a.Id,
                    GroupRequirement      = this,
                    MeetsGroupRequirement = MeetsGroupRequirement.NotApplicable
                });

                return(result);
            }

            if (this.GroupRequirementType.RequirementCheckType == RequirementCheckType.Dataview)
            {
                if (this.GroupRequirementType.DataViewId.HasValue)
                {
                    var errorMessages           = new List <string>();
                    var personService           = new PersonService(rockContext);
                    var paramExpression         = personService.ParameterExpression;
                    var dataViewWhereExpression = this.GroupRequirementType.DataView.GetExpression(personService, paramExpression, out errorMessages);
                    var dataViewQry             = personService.Get(paramExpression, dataViewWhereExpression);

                    IQueryable <Person> warningDataViewQry = null;
                    if (this.GroupRequirementType.WarningDataViewId.HasValue)
                    {
                        var warningDataViewWhereExpression = this.GroupRequirementType.WarningDataView.GetExpression(personService, paramExpression, out errorMessages);
                        warningDataViewQry = personService.Get(paramExpression, warningDataViewWhereExpression);
                    }

                    if (dataViewQry != null)
                    {
                        var personWithRequirements = from p in personQry
                                                     join d in dataViewQry on p equals d into oj
                                                     from d in oj.DefaultIfEmpty()
                                                     select new { PersonId = p.Id, Included = d != null, WarningIncluded = false };

                        // if a Warning Database was specified, set the WarningIncluded flag to true if they are included in the Warning Dataview
                        if (warningDataViewQry != null)
                        {
                            personWithRequirements = personWithRequirements.Select(a => new
                            {
                                a.PersonId,
                                a.Included,
                                WarningIncluded = warningDataViewQry.Any(w => w.Id == a.PersonId)
                            });
                        }

                        var result = personWithRequirements.ToList().Select(a =>
                                                                            new PersonGroupRequirementStatus
                        {
                            PersonId              = a.PersonId,
                            GroupRequirement      = this,
                            MeetsGroupRequirement = a.Included
                                    ? (a.WarningIncluded ? MeetsGroupRequirement.MeetsWithWarning : MeetsGroupRequirement.Meets)
                                    : MeetsGroupRequirement.NotMet
                        });

                        return(result);
                    }
                }
                else
                {
                    throw new Exception("No dataview assigned to Group Requirement Type: " + this.GroupRequirementType.Name);
                }
            }
            else if (this.GroupRequirementType.RequirementCheckType == RequirementCheckType.Sql)
            {
                string formattedSql        = this.GroupRequirementType.SqlExpression.ResolveMergeFields(this.GroupRequirementType.GetMergeObjects(this.Group));
                string warningFormattedSql = this.GroupRequirementType.WarningSqlExpression.ResolveMergeFields(this.GroupRequirementType.GetMergeObjects(this.Group));
                try
                {
                    var tableResult = DbService.GetDataTable(formattedSql, System.Data.CommandType.Text, null);
                    if (tableResult.Columns.Count > 0)
                    {
                        IEnumerable <int> personIds        = tableResult.Rows.OfType <System.Data.DataRow>().Select(r => Convert.ToInt32(r[0]));
                        IEnumerable <int> warningPersonIds = null;

                        // if a Warning SQL was specified, get a list of PersonIds that should have a warning with their status
                        if (!string.IsNullOrWhiteSpace(warningFormattedSql))
                        {
                            var warningTableResult = DbService.GetDataTable(warningFormattedSql, System.Data.CommandType.Text, null);
                            if (warningTableResult.Columns.Count > 0)
                            {
                                warningPersonIds = warningTableResult.Rows.OfType <System.Data.DataRow>().Select(r => Convert.ToInt32(r[0]));
                            }
                        }

                        var result = personQry.Select(a => a.Id).ToList().Select(a => new PersonGroupRequirementStatus
                        {
                            PersonId              = a,
                            GroupRequirement      = this,
                            MeetsGroupRequirement = personIds.Contains(a)
                                    ? ((warningPersonIds != null && warningPersonIds.Contains(a))
                                        ? MeetsGroupRequirement.MeetsWithWarning
                                        : MeetsGroupRequirement.Meets
                                       )
                                    : MeetsGroupRequirement.NotMet,
                        });

                        return(result);
                    }
                }
                catch (Exception ex)
                {
                    // Exception occurred (probably due to bad SQL)
                    ExceptionLogService.LogException(ex, System.Web.HttpContext.Current);

                    var result = personQry.Select(a => a.Id).ToList().Select(a => new PersonGroupRequirementStatus
                    {
                        PersonId              = a,
                        GroupRequirement      = this,
                        MeetsGroupRequirement = MeetsGroupRequirement.Error
                    });

                    return(result);
                }
            }
            else
            {
                // manual
                var groupMemberRequirementQry = new GroupMemberRequirementService(rockContext).Queryable().Where(a => a.GroupRequirementId == this.Id && a.RequirementMetDateTime.HasValue);

                var result = personQry.ToList().Select(a =>
                                                       new PersonGroupRequirementStatus
                {
                    PersonId              = a.Id,
                    GroupRequirement      = this,
                    MeetsGroupRequirement = groupMemberRequirementQry.Any(r => r.GroupMember.PersonId == a.Id) ? MeetsGroupRequirement.Meets : MeetsGroupRequirement.NotMet
                });

                return(result);
            }

            // shouldn't happen
            return(null);
        }
Esempio n. 4
0
        /// <summary>
        /// Updates the group member requirement result.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="personId">The person identifier.</param>
        /// <param name="groupId">The group identifier.</param>
        /// <param name="meetsGroupRequirement">The meets group requirement.</param>
        public void UpdateGroupMemberRequirementResult(RockContext rockContext, int personId, int groupId, MeetsGroupRequirement meetsGroupRequirement)
        {
            GroupRequirement groupRequirement = this;
            var currentDateTime = RockDateTime.Now;
            GroupMemberRequirementService groupMemberRequirementService = new GroupMemberRequirementService(rockContext);
            var groupMemberService = new GroupMemberService(rockContext);
            var groupMemberQry     = groupMemberService.Queryable(true).Where(a => a.PersonId == personId && a.GroupId == groupId);

            if (groupRequirement.GroupId.HasValue)
            {
                groupMemberQry = groupMemberQry.Where(g => g.GroupId == groupRequirement.GroupId);
            }
            else if (groupRequirement.GroupTypeId.HasValue)
            {
                groupMemberQry = groupMemberQry.Where(g => g.Group.GroupTypeId == groupRequirement.GroupTypeId);
            }
            else
            {
                // shouldn't happen, but grouprequirement doesn't have a groupId or a GroupTypeId
                return;
            }



            if (this.GroupRoleId != null)
            {
                groupMemberQry = groupMemberQry.Where(a => a.GroupRoleId == this.GroupRoleId);
            }

            // just in case the same person is in the same group multiple times, get a list of the groupMember records for this person
            foreach (var groupMemberId in groupMemberQry.Select(a => a.Id))
            {
                var groupMemberRequirement = groupMemberRequirementService.Queryable().Where(a => a.GroupMemberId == groupMemberId && a.GroupRequirementId == groupRequirement.Id).FirstOrDefault();
                if (groupMemberRequirement == null)
                {
                    groupMemberRequirement = new GroupMemberRequirement();
                    groupMemberRequirement.GroupMemberId      = groupMemberId;
                    groupMemberRequirement.GroupRequirementId = groupRequirement.Id;
                    groupMemberRequirementService.Add(groupMemberRequirement);
                }

                groupMemberRequirement.LastRequirementCheckDateTime = currentDateTime;

                if ((meetsGroupRequirement == MeetsGroupRequirement.Meets) || (meetsGroupRequirement == MeetsGroupRequirement.MeetsWithWarning))
                {
                    // they meet the requirement so update the Requirement Met Date/Time
                    groupMemberRequirement.RequirementMetDateTime  = currentDateTime;
                    groupMemberRequirement.RequirementFailDateTime = null;
                }
                else
                {
                    // they don't meet the requirement so set the Requirement Met Date/Time to null
                    groupMemberRequirement.RequirementMetDateTime  = null;
                    groupMemberRequirement.RequirementFailDateTime = currentDateTime;
                }

                if (meetsGroupRequirement == MeetsGroupRequirement.MeetsWithWarning)
                {
                    if (!groupMemberRequirement.RequirementWarningDateTime.HasValue)
                    {
                        // they have a warning for the requirement, and didn't have a warning already
                        groupMemberRequirement.RequirementWarningDateTime = currentDateTime;
                    }
                }
                else
                {
                    // no warning, so set to null
                    groupMemberRequirement.RequirementWarningDateTime = null;
                }
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Returns a list of each person and their GroupRequiremnt status for this group requirement
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="personQry">The person qry.</param>
        /// <param name="groupId">The group identifier.</param>
        /// <param name="groupRoleId">The group role identifier.</param>
        /// <returns></returns>
        /// <exception cref="System.Exception">No dataview assigned to Group Requirement Type: " + this.GroupRequirementType.Name</exception>
        public IEnumerable <PersonGroupRequirementStatus> PersonQueryableMeetsGroupRequirement(RockContext rockContext, IQueryable <Person> personQry, int groupId, int?groupRoleId)
        {
            if ((this.GroupRoleId != null) && (groupRoleId != null) && (this.GroupRoleId != groupRoleId))
            {
                // if this GroupRequirement is for a specific role, the groupRole we are checking for is something different
                var result = personQry.Select(p => p.Id).ToList().Select(a =>
                                                                         new PersonGroupRequirementStatus
                {
                    PersonId              = Id,
                    GroupRequirement      = this,
                    MeetsGroupRequirement = MeetsGroupRequirement.NotApplicable
                });

                return(result);
            }

            if (this.GroupRequirementType.RequirementCheckType == RequirementCheckType.Dataview)
            {
                var        errorMessages               = new List <string>();
                var        personService               = new PersonService(rockContext);
                var        paramExpression             = personService.ParameterExpression;
                List <int> warningDataViewPersonIdList = null;
                if (this.GroupRequirementType.WarningDataViewId.HasValue)
                {
                    var warningDataViewWhereExpression = this.GroupRequirementType.WarningDataView.GetExpression(personService, paramExpression, out errorMessages);
                    warningDataViewPersonIdList = personService.Get(paramExpression, warningDataViewWhereExpression).Where(a => personQry.Any(p => p.Id == a.Id)).Select(a => a.Id).ToList();
                }

                if (this.GroupRequirementType.DataViewId.HasValue)
                {
                    var dataViewWhereExpression = this.GroupRequirementType.DataView.GetExpression(personService, paramExpression, out errorMessages);
                    var dataViewQry             = personService.Get(paramExpression, dataViewWhereExpression);
                    if (dataViewQry != null)
                    {
                        var personWithRequirementsQuery = from p in personQry
                                                          join d in dataViewQry on p.Id equals d.Id into oj
                                                          from d in oj.DefaultIfEmpty()
                                                          select new { PersonId = p.Id, Included = d != null };

                        var personWithRequirementsList = personWithRequirementsQuery.Select(p => new { PersonId = p.PersonId, Included = p.Included }).ToList();

                        var result = personWithRequirementsList.Select(a =>
                        {
                            var personGroupRequirementStatus = new PersonGroupRequirementStatus
                            {
                                PersonId         = a.PersonId,
                                GroupRequirement = this
                            };

                            var hasWarning = warningDataViewPersonIdList?.Contains(a.PersonId) == true;

                            if (a.Included)
                            {
                                if (hasWarning)
                                {
                                    personGroupRequirementStatus.MeetsGroupRequirement = MeetsGroupRequirement.MeetsWithWarning;
                                }
                                else
                                {
                                    personGroupRequirementStatus.MeetsGroupRequirement = MeetsGroupRequirement.Meets;
                                }
                            }
                            else
                            {
                                personGroupRequirementStatus.MeetsGroupRequirement = MeetsGroupRequirement.NotMet;
                            }

                            return(personGroupRequirementStatus);
                        }
                                                                       );

                        return(result);
                    }
                }
                else
                {
                    var personWithIdRequirements = personQry.Select(p => p.Id);

                    var result = personWithIdRequirements.ToList().Select(a =>
                                                                          new PersonGroupRequirementStatus
                    {
                        PersonId              = a,
                        GroupRequirement      = this,
                        MeetsGroupRequirement = warningDataViewPersonIdList.Contains(a) == true ? MeetsGroupRequirement.MeetsWithWarning : MeetsGroupRequirement.Meets
                    });

                    return(result);
                }
            }
            else if (this.GroupRequirementType.RequirementCheckType == RequirementCheckType.Sql)
            {
                // if requirement set on GroupType, this.Group is null
                var    targetGroup      = this.Group ?? new GroupService(rockContext).Get(groupId);
                var    personQryIdList  = personQry.Select(a => a.Id).ToList();
                Person personMergeField = null;
                if (personQryIdList.Count == 1)
                {
                    var personId = personQryIdList[0];
                    personMergeField = new PersonService(rockContext).GetNoTracking(personId);
                }

                string formattedSql        = this.GroupRequirementType.SqlExpression.ResolveMergeFields(this.GroupRequirementType.GetMergeObjects(targetGroup, personMergeField));
                string warningFormattedSql = this.GroupRequirementType.WarningSqlExpression.ResolveMergeFields(this.GroupRequirementType.GetMergeObjects(targetGroup, personMergeField));
                try
                {
                    var tableResult = DbService.GetDataTable(formattedSql, System.Data.CommandType.Text, null);
                    if (tableResult.Columns.Count > 0)
                    {
                        IEnumerable <int> personIds        = tableResult.Rows.OfType <System.Data.DataRow>().Select(r => Convert.ToInt32(r[0]));
                        IEnumerable <int> warningPersonIds = null;

                        // if a Warning SQL was specified, get a list of PersonIds that should have a warning with their status
                        if (!string.IsNullOrWhiteSpace(warningFormattedSql))
                        {
                            var warningTableResult = DbService.GetDataTable(warningFormattedSql, System.Data.CommandType.Text, null);
                            if (warningTableResult.Columns.Count > 0)
                            {
                                warningPersonIds = warningTableResult.Rows.OfType <System.Data.DataRow>().Select(r => Convert.ToInt32(r[0]));
                            }
                        }

                        var result = personQryIdList.Select(a => new PersonGroupRequirementStatus
                        {
                            PersonId              = a,
                            GroupRequirement      = this,
                            MeetsGroupRequirement = personIds.Contains(a)
                                    ? ((warningPersonIds != null && warningPersonIds.Contains(a))
                                        ? MeetsGroupRequirement.MeetsWithWarning
                                        : MeetsGroupRequirement.Meets
                                       )
                                    : MeetsGroupRequirement.NotMet,
                        });

                        return(result);
                    }
                }
                catch (Exception ex)
                {
                    // Exception occurred (probably due to bad SQL)
                    ExceptionLogService.LogException(ex, System.Web.HttpContext.Current);

                    var result = personQry.Select(a => a.Id).ToList().Select(a => new PersonGroupRequirementStatus
                    {
                        PersonId              = a,
                        GroupRequirement      = this,
                        MeetsGroupRequirement = MeetsGroupRequirement.Error,
                        CalculationException  = ex
                    });

                    return(result);
                }
            }
            else
            {
                // manual
                var groupMemberRequirementQry = new GroupMemberRequirementService(rockContext).Queryable().Where(a => a.GroupMember.GroupId == groupId && a.GroupRequirementId == this.Id && a.RequirementMetDateTime.HasValue);

                var result = personQry.ToList().Select(a =>
                                                       new PersonGroupRequirementStatus
                {
                    PersonId              = a.Id,
                    GroupRequirement      = this,
                    MeetsGroupRequirement = groupMemberRequirementQry.Any(r => r.GroupMember.PersonId == a.Id) ? MeetsGroupRequirement.Meets : MeetsGroupRequirement.NotMet
                });

                return(result);
            }

            // shouldn't happen
            return(null);
        }
Esempio n. 6
0
        /// <summary>
        /// Groups the members not meeting requirements.
        /// </summary>
        /// <param name="groupId">The group identifier.</param>
        /// <param name="includeWarnings">if set to <c>true</c> [include warnings].</param>
        /// <param name="includeInactive">if set to <c>true</c> [include inactive].</param>
        /// <returns></returns>
        public Dictionary <GroupMember, Dictionary <PersonGroupRequirementStatus, DateTime> > GroupMembersNotMeetingRequirements(int groupId, bool includeWarnings, bool includeInactive = false)
        {
            Dictionary <GroupMember, Dictionary <PersonGroupRequirementStatus, DateTime> > results = new Dictionary <GroupMember, Dictionary <PersonGroupRequirementStatus, DateTime> >();

            var rockContext                   = this.Context as RockContext;
            var groupRequirementService       = new GroupRequirementService(rockContext);
            var groupMemberService            = new GroupMemberService(rockContext);
            var groupMemberRequirementService = new GroupMemberRequirementService(rockContext);

            var  qryGroupRequirements = groupRequirementService.Queryable().Where(a => a.GroupId == groupId);
            bool hasGroupRequirements = qryGroupRequirements.Any();

            if (!hasGroupRequirements)
            {
                // if no group requirements, then there are no members that don't meet the requirements, so return an empty dictionary
                return(new Dictionary <GroupMember, Dictionary <PersonGroupRequirementStatus, DateTime> >());
            }

            var qryGroupMembers            = groupMemberService.Queryable().Where(a => a.GroupId == groupId);
            var qryGroupMemberRequirements = groupMemberRequirementService.Queryable().Where(a => a.GroupMember.GroupId == groupId);

            if (!includeInactive)
            {
                qryGroupMembers = qryGroupMembers.Where(a => a.GroupMemberStatus == GroupMemberStatus.Active);
            }

            // get a list of group member ids that don't meet all the requirements
            IQueryable <int> qryGroupMemberIdsThatLackGroupRequirements = qryGroupMembers.Where(
                a => !qryGroupRequirements.Select(x => x.Id).All(
                    r => a.GroupMemberRequirements.Where(mr => mr.RequirementMetDateTime.HasValue).Select(x => x.GroupRequirementId).Contains(r))).Select(a => a.Id);

            IQueryable <GroupMember> qryMembersWithIssues;

            if (includeWarnings)
            {
                IQueryable <int> qryGroupMemberIdsWithRequirementWarnings = qryGroupMemberRequirements.Where(a => a.RequirementWarningDateTime != null || a.RequirementFailDateTime != null).Select(a => a.GroupMemberId).Distinct();
                qryMembersWithIssues = qryGroupMembers.Where(a => qryGroupMemberIdsThatLackGroupRequirements.Contains(a.Id) || qryGroupMemberIdsWithRequirementWarnings.Contains(a.Id));
            }
            else
            {
                qryMembersWithIssues = qryGroupMembers.Where(a => qryGroupMemberIdsThatLackGroupRequirements.Contains(a.Id));
            }

            var qry = qryMembersWithIssues.Select(a => new
            {
                GroupMember = a,
                GroupRequirementStatuses = qryGroupMemberRequirements.Where(x => x.GroupMemberId == a.Id)
            });

            var currentDateTime = RockDateTime.Now;

            foreach (var groupMemberWithIssues in qry)
            {
                Dictionary <PersonGroupRequirementStatus, DateTime> statuses = new Dictionary <PersonGroupRequirementStatus, DateTime>();

                // populate where the status is known
                foreach (var requirementStatus in groupMemberWithIssues.GroupRequirementStatuses)
                {
                    PersonGroupRequirementStatus status = new PersonGroupRequirementStatus();
                    status.GroupRequirement = requirementStatus.GroupRequirement;
                    status.PersonId         = groupMemberWithIssues.GroupMember.PersonId;

                    DateTime occuranceDate = new DateTime();

                    if (requirementStatus.RequirementMetDateTime == null)
                    {
                        status.MeetsGroupRequirement = MeetsGroupRequirement.NotMet;
                        occuranceDate = requirementStatus.RequirementFailDateTime ?? currentDateTime;
                    }
                    else if (requirementStatus.RequirementWarningDateTime.HasValue)
                    {
                        status.MeetsGroupRequirement = MeetsGroupRequirement.MeetsWithWarning;
                        occuranceDate = requirementStatus.RequirementWarningDateTime.Value;
                    }
                    else
                    {
                        status.MeetsGroupRequirement = MeetsGroupRequirement.Meets;
                        occuranceDate = requirementStatus.RequirementMetDateTime.Value;
                    }

                    statuses.Add(status, occuranceDate);
                }

                // also add any groupRequirements that they don't have statuses for (and therefore haven't met)
                foreach (var groupRequirement in qryGroupRequirements)
                {
                    if (!statuses.Any(x => x.Key.GroupRequirement.Id == groupRequirement.Id))
                    {
                        PersonGroupRequirementStatus status = new PersonGroupRequirementStatus();
                        status.GroupRequirement      = groupRequirement;
                        status.PersonId              = groupMemberWithIssues.GroupMember.PersonId;
                        status.MeetsGroupRequirement = MeetsGroupRequirement.NotMet;
                        statuses.Add(status, currentDateTime);
                    }
                }

                var statusesWithIssues = statuses.Where(a => a.Key.MeetsGroupRequirement != MeetsGroupRequirement.Meets).ToDictionary(k => k.Key, v => v.Value);

                if (statusesWithIssues.Any())
                {
                    results.Add(groupMemberWithIssues.GroupMember, statusesWithIssues);
                }
            }

            return(results);
        }