private IQueryable <RelatedPersonInfo> GetRelatedPeopleQuery(RockContext context, IEnumerable <int> groupTypeIds, IEnumerable <Guid> principalRoleGuids, IEnumerable <Guid> targetRoleGuids,
                                                                     string relationshipName = "*")
        {
            var relationshipGroupMembersQuery = new GroupMemberService(context).Queryable();

            relationshipGroupMembersQuery = relationshipGroupMembersQuery.Where(x => groupTypeIds.Contains(x.Group.GroupTypeId));

            var relatedPeopleQuery = new PersonService(context).Queryable()
                                     .SelectMany(p => relationshipGroupMembersQuery.Where(gm => gm.PersonId == p.Id && principalRoleGuids.Contains(gm.GroupRole.Guid))
                                                 .SelectMany(gm => gm.Group.Members)
                                                 .Where(gm => targetRoleGuids.Contains(gm.GroupRole.Guid) && gm.PersonId != p.Id)
                                                 .OrderBy(gm => gm.GroupRole.Order)
                                                 .ThenBy(gm => gm.Person.BirthDate)
                                                 .ThenBy(gm => gm.Person.Gender)
                                                 .Select(
                                                     gm =>
                                                     new RelatedPersonInfo
            {
                RelatedToPersonId = p.Id,
                PersonId          = gm.Person.Id,
                FirstName         = gm.Person.FirstName,
                LastName          = gm.Person.LastName,
                Suffix            = gm.Person.SuffixValue.Value,
                RelationshipName  =
                    (relationshipName == "*"
                                                                                                                                      ? gm.GroupRole.Name
                                                                                                                                      : relationshipName)
            }));

            return(relatedPeopleQuery);
        }
        private void ListGroups()
        {
            RockContext rockContext = new RockContext();

            var qry = new GroupMemberService(rockContext)
                      .Queryable("Group")
                      .Where(m => m.PersonId == CurrentPersonId &&
                             m.GroupMemberStatus == GroupMemberStatus.Active &&
                             m.Group.IsActive == true);

            List <Guid> includeGroupTypeGuids = GetAttributeValue("IncludeGroupTypes").SplitDelimitedValues().Select(a => Guid.Parse(a)).ToList();

            if (includeGroupTypeGuids.Count > 0)
            {
                qry = qry.Where(t => includeGroupTypeGuids.Contains(t.Group.GroupType.Guid));
            }

            List <Guid> excludeGroupTypeGuids = GetAttributeValue("ExcludeGroupTypes").SplitDelimitedValues().Select(a => Guid.Parse(a)).ToList();

            if (excludeGroupTypeGuids.Count > 0)
            {
                qry = qry.Where(t => !excludeGroupTypeGuids.Contains(t.Group.GroupType.Guid));
            }

            var groups = qry.Select(m => new GroupInvolvementSummary  {
                Group = m.Group, Role = m.GroupRole.Name, IsLeader = m.GroupRole.IsLeader, GroupType = m.Group.GroupType.Name
            }).ToList();

            var mergeFields = new Dictionary <string, object>();

            mergeFields.Add("Groups", groups);
            mergeFields.Add("CurrentPerson", CurrentPerson);
            var globalAttributeFields = Rock.Web.Cache.GlobalAttributesCache.GetMergeFields(CurrentPerson);

            globalAttributeFields.ToList().ForEach(d => mergeFields.Add(d.Key, d.Value));

            Dictionary <string, object> linkedPages = new Dictionary <string, object>();

            linkedPages.Add("DetailPage", LinkedPageUrl("DetailPage", null));
            mergeFields.Add("LinkedPages", linkedPages);

            string template = GetAttributeValue("LavaTemplate");

            // show debug info
            bool enableDebug = GetAttributeValue("EnableDebug").AsBoolean();

            if (enableDebug && IsUserAuthorized(Authorization.EDIT))
            {
                lDebug.Visible = true;
                lDebug.Text    = mergeFields.lavaDebugInfo();
            }

            lContent.Text = template.ResolveMergeFields(mergeFields);
        }
Example #3
0
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entityIdProperty">The entity identifier property.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override Expression GetExpression(RockContext context, MemberExpression entityIdProperty, string selection)
        {
            var adultGuid  = SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT.AsGuid();
            var childGuid  = SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_CHILD.AsGuid();
            var familyGuid = SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuid();

            //Contains an array of the int representation of EmailPreferences selected
            int[] selectedPreferences = null;
            if (!string.IsNullOrEmpty(selection))
            {
                selectedPreferences = Array.ConvertAll(selection.Split(','), s => int.Parse(s));
            }

            var familyGroupMembers = new GroupMemberService(context).Queryable()
                                     .Where(m => m.Group.GroupType.Guid == familyGuid);

            IQueryable <IEnumerable <string> > personParentsEmailQuery;

            //Done as an if statement because:
            // 1) If you try and check selectedPreferences for null in LINQ it throws an exception
            // 2) If all preferences are selected it's quicker to disregard the preference entirely
            if (selectedPreferences == null || selectedPreferences.Length == 3)
            {
                // this returns Enumerable of Email addresses for Parents per row. The Grid then uses ListDelimiterField to convert the list into Parent's Phone Numbers
                personParentsEmailQuery = new PersonService(context).Queryable()
                                          .Select(p => familyGroupMembers.Where(s => s.PersonId == p.Id && s.GroupRole.Guid == childGuid)
                                                  .SelectMany(gm => gm.Group.Members)
                                                  .Where(m => m.GroupRole.Guid == adultGuid)
                                                  .Where(m => !string.IsNullOrEmpty(m.Person.Email) && m.Person.IsEmailActive)
                                                  .OrderBy(m => m.Group.Members.FirstOrDefault(x => x.PersonId == p.Id).GroupOrder ?? int.MaxValue)
                                                  .Select(q => q.Person.Email).AsEnumerable());
            }
            else
            {
                // this returns Enumerable of Email addresses for Parents per row. The Grid then uses ListDelimiterField to convert the list into Parent's Phone Numbers
                personParentsEmailQuery = new PersonService(context).Queryable()
                                          .Select(p => familyGroupMembers.Where(s => s.PersonId == p.Id && s.GroupRole.Guid == childGuid)
                                                  .SelectMany(gm => gm.Group.Members)
                                                  .Where(m => m.GroupRole.Guid == adultGuid)
                                                  .Where(m => selectedPreferences.Contains((int)m.Person.EmailPreference))
                                                  .Where(m => !string.IsNullOrEmpty(m.Person.Email) && m.Person.IsEmailActive)
                                                  .OrderBy(m => m.Group.Members.FirstOrDefault(x => x.PersonId == p.Id).GroupOrder ?? int.MaxValue)
                                                  .Select(q => q.Person.Email).AsEnumerable());
            }

            var selectEmail = SelectExpressionExtractor.Extract(personParentsEmailQuery, entityIdProperty, "p");

            return(selectEmail);
        }
Example #4
0
        /// <summary>
        /// Gets the recipient person identifier expression.
        /// </summary>
        /// <param name="dbContext">The database context.</param>
        /// <param name="entityIdProperty">The entity identifier property.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public Expression GetRecipientPersonIdExpression( System.Data.Entity.DbContext dbContext, MemberExpression entityIdProperty, string selection )
        {
            var rockContext = dbContext as RockContext;
            if ( rockContext != null )
            {
                Guid adultGuid = Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT.AsGuid();
                Guid childGuid = Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_CHILD.AsGuid();
                Guid familyGuid = Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuid();

                var familyGroupMembers = new GroupMemberService( rockContext ).Queryable()
                    .Where( m => m.Group.GroupType.Guid == familyGuid );

                // this returns Enumerable of KidInfo per row. See this.GetGridField to see how it is processed 
                var personChildrenQuery = new PersonService( rockContext ).Queryable()
                    .Select( p => familyGroupMembers.Where( s => s.PersonId == p.Id && s.GroupRole.Guid == adultGuid )
                        .SelectMany( m => m.Group.Members )
                        .Where( m => m.GroupRole.Guid == childGuid )
                        .OrderBy( m => m.Group.Members.FirstOrDefault( x => x.PersonId == p.Id ).GroupOrder ?? int.MaxValue )
                        .ThenBy( m => m.Person.BirthYear ).ThenBy( m => m.Person.BirthMonth ).ThenBy( m => m.Person.BirthDay )
                        .Select( m => m.Person.Id ).AsEnumerable() );

                var selectChildrenExpression = SelectExpressionExtractor.Extract( personChildrenQuery, entityIdProperty, "p" );

                return selectChildrenExpression;
            }

            return null;
        }
Example #5
0
        /// <summary>
        /// Gets the recipient person identifier expression.
        /// </summary>
        /// <param name="dbContext">The database context.</param>
        /// <param name="entityIdProperty">The entity identifier property.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public Expression GetRecipientPersonIdExpression(System.Data.Entity.DbContext dbContext, MemberExpression entityIdProperty, string selection)
        {
            var rockContext = dbContext as RockContext;

            if (rockContext != null)
            {
                Guid adultGuid  = Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT.AsGuid();
                Guid childGuid  = Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_CHILD.AsGuid();
                Guid familyGuid = Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuid();

                var familyGroupMembers = new GroupMemberService(rockContext).Queryable()
                                         .Where(m => m.Group.GroupType.Guid == familyGuid);

                // this returns Enumerable of ids for Parents per row. The Grid then uses ListDelimiterField to convert the list into Parents Names
                var personParentsQuery = new PersonService(rockContext).Queryable()
                                         .Select(p => familyGroupMembers.Where(s => s.PersonId == p.Id && s.GroupRole.Guid == childGuid)
                                                 .SelectMany(m => m.Group.Members)
                                                 .Where(m => m.GroupRole.Guid == adultGuid)
                                                 .OrderBy(m => m.Group.Members.FirstOrDefault(x => x.PersonId == p.Id).GroupOrder ?? int.MaxValue)
                                                 .ThenBy(m => m.Person.Gender)
                                                 .Select(m => m.Person.Id).AsEnumerable());

                var selectParentsExpression = SelectExpressionExtractor.Extract(personParentsQuery, entityIdProperty, "p");

                return(selectParentsExpression);
            }

            return(null);
        }
Example #6
0
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entityIdProperty">The entity identifier property.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override Expression GetExpression(RockContext context, MemberExpression entityIdProperty, string selection)
        {
            Guid adultGuid  = Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT.AsGuid();
            Guid childGuid  = Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_CHILD.AsGuid();
            Guid familyGuid = Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuid();

            var familyGroupMembers = new GroupMemberService(context).Queryable()
                                     .Where(m => m.Group.GroupType.Guid == familyGuid);

            // this returns Enumerable of KidInfo per row. See this.GetGridField to see how it is processed
            var personChildrenQuery = new PersonService(context).Queryable()
                                      .Select(p => familyGroupMembers.Where(s => s.PersonId == p.Id && s.GroupRole.Guid == adultGuid)
                                              .SelectMany(m => m.Group.Members)
                                              .Where(m => m.GroupRole.Guid == childGuid)
                                              .OrderBy(m => m.Person.BirthYear).ThenBy(m => m.Person.BirthMonth).ThenBy(m => m.Person.BirthDay)
                                              .Select(m => new KidInfo
            {
                NickName      = m.Person.NickName,
                LastName      = m.Person.LastName,
                SuffixValueId = m.Person.SuffixValueId,
                Gender        = m.Person.Gender,
                BirthDate     = m.Person.BirthDate
            }).AsEnumerable());

            var selectChildrenExpression = SelectExpressionExtractor.Extract(personChildrenQuery, entityIdProperty, "p");

            return(selectChildrenExpression);
        }
Example #7
0
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entityIdProperty">The entity identifier property.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override Expression GetExpression(RockContext context, MemberExpression entityIdProperty, string selection)
        {
            //// Spouse is determined if all these conditions are met
            //// 1) Adult in the same family as Person (GroupType = Family, GroupRole = Adult, and in same Group)
            //// 2) Opposite Gender as Person
            //// 3) Both Persons are Married

            var  selectionParts  = selection.Split('|');
            bool includeLastname = selectionParts.Length > 0 && selectionParts[0].AsBoolean();

            Guid adultGuid             = Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT.AsGuid();
            Guid marriedGuid           = Rock.SystemGuid.DefinedValue.PERSON_MARITAL_STATUS_MARRIED.AsGuid();
            int  marriedDefinedValueId = DefinedValueCache.Get(marriedGuid).Id;
            Guid familyGuid            = Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuid();

            var familyGroupMembers = new GroupMemberService(context).Queryable()
                                     .Where(m => m.Group.GroupType.Guid == familyGuid);

            var personSpouseQuery = new PersonService(context).Queryable()
                                    .Select(p => familyGroupMembers.Where(s => s.PersonId == p.Id && s.Person.MaritalStatusValueId == marriedDefinedValueId && s.GroupRole.Guid == adultGuid)
                                            .SelectMany(m => m.Group.Members)
                                            .Where(m =>
                                                   m.PersonId != p.Id &&
                                                   m.GroupRole.Guid == adultGuid &&
                                                   m.Person.Gender != p.Gender &&
                                                   m.Person.MaritalStatusValueId == marriedDefinedValueId &&
                                                   !m.Person.IsDeceased)
                                            .OrderBy(m => m.Group.Members.FirstOrDefault(x => x.PersonId == p.Id).GroupOrder ?? int.MaxValue)
                                            .Select(m => includeLastname ? m.Person.NickName + " " + m.Person.LastName : m.Person.NickName).FirstOrDefault());

            var selectSpouseExpression = SelectExpressionExtractor.Extract(personSpouseQuery, entityIdProperty, "p");

            return(selectSpouseExpression);
        }
Example #8
0
        /// <summary>
        /// Gets the recipient person identifier expression.
        /// </summary>
        /// <param name="dbContext">The database context.</param>
        /// <param name="entityIdProperty">The entity identifier property.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public Expression GetRecipientPersonIdExpression(System.Data.Entity.DbContext dbContext, MemberExpression entityIdProperty, string selection)
        {
            var rockContext = dbContext as RockContext;

            if (rockContext != null)
            {
                Guid adultGuid             = Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT.AsGuid();
                Guid marriedGuid           = Rock.SystemGuid.DefinedValue.PERSON_MARITAL_STATUS_MARRIED.AsGuid();
                int  marriedDefinedValueId = DefinedValueCache.Get(marriedGuid).Id;
                Guid familyGuid            = Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuid();

                var familyGroupMembers = new GroupMemberService(rockContext).Queryable()
                                         .Where(m => m.Group.GroupType.Guid == familyGuid);

                var personSpouseQuery = new PersonService(rockContext).Queryable()
                                        .Select(p => familyGroupMembers.Where(s => s.PersonId == p.Id && s.Person.MaritalStatusValueId == marriedDefinedValueId && s.GroupRole.Guid == adultGuid)
                                                .SelectMany(m => m.Group.Members)
                                                .Where(m =>
                                                       m.PersonId != p.Id &&
                                                       m.GroupRole.Guid == adultGuid &&
                                                       m.Person.Gender != p.Gender &&
                                                       m.Person.MaritalStatusValueId == marriedDefinedValueId &&
                                                       !m.Person.IsDeceased)
                                                .OrderBy(m => m.Group.Members.FirstOrDefault(x => x.PersonId == p.Id).GroupOrder ?? int.MaxValue)
                                                .Select(m => m.Person.Id).FirstOrDefault());

                var selectSpouseExpression = SelectExpressionExtractor.Extract(personSpouseQuery, entityIdProperty, "p");

                return(selectSpouseExpression);
            }

            return(null);
        }
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entityIdProperty">The entity identifier property.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override Expression GetExpression(RockContext context, MemberExpression entityIdProperty, string selection)
        {
            Guid adultGuid  = Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT.AsGuid();
            Guid childGuid  = Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_CHILD.AsGuid();
            Guid familyGuid = Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuid();
            Guid?phoneNumberTypeValueGuid = selection.AsGuidOrNull();

            if (!phoneNumberTypeValueGuid.HasValue)
            {
                phoneNumberTypeValueGuid = Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_HOME.AsGuid();
            }

            int phoneNumberTypeValueId = DefinedValueCache.Read(phoneNumberTypeValueGuid.Value).Id;

            var familyGroupMembers = new GroupMemberService(context).Queryable()
                                     .Where(m => m.Group.GroupType.Guid == familyGuid);

            // this returns Enumerable of PhoneNumber for Parents per row. The Grid then uses ListDelimiterField to convert the list into Parent's Phone Numbers
            var personParentsPhoneQuery = new PersonService(context).Queryable()
                                          .Select(p => familyGroupMembers.Where(s => s.PersonId == p.Id && s.GroupRole.Guid == childGuid)
                                                  .SelectMany(m => m.Group.Members)
                                                  .Where(m => m.GroupRole.Guid == adultGuid)
                                                  .Select(m => m.Person)
                                                  .Where(m => m.PhoneNumbers.Count(t => t.NumberTypeValueId == phoneNumberTypeValueId) != 0)
                                                  .Select(m => m.PhoneNumbers.FirstOrDefault(t => t.NumberTypeValueId == phoneNumberTypeValueId)).AsEnumerable());

            var selectNumbersExpression = SelectExpressionExtractor.Extract(personParentsPhoneQuery, entityIdProperty, "p");

            return(selectNumbersExpression);
        }
Example #10
0
        /// <summary>
        /// Creates a Linq Expression that can be applied to an IQueryable to filter the result set.
        /// </summary>
        /// <param name="entityType">The type of entity in the result set.</param>
        /// <param name="serviceInstance">A service instance that can be queried to obtain the result set.</param>
        /// <param name="parameterExpression">The input parameter that will be injected into the filter expression.</param>
        /// <param name="selection">A formatted string representing the filter settings.</param>
        /// <returns>
        /// A Linq Expression that can be used to filter an IQueryable.
        /// </returns>
        public override Expression GetExpression(Type entityType, IService serviceInstance, ParameterExpression parameterExpression, string selection)
        {
            var settings = new FilterSettings(selection);

            var context = (RockContext)serviceInstance.Context;

            //
            // Define Candidate People.
            //

            var dataView = DataComponentSettingsHelper.GetDataViewForFilterComponent(settings.PersonDataViewGuid, context);

            var personService = new PersonService(context);

            var personQuery = personService.Queryable();

            if (dataView != null)
            {
                personQuery = DataComponentSettingsHelper.FilterByDataView(personQuery, dataView, personService);
            }

            var personKeys = personQuery.Select(x => x.Id);

            //
            // Construct the Query to return the list of Group Members matching the filter conditions.
            //
            var groupMemberQuery = new GroupMemberService(context).Queryable();

            groupMemberQuery = groupMemberQuery.Where(gm => personKeys.Contains(gm.PersonId));

            var result = FilterExpressionExtractor.Extract <Rock.Model.GroupMember>(groupMemberQuery, parameterExpression, "gm");

            return(result);
        }
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entityIdProperty">The entity identifier property.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override Expression GetExpression(RockContext context, MemberExpression entityIdProperty, string selection)
        {
            //// Spouse is determined if all these conditions are met
            //// 1) Adult in the same family as Person (GroupType = Family, GroupRole = Adult, and in same Group)
            //// 2) Opposite Gender as Person
            //// 3) Both Persons are Married

            Guid adultGuid             = Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT.AsGuid();
            Guid marriedGuid           = Rock.SystemGuid.DefinedValue.PERSON_MARITAL_STATUS_MARRIED.AsGuid();
            int  marriedDefinedValueId = DefinedValueCache.Read(marriedGuid).Id;
            Guid familyGuid            = Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuid();

            var familyGroupMembers = new GroupMemberService(context).Queryable()
                                     .Where(m => m.Group.GroupType.Guid == familyGuid);

            var personSpouseQuery = new PersonService(context).Queryable()
                                    .Select(p => familyGroupMembers.Where(s => s.PersonId == p.Id && s.Person.MaritalStatusValueId == marriedDefinedValueId && s.GroupRole.Guid == adultGuid)
                                            .SelectMany(m => m.Group.Members)
                                            .Where(fm => fm.PersonId != p.Id)
                                            .Where(m => m.GroupRole.Guid == adultGuid)
                                            .Where(m => m.Person.Gender != p.Gender)
                                            .Where(m => m.Person.MaritalStatusValueId == marriedDefinedValueId)
                                            .Select(m => m.Person.FirstName).FirstOrDefault());

            var selectSpouseExpression = SelectExpressionExtractor.Extract <Rock.Model.Person>(personSpouseQuery, entityIdProperty, "p");

            return(selectSpouseExpression);
        }
Example #12
0
        private IQueryable <RelatedPersonInfo> GetRelatedPeopleQuery(RockContext context, IEnumerable <int> groupTypeIds, IEnumerable <Guid> principalRoleGuids, IEnumerable <Guid> targetRoleGuids,
                                                                     string relationshipName = "*")
        {
            /*
             * 2020-03-19 - JPH
             *
             * If a given Report includes deceased individuals, the 'Related People' Field Type should list non-deceased
             * people who have known relationships with the deceased individual. Note that this is a one-way street: a
             * deceased Person should never be displayed within the 'Related People' Field Type itself, but rather: a
             * deceased Person should only be displayed as a row within a given Report when they are the subject of that
             * Report (the 'Include Deceased' checkbox has been checked for the underlying Data View).
             *
             * Reason: Issue #4120 (Reporting on Known Relationships for Deceased Individuals)
             * https://github.com/SparkDevNetwork/Rock/issues/4120
             */

            var relationshipGroupMembersQuery = new GroupMemberService(context).Queryable(true);

            relationshipGroupMembersQuery = relationshipGroupMembersQuery.Where(x => groupTypeIds.Contains(x.Group.GroupTypeId));

            var relatedPeopleQuery = new PersonService(context).Queryable(new PersonService.PersonQueryOptions {
                IncludeDeceased = true
            })
                                     .SelectMany(p => relationshipGroupMembersQuery.Where(gm => gm.PersonId == p.Id && principalRoleGuids.Contains(gm.GroupRole.Guid))
                                                 .SelectMany(gm => gm.Group.Members)
                                                 .Where(gm => targetRoleGuids.Contains(gm.GroupRole.Guid) && gm.PersonId != p.Id)
                                                 .Where(gm => gm.Person.IsDeceased == false)
                                                 .OrderBy(gm => gm.GroupRole.Order)
                                                 .ThenBy(gm => gm.Person.BirthDate)
                                                 .ThenBy(gm => gm.Person.Gender)
                                                 .Select(
                                                     gm =>
                                                     new RelatedPersonInfo
            {
                RelatedToPersonId = p.Id,
                PersonId          = gm.Person.Id,
                FirstName         = gm.Person.FirstName,
                LastName          = gm.Person.LastName,
                Suffix            = gm.Person.SuffixValue.Value,
                RelationshipName  =
                    (relationshipName == "*"
                                                                                                                                      ? gm.GroupRole.Name
                                                                                                                                      : relationshipName)
            }));

            return(relatedPeopleQuery);
        }
Example #13
0
        /// <summary>
        /// Loads the list of people that are in the selected group
        /// </summary>
        private void LoadDropDowns()
        {
            var personEntityType = EntityTypeCache.Read <Person>();
            var currentPerson    = RockPage.GetCurrentContext(personEntityType) as Person;

            int?personIdParam = Request.QueryString["personId"].AsIntegerOrNull();

            // if a personId is in the page params, use that instead of the person context
            if (personIdParam.HasValue)
            {
                if (currentPerson == null || currentPerson.Id != personIdParam.Value)
                {
                    SetPersonContext(personIdParam.Value, false);
                }
            }

            RockContext rockContext = new RockContext();
            Group       group       = null;
            var         groupGuid   = this.GetAttributeValue("Group").AsGuidOrNull();

            if (groupGuid.HasValue)
            {
                group = new GroupService(rockContext).Get(groupGuid.Value);
            }

            if (group == null)
            {
                nbSelectGroupWarning.Visible = true;
            }
            else
            {
                nbSelectGroupWarning.Visible = false;

                var personQry = new GroupMemberService(rockContext).Queryable().Where(a => a.GroupId == group.Id).Select(a => a.Person).Distinct();

                if (currentPerson != null)
                {
                    // ensure that the current person is in the selected group
                    currentPerson = personQry.Where(a => a.Id == currentPerson.Id).FirstOrDefault();
                }

                lCurrentSelection.Text = currentPerson != null?currentPerson.ToString() : GetAttributeValue("NoPersonText");

                var personList = personQry.OrderBy(a => a.LastName).ThenBy(a => a.NickName).ToList().Select(a => new
                {
                    Name = a.FullName,
                    Id   = a.Id
                }).ToList();

                // check if the person can be unselected
                if (!string.IsNullOrEmpty(GetAttributeValue("ClearSelectionText")))
                {
                    personList.Insert(0, new { Name = GetAttributeValue("ClearSelectionText"), Id = 0 });
                }

                rptPersons.DataSource = personList;
                rptPersons.DataBind();
            }
        }
Example #14
0
        /// <summary>
        /// Loads the list of people that are in the selected group
        /// </summary>
        private void LoadDropDowns()
        {
            var personEntityType = EntityTypeCache.Get <Person>();
            var currentPerson    = RockPage.GetCurrentContext(personEntityType) as Person;

            int?personIdParam = Request.QueryString["PersonId"].AsIntegerOrNull();

            // if a personId is in the page parameters, use that instead of the person context
            if (personIdParam.HasValue)
            {
                // if there is a query parameter, ensure that the Person Context cookie is set (and has an updated expiration)
                // note, the Person Context might already match due to the query parameter, but has a different cookie context, so we still need to ensure the cookie context is updated
                SetPersonContext(personIdParam.Value, false);
            }

            RockContext rockContext = new RockContext();
            Group       group       = null;
            var         groupGuid   = this.GetAttributeValue(AttributeKey.Group).AsGuidOrNull();

            if (groupGuid.HasValue)
            {
                group = new GroupService(rockContext).Get(groupGuid.Value);
            }

            if (group == null)
            {
                nbSelectGroupWarning.Visible = true;
            }
            else
            {
                nbSelectGroupWarning.Visible = false;

                var personQry = new GroupMemberService(rockContext).Queryable().Where(a => a.GroupId == group.Id).Select(a => a.Person).Distinct();

                if (currentPerson != null)
                {
                    // ensure that the current person is in the selected group
                    currentPerson = personQry.Where(a => a.Id == currentPerson.Id).FirstOrDefault();
                }

                lCurrentSelection.Text = currentPerson != null?currentPerson.ToString() : GetAttributeValue(AttributeKey.NoPersonText);

                var personList = personQry.OrderBy(a => a.LastName).ThenBy(a => a.NickName).ToList().Select(a => new
                {
                    Name = a.FullName,
                    Id   = a.Id
                }).ToList();

                // check if the person can be unselected
                if (!string.IsNullOrEmpty(GetAttributeValue(AttributeKey.ClearSelectionText)))
                {
                    personList.Insert(0, new { Name = GetAttributeValue(AttributeKey.ClearSelectionText), Id = 0 });
                }

                rptPersons.DataSource = personList;
                rptPersons.DataBind();
            }
        }
Example #15
0
        public void Execute(IJobExecutionContext context)
        {
            var         dataMap     = context.JobDetail.JobDataMap;
            RockContext rockContext = null;
            IQueryable <GroupMember> familyMembers = null;
            var dateRange       = SlidingDateRangePicker.CalculateDateRangeFromDelimitedValues(dataMap.GetString("DateRange") ?? "-1||");
            int peopleUpdated   = 0;
            var familyGroupType = GroupTypeCache.Get(Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY);

            do
            {
                if (familyMembers != null)
                {
                    foreach (var familyMember in familyMembers.OrderBy(f => f.Id).Take(100).ToList())
                    {
                        familyMember.Person.GivingGroupId = familyMember.GroupId;
                        peopleUpdated += 1;
                    }

                    rockContext.SaveChanges();
                }

                rockContext = new RockContext();

                familyMembers = new GroupMemberService(rockContext)
                                .Queryable("Group,Person")
                                .Where(g => g.Group.GroupType.Id == familyGroupType.Id &&
                                       (g.Person.GivingGroupId == 0 || g.Person.GivingGroupId == null));

                if (dateRange.Start.HasValue)
                {
                    familyMembers = familyMembers.Where(g => g.Person.CreatedDateTime >= dateRange.Start);
                }

                if (dateRange.End.HasValue)
                {
                    familyMembers = familyMembers.Where(g => g.Person.CreatedDateTime < dateRange.End);
                }
            } while (familyMembers.Any());

            context.Result = string.Format("Combined giving on {0} {1}", peopleUpdated, peopleUpdated == 1 ? "person" : "people");
        }
Example #16
0
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entityIdProperty">The entity identifier property.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override Expression GetExpression(RockContext context, MemberExpression entityIdProperty, string selection)
        {
            string[] selectionValues = selection.Split('|');

            Location selectedLocation    = null;
            int?     locationTypeValueId = null;

            if (selectionValues.Count() >= 2)
            {
                // the selected Location
                selectedLocation = new LocationService(context).Get(selectionValues[0].AsGuid());

                // which address type (home, work, previous) to use as the person's location
                var locationTypeValueGuid = selectionValues[1].AsGuidOrNull();
                if (locationTypeValueGuid.HasValue)
                {
                    var locationTypeValue = DefinedValueCache.Get(locationTypeValueGuid.Value);
                    if (locationTypeValue != null)
                    {
                        locationTypeValueId = locationTypeValue.Id;
                    }
                }
            }

            Guid familyGuid        = Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuid();
            int  familyGroupTypeId = new GroupTypeService(context).Get(familyGuid).Id;

            var groupMemberQuery = new GroupMemberService(context).Queryable();

            IQueryable <double?> personLocationDistanceQuery;

            if (selectedLocation != null)
            {
                personLocationDistanceQuery = new PersonService(context).Queryable()
                                              .Select(p =>
                                                      groupMemberQuery
                                                      .Where(m => m.Group.GroupTypeId == familyGroupTypeId && m.PersonId == p.Id)
                                                      .SelectMany(m => m.Group.GroupLocations)
                                                      .Where(gl => gl.GroupLocationTypeValueId == locationTypeValueId)
                                                      .Where(gl => gl.Location.GeoPoint != null)
                                                      .Select(s => DbFunctions.Truncate(s.Location.GeoPoint.Distance(selectedLocation.GeoPoint) * Location.MilesPerMeter, 2))
                                                      .FirstOrDefault());
            }
            else
            {
                personLocationDistanceQuery = new PersonService(context).Queryable()
                                              .Select(p => (double?)null);
            }

            var selectExpression = SelectExpressionExtractor.Extract(personLocationDistanceQuery, entityIdProperty, "p");

            return(selectExpression);
        }
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entityIdProperty">The entity identifier property.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override Expression GetExpression(RockContext context, MemberExpression entityIdProperty, string selection)
        {
            Guid adultGuid  = Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT.AsGuid();
            Guid childGuid  = Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_CHILD.AsGuid();
            Guid familyGuid = Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuid();

            var familyGroupMembers = new GroupMemberService(context).Queryable()
                                     .Where(m => m.Group.GroupType.Guid == familyGuid);

            // this returns Enumerable of Person for Parents per row. The Grid then uses ListDelimiterField to convert the list into Parents Names
            var personParentsQuery = new PersonService(context).Queryable()
                                     .Select(p => familyGroupMembers.Where(s => s.PersonId == p.Id && s.GroupRole.Guid == childGuid)
                                             .SelectMany(m => m.Group.Members)
                                             .Where(m => m.GroupRole.Guid == adultGuid)
                                             .OrderBy(m => m.Person.Gender)
                                             .Select(m => m.Person).AsEnumerable());

            var selectParentsExpression = SelectExpressionExtractor.Extract <Rock.Model.Person>(personParentsQuery, entityIdProperty, "p");

            return(selectParentsExpression);
        }
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="entityType">Type of the entity.</param>
        /// <param name="serviceInstance">The service instance.</param>
        /// <param name="parameterExpression">The parameter expression.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override Expression GetExpression(Type entityType, IService serviceInstance, ParameterExpression parameterExpression, string selection)
        {
            if (selection.IsNotNullOrWhiteSpace())
            {
                var ebPersonFieldType = FieldTypeCache.Get(EBGuid.FieldType.EVENTBRITE_PERSON.AsGuid());
                var ebPersonAttribute = new AttributeService(( RockContext )serviceInstance.Context).GetByFieldTypeId(ebPersonFieldType.Id).FirstOrDefault();

                if (ebPersonAttribute != null)
                {
                    var qry = new GroupMemberService(( RockContext )serviceInstance.Context).Queryable()
                              .WhereAttributeValue(( RockContext )serviceInstance.Context, a => a.Attribute.Key == ebPersonAttribute.Key && a.Value != null && a.Value != "" && a.Value.Contains("^"));

                    var groupMemberIds = new List <int>();
                    foreach (var groupMember in qry.ToList())
                    {
                        if (groupMember.Attributes == null)
                        {
                            groupMember.LoadAttributes();
                        }
                        var attributeVal = groupMember.GetAttributeValue(ebPersonAttribute.Key);
                        if (attributeVal.IsNotNullOrWhiteSpace())
                        {
                            var containsValue = attributeVal.Split(new char[] { '^' })[1].Split(new string[] { "||" }, StringSplitOptions.RemoveEmptyEntries).Contains(selection);
                            if (containsValue)
                            {
                                groupMemberIds.Add(groupMember.Id);
                            }
                        }
                    }
                    qry = qry.Where(gm => groupMemberIds.Contains(gm.Id));

                    Expression extractedFilterExpression = FilterExpressionExtractor.Extract <Rock.Model.GroupMember>(qry, parameterExpression, "gm");

                    return(extractedFilterExpression);
                }
            }

            return(null);
        }
        /// <summary>
        /// Creates a Linq Expression that can be applied to an IQueryable to filter the result set.
        /// </summary>
        /// <param name="entityType">The type of entity in the result set.</param>
        /// <param name="serviceInstance">A service instance that can be queried to obtain the result set.</param>
        /// <param name="parameterExpression">The input parameter that will be injected into the filter expression.</param>
        /// <param name="selection">A formatted string representing the filter settings.</param>
        /// <returns>
        /// A Linq Expression that can be used to filter an IQueryable.
        /// </returns>
        public override Expression GetExpression(Type entityType, IService serviceInstance, ParameterExpression parameterExpression, string selection)
        {
            var settings = new SelectSettings(selection);

            var context = (RockContext)serviceInstance.Context;

            //
            // Evaluate the Data View that defines the candidate Groups.
            //
            var dataView = DataComponentSettingsHelper.GetDataViewForFilterComponent(settings.DataViewGuid, context);

            var groupService = new GroupService(context);

            var groupQuery = groupService.Queryable();

            if (dataView != null)
            {
                groupQuery = DataComponentSettingsHelper.FilterByDataView(groupQuery, dataView, groupService);
            }
            else
            {
                // Apply a default Group filter to only show Groups that would be visible in a Group List.
                groupQuery = groupQuery.Where(x => x.GroupType.ShowInGroupList);
            }

            var groupKeys = groupQuery.Select(x => x.Id);

            //
            // Construct the Query to return the list of Group Members matching the filter conditions.
            //
            var groupMemberQuery = new GroupMemberService(context).Queryable();

            // Filter By Group.
            groupMemberQuery = groupMemberQuery.Where(gm => groupKeys.Contains(gm.GroupId));

            var selectExpression = FilterExpressionExtractor.Extract <Model.GroupMember>(groupMemberQuery, parameterExpression, "gm");

            return(selectExpression);
        }
Example #20
0
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entityIdProperty">The entity identifier property.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override Expression GetExpression(RockContext context, MemberExpression entityIdProperty, string selection)
        {
            var settings = new GroupParticipationSelectSettings(selection);

            //
            // Define Candidate Groups.
            //

            // Get the Group Data View that defines the set of candidates from which matching Groups can be selected.
            var dataView = DataComponentSettingsHelper.GetDataViewForFilterComponent(settings.DataViewGuid, context);

            // Evaluate the Data View that defines the candidate Groups.
            var groupService = new GroupService(context);

            var groupQuery = groupService.Queryable();

            if (dataView != null)
            {
                groupQuery = DataComponentSettingsHelper.FilterByDataView(groupQuery, dataView, groupService);
            }
            else
            {
                // Apply a default Group filter to only show Groups that would be visible in a Group List.
                groupQuery = groupQuery.Where(x => x.GroupType.ShowInGroupList);
            }

            var groupKeys = groupQuery.Select(x => x.Id);

            //
            // Construct the Query to return the list of Group Members matching the filter conditions.
            //
            var groupMemberQuery = new GroupMemberService(context).Queryable();

            // Filter By Group.
            groupMemberQuery = groupMemberQuery.Where(x => groupKeys.Contains(x.GroupId));

            // Filter By Group Role Type.
            switch (settings.RoleType)
            {
            case RoleTypeSpecifier.Member:
                groupMemberQuery = groupMemberQuery.Where(x => !x.GroupRole.IsLeader);
                break;

            case RoleTypeSpecifier.Leader:
                groupMemberQuery = groupMemberQuery.Where(x => x.GroupRole.IsLeader);
                break;
            }

            // Filter by Group Member Status.
            if (settings.MemberStatus.HasValue)
            {
                groupMemberQuery = groupMemberQuery.Where(x => x.GroupMemberStatus == settings.MemberStatus.Value);
            }

            //
            // Create a Select Expression to return the requested values.
            //

            // Set the Output Format of the field.
            Expression selectExpression;

            if (settings.ListFormat == ListFormatSpecifier.YesNo)
            {
                // Define a Query to return True/False text indicating if the Person participates in any of the filtered Groups.
                // Note that the text must be returned as an Enumerable to satisfy the expected output of this field.
                var personGroupsQuery = new PersonService(context).Queryable()
                                        .Select(p => new List <string> {
                    groupMemberQuery.Any(s => s.PersonId == p.Id) ? "Yes" : "No"
                });

                selectExpression = SelectExpressionExtractor.Extract(personGroupsQuery, entityIdProperty, "p");
            }
            else
            {
                // Define a Query to return the collection of filtered Groups for each Person.
                Expression <Func <Rock.Model.GroupMember, string> > outputExpression;

                if (settings.ListFormat == ListFormatSpecifier.GroupOnly)
                {
                    outputExpression = ((m => m.Group.Name));
                }
                else
                {
                    outputExpression = ((m => m.Group.Name + " [" + m.GroupRole.Name + "]"));
                }

                // Define a Query to return the collection of filtered Groups for each Person.
                var personGroupsQuery = new PersonService(context).Queryable()
                                        .Select(p => groupMemberQuery.Where(s => s.PersonId == p.Id)
                                                .OrderBy(x => x.Group.Name)
                                                .ThenBy(x => x.GroupRole.Name)
                                                .Select(outputExpression).AsEnumerable());

                selectExpression = SelectExpressionExtractor.Extract(personGroupsQuery, entityIdProperty, "p");
            }

            return(selectExpression);
        }
Example #21
0
        /// <summary>
        /// Executes the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        public void Execute(IJobExecutionContext context)
        {
            var errors      = new List <string>();
            var rockContext = new RockContext();

            JobDataMap dataMap         = context.JobDetail.JobDataMap;
            Guid?      systemEmailGuid = dataMap.GetString("NotificationEmailTemplate").AsGuidOrNull();

            if (systemEmailGuid.HasValue)
            {
                var selectedGroupTypes = new List <Guid>();
                if (!string.IsNullOrWhiteSpace(dataMap.GetString("GroupTypes")))
                {
                    selectedGroupTypes = dataMap.GetString("GroupTypes").Split(',').Select(Guid.Parse).ToList();
                }

                var notificationOption = dataMap.GetString("NotifyParentLeaders").ConvertToEnum <NotificationOption>(NotificationOption.None);

                var accountAbilityGroupGuid = dataMap.GetString("AccountabilityGroup").AsGuid();

                var groupRequirementsQry = new GroupRequirementService(rockContext).Queryable();


                // get groups matching of the types provided
                GroupService groupService = new GroupService(rockContext);
                var          groups       = groupService.Queryable().AsNoTracking()
                                            .Where(g => selectedGroupTypes.Contains(g.GroupType.Guid) &&
                                                   g.IsActive == true &&
                                                   groupRequirementsQry.Any(a => (a.GroupId.HasValue && a.GroupId == g.Id) || (a.GroupTypeId.HasValue && a.GroupTypeId == g.GroupTypeId)));

                foreach (var group in groups)
                {
                    // check for members that don't meet requirements
                    var groupMembersWithIssues = groupService.GroupMembersNotMeetingRequirements(group, true);

                    if (groupMembersWithIssues.Count > 0)
                    {
                        // add issues to issue list
                        GroupsMissingRequirements groupMissingRequirements = new GroupsMissingRequirements();
                        groupMissingRequirements.Id   = group.Id;
                        groupMissingRequirements.Name = group.Name;
                        if (group.GroupType != null)
                        {
                            groupMissingRequirements.GroupTypeId   = group.GroupTypeId;
                            groupMissingRequirements.GroupTypeName = group.GroupType.Name;
                        }
                        groupMissingRequirements.AncestorPathName = groupService.GroupAncestorPathName(group.Id);

                        // get list of the group leaders
                        groupMissingRequirements.Leaders = group.Members
                                                           .Where(m => m.GroupRole.ReceiveRequirementsNotifications)
                                                           .Select(m => new GroupMemberResult
                        {
                            Id       = m.Id,
                            PersonId = m.PersonId,
                            FullName = m.Person.FullName
                        })
                                                           .ToList();


                        List <GroupMembersMissingRequirements> groupMembers = new List <GroupMembersMissingRequirements>();

                        foreach (var groupMemberIssue in groupMembersWithIssues)
                        {
                            GroupMembersMissingRequirements groupMember = new GroupMembersMissingRequirements();
                            groupMember.FullName        = groupMemberIssue.Key.Person.FullName;
                            groupMember.Id              = groupMemberIssue.Key.Id;
                            groupMember.PersonId        = groupMemberIssue.Key.PersonId;
                            groupMember.GroupMemberRole = groupMemberIssue.Key.GroupRole.Name;

                            List <MissingRequirement> missingRequirements = new List <MissingRequirement>();
                            foreach (var issue in groupMemberIssue.Value)
                            {
                                MissingRequirement missingRequirement = new MissingRequirement();
                                missingRequirement.Id             = issue.Key.GroupRequirement.GroupRequirementType.Id;
                                missingRequirement.Name           = issue.Key.GroupRequirement.GroupRequirementType.Name;
                                missingRequirement.Status         = issue.Key.MeetsGroupRequirement;
                                missingRequirement.OccurrenceDate = issue.Value;

                                switch (issue.Key.MeetsGroupRequirement)
                                {
                                case MeetsGroupRequirement.Meets:
                                    missingRequirement.Message = issue.Key.GroupRequirement.GroupRequirementType.PositiveLabel;
                                    break;

                                case MeetsGroupRequirement.MeetsWithWarning:
                                    missingRequirement.Message = issue.Key.GroupRequirement.GroupRequirementType.WarningLabel;
                                    break;

                                case MeetsGroupRequirement.NotMet:
                                    missingRequirement.Message = issue.Key.GroupRequirement.GroupRequirementType.NegativeLabel;
                                    break;
                                }

                                missingRequirements.Add(missingRequirement);
                            }

                            groupMember.MissingRequirements = missingRequirements;

                            groupMembers.Add(groupMember);
                        }
                        groupMissingRequirements.GroupMembersMissingRequirements = groupMembers;

                        _groupsMissingRequriements.Add(groupMissingRequirements);

                        // add leaders as people to notify
                        foreach (var leader in group.Members.Where(m => m.GroupRole.ReceiveRequirementsNotifications))
                        {
                            NotificationItem notification = new NotificationItem();
                            notification.GroupId = group.Id;
                            notification.Person  = leader.Person;
                            _notificationList.Add(notification);
                        }

                        // notify parents
                        if (notificationOption != NotificationOption.None)
                        {
                            var parentLeaders = new GroupMemberService(rockContext).Queryable("Person").AsNoTracking()
                                                .Where(m => m.GroupRole.ReceiveRequirementsNotifications);

                            if (notificationOption == NotificationOption.DirectParent)
                            {
                                // just the parent group
                                parentLeaders = parentLeaders.Where(m => m.GroupId == group.ParentGroupId);
                            }
                            else
                            {
                                // all parents in the hierarchy
                                var parentIds = groupService.GetAllAncestorIds(group.Id);
                                parentLeaders = parentLeaders.Where(m => parentIds.Contains(m.GroupId));
                            }

                            foreach (var parentLeader in parentLeaders.ToList())
                            {
                                NotificationItem parentNotification = new NotificationItem();
                                parentNotification.Person  = parentLeader.Person;
                                parentNotification.GroupId = group.Id;
                                _notificationList.Add(parentNotification);
                            }
                        }
                    }
                }

                // send out notifications
                int recipients             = 0;
                var notificationRecipients = _notificationList.GroupBy(p => p.Person.Id).ToList();
                foreach (var recipientId in notificationRecipients)
                {
                    var recipient = _notificationList.Where(n => n.Person.Id == recipientId.Key).Select(n => n.Person).FirstOrDefault();

                    if (!recipient.IsEmailActive || recipient.Email.IsNullOrWhiteSpace() || recipient.EmailPreference == EmailPreference.DoNotEmail)
                    {
                        continue;
                    }

                    var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null);
                    mergeFields.Add("Person", recipient);
                    var notificationGroupIds = _notificationList
                                               .Where(n => n.Person.Id == recipient.Id)
                                               .Select(n => n.GroupId)
                                               .ToList();
                    var missingRequirements = _groupsMissingRequriements.Where(g => notificationGroupIds.Contains(g.Id)).ToList();
                    mergeFields.Add("GroupsMissingRequirements", missingRequirements);

                    var emailMessage = new RockEmailMessage(systemEmailGuid.Value);
                    emailMessage.AddRecipient(new RecipientData(recipient.Email, mergeFields));
                    var emailErrors = new List <string>();
                    emailMessage.Send(out emailErrors);
                    errors.AddRange(emailErrors);

                    recipients++;
                }

                // add accountability group members
                if (!accountAbilityGroupGuid.IsEmpty())
                {
                    var accountabilityGroupMembers = new GroupMemberService(rockContext).Queryable().AsNoTracking()
                                                     .Where(m => m.Group.Guid == accountAbilityGroupGuid)
                                                     .Select(m => m.Person);

                    var emailMessage = new RockEmailMessage(systemEmailGuid.Value);
                    foreach (var person in accountabilityGroupMembers)
                    {
                        var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null);
                        mergeFields.Add("Person", person);
                        mergeFields.Add("GroupsMissingRequirements", _groupsMissingRequriements);
                        emailMessage.AddRecipient(new RecipientData(person.Email, mergeFields));
                        recipients++;
                    }
                    var emailErrors = new List <string>();
                    emailMessage.Send(out emailErrors);
                    errors.AddRange(emailErrors);
                }

                context.Result = string.Format("{0} requirement notification {1} sent", recipients, "email".PluralizeIf(recipients != 1));

                if (errors.Any())
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine();
                    sb.Append(string.Format("{0} Errors: ", errors.Count()));
                    errors.ForEach(e => { sb.AppendLine(); sb.Append(e); });
                    string errorMessage = sb.ToString();
                    context.Result += errorMessage;
                    var         exception = new Exception(errorMessage);
                    HttpContext context2  = HttpContext.Current;
                    ExceptionLogService.LogException(exception, context2);
                    throw exception;
                }
            }
            else
            {
                context.Result = "Warning: No NotificationEmailTemplate found";
            }
        }
Example #22
0
        /// <summary>
        /// Maps the family address.
        /// </summary>
        /// <param name="tableData">The table data.</param>
        /// <param name="totalRows">The total rows.</param>
        private void MapFamilyAddress(IQueryable <Row> tableData, long totalRows = 0)
        {
            var lookupContext   = new RockContext();
            var locationService = new LocationService(lookupContext);

            var familyGroupMemberList = new GroupMemberService(lookupContext).Queryable().AsNoTracking()
                                        .Where(gm => gm.Group.GroupType.Guid.Equals(new Guid(Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY))).ToList();

            var customLocationTypes = DefinedTypeCache.Read(new Guid(Rock.SystemGuid.DefinedType.GROUP_LOCATION_TYPE), lookupContext).DefinedValues;

            const string otherGroupLocationName   = "Other (Imported)";
            var          otherGroupLocationTypeId = customLocationTypes.Where(dv => dv.TypeName == otherGroupLocationName)
                                                    .Select(v => (int?)v.Id).FirstOrDefault();

            if (!otherGroupLocationTypeId.HasValue)
            {
                var otherGroupLocationType = AddDefinedValue(lookupContext, Rock.SystemGuid.DefinedType.GROUP_LOCATION_TYPE, otherGroupLocationName);
                customLocationTypes.Add(otherGroupLocationType);
                otherGroupLocationTypeId = otherGroupLocationType.Id;
            }

            var newGroupLocations = new List <GroupLocation>();

            if (totalRows == 0)
            {
                totalRows = tableData.Count();
            }

            var completed  = 0;
            var percentage = (totalRows - 1) / 100 + 1;

            ReportProgress(0, $"Verifying address import ({totalRows:N0} found).");

            foreach (var row in tableData.Where(r => r != null))
            {
                var individualId = row["Individual_ID"] as int?;
                var householdId  = row["Household_ID"] as int?;
                var personKeys   = GetPersonKeys(individualId, householdId, includeVisitors: false);
                if (personKeys != null)
                {
                    var familyGroup = familyGroupMemberList.Where(gm => gm.PersonId == personKeys.PersonId)
                                      .Select(gm => gm.Group).FirstOrDefault();

                    if (familyGroup != null)
                    {
                        var groupLocation = new GroupLocation();

                        var street1 = row["Address_1"] as string;
                        var street2 = row["Address_2"] as string;
                        var city    = row["City"] as string;
                        var state   = row["State"] as string;
                        var country = row["country"] as string; // NOT A TYPO: F1 has property in lower-case
                        var zip     = row["Postal_Code"] as string ?? string.Empty;

                        // restrict zip to 5 places to prevent duplicates
                        var familyAddress = locationService.Get(street1, street2, city, state, zip.Left(5), country, verifyLocation: false);

                        if (familyAddress != null)
                        {
                            familyAddress.CreatedByPersonAliasId = ImportPersonAliasId;
                            familyAddress.Name     = familyGroup.Name;
                            familyAddress.IsActive = true;

                            groupLocation.GroupId           = familyGroup.Id;
                            groupLocation.LocationId        = familyAddress.Id;
                            groupLocation.IsMailingLocation = false;
                            groupLocation.IsMappedLocation  = false;

                            var addressType = row["Address_Type"].ToString();
                            if (addressType.Equals("Primary", StringComparison.CurrentCultureIgnoreCase))
                            {
                                groupLocation.GroupLocationTypeValueId = HomeLocationTypeId;
                                groupLocation.IsMailingLocation        = true;
                                groupLocation.IsMappedLocation         = true;
                            }
                            else if (addressType.Equals("Business", StringComparison.CurrentCultureIgnoreCase) || addressType.StartsWith("Org", StringComparison.CurrentCultureIgnoreCase))
                            {
                                groupLocation.GroupLocationTypeValueId = WorkLocationTypeId;
                            }
                            else if (addressType.Equals("Previous", StringComparison.CurrentCultureIgnoreCase))
                            {
                                groupLocation.GroupLocationTypeValueId = PreviousLocationTypeId;
                            }
                            else if (!string.IsNullOrWhiteSpace(addressType))
                            {
                                // look for existing group location types, otherwise mark as imported
                                var customTypeId = customLocationTypes.Where(dv => dv.Value.Equals(addressType, StringComparison.CurrentCultureIgnoreCase))
                                                   .Select(dv => (int?)dv.Id).FirstOrDefault();
                                groupLocation.GroupLocationTypeValueId = customTypeId ?? otherGroupLocationTypeId;
                            }

                            newGroupLocations.Add(groupLocation);
                            completed++;

                            if (completed % percentage < 1)
                            {
                                var percentComplete = completed / percentage;
                                ReportProgress(percentComplete, $"{completed:N0} addresses imported ({percentComplete}% complete).");
                            }
                            else if (completed % ReportingNumber < 1)
                            {
                                SaveFamilyAddress(newGroupLocations);

                                // Reset context
                                newGroupLocations.Clear();
                                lookupContext   = new RockContext();
                                locationService = new LocationService(lookupContext);

                                ReportPartialProgress();
                            }
                        }
                    }
                }
            }

            if (newGroupLocations.Any())
            {
                SaveFamilyAddress(newGroupLocations);
            }

            ReportProgress(100, $"Finished address import: {completed:N0} addresses imported.");
        }
Example #23
0
        /// <summary>
        /// Job that will sync groups.
        ///
        /// Called by the <see cref="IScheduler" /> when a
        /// <see cref="ITrigger" /> fires that is associated with
        /// the <see cref="IJob" />.
        /// </summary>
        public virtual void Execute(IJobExecutionContext context)
        {
            // Get the job setting(s)
            JobDataMap dataMap = context.JobDetail.JobDataMap;
            bool       requirePasswordReset = dataMap.GetBoolean("RequirePasswordReset");

            // Counters for displaying results
            int    groupsSynced  = 0;
            int    groupsChanged = 0;
            string groupName     = string.Empty;
            string dataViewName  = string.Empty;
            var    errors        = new List <string>();

            try
            {
                // get groups set to sync
                var activeSyncIds = new List <int>();
                using (var rockContext = new RockContext())
                {
                    activeSyncIds = new GroupSyncService(rockContext)
                                    .Queryable().AsNoTracking()
                                    .Select(x => x.Id)
                                    .ToList();
                }

                foreach (var syncId in activeSyncIds)
                {
                    bool hasSyncChanged = false;

                    // Use a fresh rockContext per syc so that ChangeTracker doesn't get bogged down
                    using (var rockContext = new RockContext())
                    {
                        // increase the timeout just in case the dataview source is slow
                        rockContext.Database.CommandTimeout = 180;
                        rockContext.SourceOfChange          = "Group Sync";

                        // Get the Sync
                        var sync = new GroupSyncService(rockContext)
                                   .Queryable().AsNoTracking()
                                   .FirstOrDefault(s => s.Id == syncId);

                        // Ensure that the group's Sync Data View is a person dataview
                        if (sync != null && sync.SyncDataView.EntityTypeId == EntityTypeCache.Get(typeof(Person)).Id)
                        {
                            List <string> syncErrors = new List <string>();

                            dataViewName = sync.SyncDataView.Name;
                            groupName    = sync.Group.Name;

                            // Get the person id's from the dataview (source)
                            var personService       = new PersonService(rockContext);
                            var parameterExpression = personService.ParameterExpression;
                            var whereExpression     = sync.SyncDataView.GetExpression(personService, parameterExpression, out syncErrors);
                            var sourcePersonIds     = new PersonService(rockContext)
                                                      .Get(parameterExpression, whereExpression)
                                                      .Select(q => q.Id)
                                                      .ToList();

                            // If any error occurred, just skip this sync for now.
                            if (syncErrors.Count > 0)
                            {
                                errors.AddRange(syncErrors);
                                ExceptionLogService.LogException(new Exception(string.Format("An error occurred while trying to GroupSync group '{0}' and data view '{1}' so the sync was skipped. Error: {2}", groupName, dataViewName, String.Join(",", syncErrors))));
                                continue;
                            }

                            // Get the person id's in the group (target)
                            var targetPersonIds = new GroupMemberService(rockContext)
                                                  .Queryable().AsNoTracking()
                                                  .Where(gm => gm.GroupId == sync.GroupId)
                                                  .Select(gm => gm.PersonId)
                                                  .ToList();

                            // Delete people from the group/role that are no longer in the dataview
                            foreach (var personId in targetPersonIds.Where(t => !sourcePersonIds.Contains(t)))
                            {
                                // Use a new context to limit the amount of change-tracking required
                                using (var groupMemberContext = new RockContext())
                                {
                                    // Delete any group members for the role with the person id
                                    var groupMemberService = new GroupMemberService(groupMemberContext);
                                    foreach (var groupMember in groupMemberService
                                             .Queryable()
                                             .Where(m =>
                                                    m.GroupId == sync.GroupId &&
                                                    m.GroupRoleId == sync.GroupTypeRoleId &&
                                                    m.PersonId == personId)
                                             .ToList())
                                    {
                                        groupMemberService.Delete(groupMember);
                                    }

                                    groupMemberContext.SaveChanges();

                                    // If the Group has an exit email, and person has an email address, send them the exit email
                                    if (sync.ExitSystemEmail != null)
                                    {
                                        var person = new PersonService(groupMemberContext).Get(personId);
                                        if (person.Email.IsNotNullOrWhiteSpace())
                                        {
                                            // Send the exit email
                                            var mergeFields = new Dictionary <string, object>();
                                            mergeFields.Add("Group", sync.Group);
                                            mergeFields.Add("Person", person);
                                            var emailMessage = new RockEmailMessage(sync.ExitSystemEmail);
                                            emailMessage.AddRecipient(new RecipientData(person.Email, mergeFields));
                                            var emailErrors = new List <string>();
                                            emailMessage.Send(out emailErrors);
                                            errors.AddRange(emailErrors);
                                        }
                                    }
                                }

                                hasSyncChanged = true;
                            }

                            foreach (var personId in sourcePersonIds.Where(s => !targetPersonIds.Contains(s)))
                            {
                                // Use a new context to limit the amount of change-tracking required
                                using (var groupMemberContext = new RockContext())
                                {
                                    // Add new person to the group with the role specified in the sync
                                    var groupMemberService = new GroupMemberService(groupMemberContext);
                                    var newGroupMember     = new GroupMember {
                                        Id = 0
                                    };
                                    newGroupMember.PersonId          = personId;
                                    newGroupMember.GroupId           = sync.GroupId;
                                    newGroupMember.GroupMemberStatus = GroupMemberStatus.Active;
                                    newGroupMember.GroupRoleId       = sync.GroupTypeRoleId;
                                    groupMemberService.Add(newGroupMember);
                                    groupMemberContext.SaveChanges();

                                    // If the Group has a welcome email, and person has an email address, send them the welcome email and possibly create a login
                                    if (sync.WelcomeSystemEmail != null)
                                    {
                                        var person = new PersonService(groupMemberContext).Get(personId);
                                        if (person.Email.IsNotNullOrWhiteSpace())
                                        {
                                            // If the group is configured to add a user account for anyone added to the group, and person does not yet have an
                                            // account, add one for them.
                                            string newPassword = string.Empty;
                                            bool   createLogin = sync.AddUserAccountsDuringSync;

                                            // Only create a login if requested, no logins exist and we have enough information to generate a username.
                                            if (createLogin && !person.Users.Any() && !string.IsNullOrWhiteSpace(person.NickName) && !string.IsNullOrWhiteSpace(person.LastName))
                                            {
                                                newPassword = System.Web.Security.Membership.GeneratePassword(9, 1);
                                                string username = Rock.Security.Authentication.Database.GenerateUsername(person.NickName, person.LastName);

                                                UserLogin login = UserLoginService.Create(
                                                    groupMemberContext,
                                                    person,
                                                    AuthenticationServiceType.Internal,
                                                    EntityTypeCache.Get(Rock.SystemGuid.EntityType.AUTHENTICATION_DATABASE.AsGuid()).Id,
                                                    username,
                                                    newPassword,
                                                    true,
                                                    requirePasswordReset);
                                            }

                                            // Send the welcome email
                                            var mergeFields = new Dictionary <string, object>();
                                            mergeFields.Add("Group", sync.Group);
                                            mergeFields.Add("Person", person);
                                            mergeFields.Add("NewPassword", newPassword);
                                            mergeFields.Add("CreateLogin", createLogin);
                                            var emailMessage = new RockEmailMessage(sync.WelcomeSystemEmail);
                                            emailMessage.AddRecipient(new RecipientData(person.Email, mergeFields));
                                            var emailErrors = new List <string>();
                                            emailMessage.Send(out emailErrors);
                                            errors.AddRange(emailErrors);
                                        }
                                    }
                                }

                                hasSyncChanged = true;
                            }

                            // Increment Groups Changed Counter (if people were deleted or added to the group)
                            if (hasSyncChanged)
                            {
                                groupsChanged++;
                            }

                            // Increment the Groups Synced Counter
                            groupsSynced++;
                        }
                    }
                }

                // Format the result message
                var resultMessage = string.Empty;
                if (groupsSynced == 0)
                {
                    resultMessage = "No groups to sync";
                }
                else if (groupsSynced == 1)
                {
                    resultMessage = "1 group was sync'ed";
                }
                else
                {
                    resultMessage = string.Format("{0} groups were sync'ed", groupsSynced);
                }

                resultMessage += string.Format(" and {0} groups were changed", groupsChanged);

                if (errors.Any())
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine();
                    sb.Append("Errors: ");
                    errors.ForEach(e => { sb.AppendLine(); sb.Append(e); });
                    string errorMessage = sb.ToString();
                    resultMessage += errorMessage;
                    throw new Exception(errorMessage);
                }

                context.Result = resultMessage;
            }
            catch (System.Exception ex)
            {
                HttpContext context2 = HttpContext.Current;
                ExceptionLogService.LogException(ex, context2);
                throw;
            }
        }
Example #24
0
        /// <summary>
        /// Updates the note watch notification digest.
        /// </summary>
        /// <param name="personIdNotificationDigestList">The person identifier notification digest list.</param>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="noteId">The note identifier.</param>
        private void UpdateNoteWatchNotificationDigest(Dictionary <int, NoteWatchPersonToNotifyList> personIdNotificationDigestList, RockContext rockContext, int noteId)
        {
            var noteService = new Rock.Model.NoteService(rockContext);

            var note = noteService.Queryable().Include(a => a.EditedByPersonAlias).FirstOrDefault(a => a.Id == noteId);

            if (note == null || !note.EntityId.HasValue)
            {
                // shouldn't' happen
                return;
            }

            var noteType = NoteTypeCache.Get(note.NoteTypeId);

            // make sure the note's notetype has an EntityTypeId (is should, but just in case it doesn't)
            int?noteEntityTypeId = noteType?.EntityTypeId;

            if (!noteEntityTypeId.HasValue)
            {
                return;
            }

            var noteWatchService = new Rock.Model.NoteWatchService(rockContext);

            // narrow it down to NoteWatches for the same EntityType as the Note
            var noteWatchesQuery = noteWatchService.Queryable()
                                   .Where(a =>
                                          (a.EntityTypeId.HasValue && a.EntityTypeId.Value == noteEntityTypeId.Value) ||
                                          (a.NoteTypeId.HasValue && a.NoteType.EntityTypeId == noteEntityTypeId));

            // narrow it down to either note watches on..
            // 1) specific Entity
            // 2) specific Note
            // 3) any note of the NoteType
            // 4) any note on the EntityType

            // specific Entity
            noteWatchesQuery = noteWatchesQuery.Where(a =>
                                                      (a.EntityId == null) ||
                                                      (note.EntityId.HasValue && a.EntityId.Value == note.EntityId.Value));

            // or specifically for this Note's ParentNote (a reply to the Note)
            noteWatchesQuery = noteWatchesQuery.Where(a =>
                                                      (a.NoteId == null) ||
                                                      (note.ParentNoteId.HasValue && a.NoteId.Value == note.ParentNoteId));

            // or specifically for this note's note type
            noteWatchesQuery = noteWatchesQuery.Where(a =>
                                                      (a.NoteTypeId == null) ||
                                                      (a.NoteTypeId.Value == note.NoteTypeId));

            // if there are any NoteWatches that relate to this note, process them
            if (noteWatchesQuery.Any())
            {
                var noteWatchesForNote = noteWatchesQuery.Include(a => a.WatcherPersonAlias.Person).AsNoTracking().ToList();
                List <NoteWatchPersonToNotify> noteWatchPersonToNotifyListAll = new List <NoteWatchPersonToNotify>();

                // loop thru Watches to get a list of people to possibly notify/override
                foreach (var noteWatch in noteWatchesForNote)
                {
                    // if a specific person is the watcher, add them
                    var watcherPerson = noteWatch.WatcherPersonAlias?.Person;
                    if (watcherPerson != null)
                    {   // Since this is iterated do not add the person to the list if they are already there.
                        var exists = noteWatchPersonToNotifyListAll.Where(p => p.Person.Email.Contains(watcherPerson.Email)).Any();
                        if (!exists)
                        {
                            noteWatchPersonToNotifyListAll.Add(new NoteWatchPersonToNotify(watcherPerson, note, noteWatch));
                        }
                    }

                    if (noteWatch.WatcherGroupId.HasValue)
                    {
                        var watcherPersonsFromGroup = new GroupMemberService(rockContext).Queryable()
                                                      .Where(a => a.GroupMemberStatus == GroupMemberStatus.Active && a.GroupId == noteWatch.WatcherGroupId.Value)
                                                      .Select(a => a.Person).ToList();

                        if (watcherPersonsFromGroup.Any())
                        {
                            // Do not add people from the group that are already added.
                            var distinctWatchers = watcherPersonsFromGroup.Where(wg => !noteWatchPersonToNotifyListAll.Where(w => w.Person.Email.Contains(wg.Email)).Any());
                            noteWatchPersonToNotifyListAll.AddRange(distinctWatchers.Select(a => new NoteWatchPersonToNotify(a, note, noteWatch)));
                        }
                    }
                }

                var noteWatchPersonToNotifyList = noteWatchPersonToNotifyListAll.Where(a => a.NoteWatch.IsWatching).ToList();
                var noteWatchPersonToNotifyListWatchDisabled = noteWatchPersonToNotifyListAll.Where(a => !a.NoteWatch.IsWatching).ToList();
                var noteWatchPersonToNotifyListNoOverride    = noteWatchPersonToNotifyList.Where(a => a.NoteWatch.AllowOverride == false).ToList();

                foreach (var noteWatchPersonToNotify in noteWatchPersonToNotifyList)
                {
                    // check if somebody wanted to specifically NOT watch this (and there isn't another watch that prevents overrides)
                    if (noteWatchPersonToNotifyListWatchDisabled.Any(a => a.Person.Id == noteWatchPersonToNotify.Person.Id))
                    {
                        // Person Requested to NOT watch, now make sure that they aren't force to watch based on Override = False
                        if (!noteWatchPersonToNotifyListNoOverride.Any(a => a.Person.Id == noteWatchPersonToNotify.Person.Id))
                        {
                            // person requested to NOT watch, and there aren't any overrides to prevent that, so jump out to the next one
                            continue;
                        }
                    }

                    NoteWatchPersonToNotifyList personToNotifyList;
                    if (personIdNotificationDigestList.ContainsKey(noteWatchPersonToNotify.Person.Id))
                    {
                        // This just create a place holder for the Note referring to item in the digest by key of person
                        personToNotifyList = personIdNotificationDigestList[noteWatchPersonToNotify.Person.Id] ?? new NoteWatchPersonToNotifyList(noteWatchPersonToNotify.Person);
                    }
                    else
                    {
                        // This just creates  a new place holder for the Note in the digest
                        personToNotifyList = new NoteWatchPersonToNotifyList(noteWatchPersonToNotify.Person);
                        personIdNotificationDigestList.Add(noteWatchPersonToNotify.Person.Id, personToNotifyList);
                    }

                    // Only include the note if the watcher person is authorized to view the note
                    if (noteWatchPersonToNotify.Note.IsAuthorized(Rock.Security.Authorization.VIEW, noteWatchPersonToNotify.Person))
                    {
                        // This is where the get added to the item of the digest
                        personToNotifyList.Add(noteWatchPersonToNotify);
                    }
                }
            }
        }
        protected void DoSQL()
        {
            int         SelectedCampusId   = cpCampus.SelectedValue.AsInteger();
            CampusCache SelectedCampus     = CampusCache.Read(SelectedCampusId);
            string      SelectedCampusName = SelectedCampus != null ? SelectedCampus.Name : "";

            var sunday     = DateTime.Today.SundayDate().AddDays(-6);
            var lastSunday = sunday.AddDays(-7);

            SundayDate = sunday.ToShortDateString();

            MetricValueService mvServ = new MetricValueService(rockContext);

            var metricValues    = SelectedCampusId == 0 ? mvServ.Queryable() : mvServ.Queryable().Where(mv => mv.MetricValuePartitions.Where(mvp => mvp.MetricPartition.EntityTypeId == 67).Select(mvp => mvp.EntityId).Contains(SelectedCampusId));
            var metric_Goal     = metricValues.Where(mv => mv.MetricValueType == MetricValueType.Goal);
            var metric_Measure  = metricValues.Where(mv => mv.MetricValueType == MetricValueType.Measure);
            var metric_LastWeek = metric_Measure.Where(mv => mv.MetricValueDateTime > lastSunday && mv.MetricValueDateTime <= sunday);


            //Attendance Last Week - All Environments
            int iAttendanceGoalCurrent = decimal.ToInt32(metric_Goal.Where(mv => new int[] { 2, 3, 4, 5 }.Contains(mv.MetricId) && mv.MetricValueDateTime.Value.Year == sunday.Year).Sum(mv => mv.YValue) ?? 0);
            int iAttendanceLastWeekAll = decimal.ToInt32(metric_LastWeek.Where(mv => new int[] { 2, 3, 4, 5 }.Contains(mv.MetricId)).Sum(mv => mv.YValue) ?? 0);
            int iAttendancePercent     = iAttendanceGoalCurrent != 0 ? ( int )((( double )iAttendanceLastWeekAll / iAttendanceGoalCurrent) * 100) : 0;

            AttendanceLastWeekAll = iAttendanceLastWeekAll.ToString();
            AttendancePercentage  = iAttendancePercent.ToString();

            AttendanceColor = GetColorForPercent(iAttendancePercent);

            //Attendance Last Week - Auditorium
            AttendanceLastWeekAud = decimal.ToInt32(metric_LastWeek.Where(mv => new int[] { 2 }.Contains(mv.MetricId)).Sum(mv => mv.YValue) ?? 0).ToString();

            //Attendance Last Week - Rainforest + Velocity
            AttendanceLastWeekChild = decimal.ToInt32(metric_LastWeek.Where(mv => new int[] { 3, 4 }.Contains(mv.MetricId)).Sum(mv => mv.YValue) ?? 0).ToString();

            //Attendance Last Week - The Collective
            AttendanceLastWeekStudent = decimal.ToInt32(metric_LastWeek.Where(mv => new int[] { 5 }.Contains(mv.MetricId)).Sum(mv => mv.YValue) ?? 0).ToString();


            //Comitments
            var commitStartDate = DateTime.Parse("2015-09-01");

            //First Time Commitments
            int iCommitments = decimal.ToInt32(metric_Measure.Where(mv => mv.MetricId == 12 && mv.MetricValueDateTime >= commitStartDate).Sum(mv => mv.YValue) ?? 0);

            Commitments = iCommitments.ToString();


            //Re-commitments
            int iRecommitments = decimal.ToInt32(metric_Measure.Where(mv => mv.MetricId == 13 && mv.MetricValueDateTime >= commitStartDate).Sum(mv => mv.YValue) ?? 0);

            Recommitments = iRecommitments.ToString();


            //TotalCommitments
            int iTotalCommitments       = decimal.ToInt32(metric_Measure.Where(mv => new int[] { 12, 13 }.Contains(mv.MetricId) && mv.MetricValueDateTime >= commitStartDate).Sum(mv => mv.YValue) ?? 0);
            int iTotalCommitmentGoal    = decimal.ToInt32(metric_Goal.Where(mv => new int[] { 12, 13 }.Contains(mv.MetricId) && mv.MetricValueDateTime.Value.Year == sunday.Year).Sum(mv => mv.YValue) ?? 0);
            int iTotalCommitmentPercent = iTotalCommitmentGoal != 0 ? ( int )((( double )iTotalCommitments / iTotalCommitmentGoal) * 100) : 0;

            AllCommitments            = iTotalCommitments.ToString();
            TotalCommitmentPercentage = iTotalCommitmentPercent.ToString();

            TotalCommitmentColor = GetColorForPercent(iTotalCommitmentPercent);


            //Involvement
            var groupMembers = new GroupMemberService(rockContext).Queryable().Where(gm => gm.Group.IsActive && gm.GroupMemberStatus == GroupMemberStatus.Active);

            if (SelectedCampusId != 0)
            {
                groupMembers = groupMembers.Where(gm => gm.Group.CampusId == SelectedCampusId);
            }

            //Small Group Leaders
            SmallGroupLeaders = groupMembers.Where(gm => gm.Group.GroupTypeId == 25 && gm.GroupRoleId == 24).DistinctBy(gm => gm.PersonId).Count().ToString();

            //Volunteers
            Volunteers = groupMembers.Where(gm => gm.Group.GroupTypeId == 42).DistinctBy(gm => gm.PersonId).Count().ToString();

            //Total Involvement
            Involvement = groupMembers.Where(gm => (gm.Group.GroupTypeId == 25 && gm.GroupRoleId == 24) || gm.Group.GroupTypeId == 42).DistinctBy(gm => gm.PersonId).Count().ToString();


            WorkflowService workServ = new WorkflowService(rockContext);

            var today = DateTime.Now;

            int iInactiveFollowupComplete;
            int iInactiveFollowupIncomplete;

            //Inactive Follow-up
            if (SelectedCampusId == 0)
            {
                iInactiveFollowupComplete = workServ.Queryable().Where(w => w.WorkflowTypeId == 120 && w.Status == "Completed" && w.ActivatedDateTime.Value.Year == today.Year && w.ActivatedDateTime.Value.Month == today.Month).Count();
            }
            else
            {
                iInactiveFollowupComplete = workServ.Queryable().Where(w => w.WorkflowTypeId == 120 && w.Status == "Completed" && w.ActivatedDateTime.Value.Year == today.Year && w.ActivatedDateTime.Value.Month == today.Month).WhereAttributeValue(rockContext, "Campus", SelectedCampusName).Count();
            }

            if (SelectedCampusId == 0)
            {
                iInactiveFollowupIncomplete = workServ.Queryable().Where(w => w.WorkflowTypeId == 120 && w.Status != "Completed" && w.ActivatedDateTime.Value.Year == today.Year && w.ActivatedDateTime.Value.Month == today.Month).Count();
            }
            else
            {
                iInactiveFollowupIncomplete = workServ.Queryable().Where(w => w.WorkflowTypeId == 120 && w.Status != "Completed" && w.ActivatedDateTime.Value.Year == today.Year && w.ActivatedDateTime.Value.Month == today.Month).WhereAttributeValue(rockContext, "Campus", SelectedCampusName).Count();
            }

            int iInactiveFollowup           = iInactiveFollowupComplete + iInactiveFollowupIncomplete;
            int iInactiveFollowupPercentage = iInactiveFollowup != 0 ? ( int )((( double )iInactiveFollowupComplete / iInactiveFollowup) * 100) : 0;

            InactiveFollowupComplete   = iInactiveFollowupComplete.ToString();
            InactiveFollowupIncomplete = iInactiveFollowupIncomplete.ToString();
            InactiveFollowup           = iInactiveFollowup.ToString();
            InactiveFollowupPercentage = iInactiveFollowupPercentage.ToString();

            InactiveFollowupColor = GetColorForPercent(iInactiveFollowupPercentage);
        }
Example #26
0
        /// <summary>
        /// Creates a Linq Expression that can be applied to an IQueryable to filter the result set.
        /// </summary>
        /// <param name="entityType">The type of entity in the result set.</param>
        /// <param name="serviceInstance">A service instance that can be queried to obtain the result set.</param>
        /// <param name="parameterExpression">The input parameter that will be injected into the filter expression.</param>
        /// <param name="selection">A formatted string representing the filter settings.</param>
        /// <returns>
        /// A Linq Expression that can be used to filter an IQueryable.
        /// </returns>
        public override Expression GetExpression(Type entityType, IService serviceInstance, ParameterExpression parameterExpression, string selection)
        {
            var settings = new SelectSettings(selection);

            var context = ( RockContext )serviceInstance.Context;

            //
            // Evaluate the Data View that defines the candidate Groups.
            //
            var dataView = DataComponentSettingsHelper.GetDataViewForFilterComponent(settings.DataViewGuid, context);

            var groupService = new GroupService(context);

            var groupQuery = groupService.Queryable();

            if (dataView != null)
            {
                groupQuery = DataComponentSettingsHelper.FilterByDataView(groupQuery, dataView, groupService);
            }
            else
            {
                // Apply a default Group filter to only show Groups that would be visible in a Group List.
                groupQuery = groupQuery.Where(x => x.GroupType.ShowInGroupList);
            }

            var groupKeys = groupQuery.Select(x => x.Id);

            //
            // Construct the Query to return the list of Group Members matching the filter conditions.
            //
            var groupMemberQuery = new GroupMemberService(context).Queryable();

            // Filter By Group.
            groupMemberQuery = groupMemberQuery.Where(x => groupKeys.Contains(x.GroupId));

            // Filter By Group Role Type.
            switch (settings.RoleType)
            {
            case RoleTypeSpecifier.Member:
                groupMemberQuery = groupMemberQuery.Where(x => !x.GroupRole.IsLeader);
                break;

            case RoleTypeSpecifier.Leader:
                groupMemberQuery = groupMemberQuery.Where(x => x.GroupRole.IsLeader);
                break;
            }

            // Filter by Group Member Status.
            if (settings.MemberStatus.HasValue)
            {
                groupMemberQuery = groupMemberQuery.Where(x => x.GroupMemberStatus == settings.MemberStatus.Value);
            }

            //
            // Create a Select Expression to return the Person records referenced by the Group Members.
            //
            var personGroupsQuery = new PersonService(context).Queryable()
                                    .Where(p => groupMemberQuery.Select(gm => gm.PersonId).Contains(p.Id));

            var selectExpression = FilterExpressionExtractor.Extract <Model.Person>(personGroupsQuery, parameterExpression, "p");

            return(selectExpression);
        }
Example #27
0
        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="entityIdProperty">The entity identifier property.</param>
        /// <param name="selection">The selection.</param>
        /// <returns></returns>
        public override Expression GetExpression(RockContext context, MemberExpression entityIdProperty, string selection)
        {
            var settings = new RelatedPeopleSelectSettings(selection);

            bool showRelationship = (settings.ListFormat == ListFormatSpecifier.NameAndRelationship);

            // Get Support Data.
            var adultGuid = GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT.AsGuid();
            var childGuid = GroupRole.GROUPROLE_FAMILY_MEMBER_CHILD.AsGuid();

            int familyGroupTypeId            = GroupTypeCache.Read(SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuid()).Id;
            int knownRelationshipGroupTypeId = GroupTypeCache.Read(SystemGuid.GroupType.GROUPTYPE_KNOWN_RELATIONSHIPS.AsGuid()).Id;

            //
            // Construct a Query to return the list of Related People matching the filter conditions.
            //
            IQueryable <RelatedPersonInfo> allRelatedPeopleQuery = null;

            // If we are looking for Parents...
            // Add the Adults from the Family Group in which the Principal participates as a Child.
            if (settings.FamilyRelationshipTypeGuids.Contains(FamilyRelationshipParentGuid.AsGuid()))
            {
                var familyMembersQuery = GetRelatedPeopleQuery(context, new List <int> {
                    familyGroupTypeId
                }, new List <Guid> {
                    childGuid
                }, new List <Guid> {
                    adultGuid
                }, showRelationship ? "Parent" : null);

                allRelatedPeopleQuery = GetRelatedPeopleUnionQuery(allRelatedPeopleQuery, familyMembersQuery);
            }

            // If we are looking for Children...
            // Add the Children from the Family Group in which the Principal participates as an Adult.
            if (settings.FamilyRelationshipTypeGuids.Contains(FamilyRelationshipChildGuid.AsGuid()))
            {
                var familyMembersQuery = GetRelatedPeopleQuery(context, new List <int> {
                    familyGroupTypeId
                }, new List <Guid> {
                    adultGuid
                }, new List <Guid> {
                    childGuid
                }, showRelationship ? "Child" : null);

                allRelatedPeopleQuery = GetRelatedPeopleUnionQuery(allRelatedPeopleQuery, familyMembersQuery);
            }

            // If we are looking for Siblings...
            // Add other Children from the Family Group in which the Principal participates as a Child.
            if (settings.FamilyRelationshipTypeGuids.Contains(FamilyRelationshipSiblingGuid.AsGuid()))
            {
                var familyMembersQuery = GetRelatedPeopleQuery(context, new List <int> {
                    familyGroupTypeId
                }, new List <Guid> {
                    childGuid
                }, new List <Guid> {
                    childGuid
                }, showRelationship ? "Sibling" : null);

                allRelatedPeopleQuery = GetRelatedPeopleUnionQuery(allRelatedPeopleQuery, familyMembersQuery);
            }

            // If we are looking for a Spouse...
            // Add other Married Adult in the Family Group in which the Principal participates as a Married Adult.
            if (settings.FamilyRelationshipTypeGuids.Contains(FamilyRelationshipSpouseGuid.AsGuid()))
            {
                var marriedStatusGuid = SystemGuid.DefinedValue.PERSON_MARITAL_STATUS_MARRIED.AsGuid();
                int marriedStatusId   = DefinedValueCache.Read(marriedStatusGuid).Id;

                var familyGroupMembers = new GroupMemberService(context).Queryable()
                                         .Where(m => m.Group.GroupTypeId == familyGroupTypeId);

                var personSpouseQuery = new PersonService(context).Queryable()
                                        .SelectMany(
                    p =>
                    familyGroupMembers.Where(gm => gm.PersonId == p.Id && gm.Person.MaritalStatusValueId == marriedStatusId && gm.GroupRole.Guid == adultGuid)
                    .SelectMany(gm => gm.Group.Members)
                    .Where(gm => gm.PersonId != p.Id && gm.GroupRole.Guid == adultGuid && gm.Person.MaritalStatusValueId == marriedStatusId)
                    .Select(
                        gm =>
                        new RelatedPersonInfo
                {
                    RelatedToPersonId = p.Id,
                    PersonId          = gm.Person.Id,
                    FirstName         = gm.Person.FirstName,
                    LastName          = gm.Person.LastName,
                    Suffix            = gm.Person.SuffixValue.Value,
                    RelationshipName  = showRelationship ? "Spouse" : null
                }));

                allRelatedPeopleQuery = GetRelatedPeopleUnionQuery(allRelatedPeopleQuery, personSpouseQuery);
            }

            // If we are looking for a Known Relationship...
            // Add other People from the Known Relationship Group having the specified Roles and in which the Principal is the Owner.
            if (settings.KnownRelationshipTypeGuids.Any())
            {
                var ownerGuid          = GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_OWNER.AsGuid();
                var principalRoleGuids = new List <Guid>();
                var targetRoleGuids    = new List <Guid>(settings.KnownRelationshipTypeGuids);

                principalRoleGuids.Add(ownerGuid);

                var knownPersonsQuery = GetRelatedPeopleQuery(context, new List <int> {
                    knownRelationshipGroupTypeId
                }, principalRoleGuids, targetRoleGuids, showRelationship ? "*" : null);

                allRelatedPeopleQuery = GetRelatedPeopleUnionQuery(allRelatedPeopleQuery, knownPersonsQuery);
            }

            //
            // Create a Select Expression to return the requested values.
            //
            var personQuery = new PersonService(context).Queryable().Select(p => allRelatedPeopleQuery.Where(rpi => rpi.RelatedToPersonId == p.Id).AsEnumerable());

            var selectExpression = SelectExpressionExtractor.Extract(personQuery, entityIdProperty, "p");

            return(selectExpression);
        }
Example #28
0
        /// <summary>
        /// Binds the grid.
        /// </summary>
        private void BindGrid()
        {
            // Find all the Group Types
            var groupTypeIds = GetAvailableGroupTypes();

            if (GetAttributeValue("DisplayFilter").AsBooleanOrNull() ?? false)
            {
                int?groupTypeFilter = gfSettings.GetUserPreference("Group Type").AsIntegerOrNull();
                if (groupTypeFilter.HasValue)
                {
                    groupTypeIds = groupTypeIds.Where(g => g == groupTypeFilter.Value).ToList();
                }
            }

            // filter to a specific group type if provided in the query string
            if (!string.IsNullOrWhiteSpace(RockPage.PageParameter("GroupTypeId")))
            {
                int?groupTypeId = RockPage.PageParameter("GroupTypeId").AsIntegerOrNull();

                if (groupTypeId.HasValue)
                {
                    groupTypeIds.Clear();
                    groupTypeIds.Add(groupTypeId.Value);
                }
            }

            var rockContext  = new RockContext();
            var groupService = new GroupService(rockContext);

            SortProperty sortProperty = gGroups.SortProperty;

            if (sortProperty == null)
            {
                sortProperty = new SortProperty(new GridViewSortEventArgs("Name", SortDirection.Ascending));
            }

            bool onlySecurityGroups = GetAttributeValue("LimittoSecurityRoleGroups").AsBoolean();

            var qryGroups = groupService.Queryable()
                            .Where(g => groupTypeIds.Contains(g.GroupTypeId) && (!onlySecurityGroups || g.IsSecurityRole));

            string limitToActiveStatus = GetAttributeValue("LimittoActiveStatus");

            bool showActive   = true;
            bool showInactive = true;

            if (limitToActiveStatus == "all" && gfSettings.Visible)
            {
                // Filter by active/inactive unless the block settings restrict it
                if (ddlActiveFilter.SelectedIndex > -1)
                {
                    switch (ddlActiveFilter.SelectedValue)
                    {
                    case "active":
                        showInactive = false;
                        break;

                    case "inactive":
                        showActive = false;
                        break;
                    }
                }
            }
            else if (limitToActiveStatus != "all")
            {
                // filter by the block setting for Active Status
                if (limitToActiveStatus == "active")
                {
                    showInactive = false;
                }
            }


            var groupTypePurposeValue = gfSettings.GetUserPreference("Group Type Purpose").AsIntegerOrNull();

            var groupList = new List <GroupListRowInfo>();

            // Person context will exist if used on a person detail page
            int personEntityTypeId = EntityTypeCache.Read("Rock.Model.Person").Id;

            if (ContextTypesRequired.Any(e => e.Id == personEntityTypeId))
            {
                var personContext = ContextEntity <Person>();
                if (personContext != null)
                {
                    // limit to Groups that the person is a member of
                    var qry = new GroupMemberService(rockContext).Queryable(true)
                              .Where(m => m.PersonId == personContext.Id)
                              .Join(qryGroups, gm => gm.GroupId, g => g.Id, (gm, g) => new { Group = g, GroupMember = gm });

                    // Filter by Active Status of Group and Group Membership.
                    if (showActive && !showInactive)
                    {
                        // Show only active Groups and active Memberships.
                        qry = qry.Where(gmg => gmg.Group.IsActive && gmg.GroupMember.GroupMemberStatus == GroupMemberStatus.Active);
                    }
                    else if (!showActive)
                    {
                        // Show only inactive Groups or inactive Memberships.
                        qry = qry.Where(gmg => !gmg.Group.IsActive || gmg.GroupMember.GroupMemberStatus == GroupMemberStatus.Inactive);
                    }

                    if (groupTypePurposeValue.HasValue && gfSettings.Visible)
                    {
                        qry = qry.Where(t => t.Group.GroupType.GroupTypePurposeValueId == groupTypePurposeValue);
                    }

                    groupList = qry
                                .AsEnumerable()
                                .Where(gm => gm.Group.IsAuthorized(Rock.Security.Authorization.VIEW, CurrentPerson))
                                .Select(m => new GroupListRowInfo
                    {
                        Id             = m.Group.Id,
                        Path           = string.Empty,
                        Name           = m.Group.Name,
                        GroupTypeName  = m.Group.GroupType.Name,
                        GroupOrder     = m.Group.Order,
                        GroupTypeOrder = m.Group.GroupType.Order,
                        Description    = m.Group.Description,
                        IsSystem       = m.Group.IsSystem,
                        GroupRole      = m.GroupMember.GroupRole.Name,
                        DateAdded      = m.GroupMember.DateTimeAdded ?? m.GroupMember.CreatedDateTime,
                        IsActive       = m.Group.IsActive && (m.GroupMember.GroupMemberStatus == GroupMemberStatus.Active),
                        IsActiveOrder  = (m.Group.IsActive && (m.GroupMember.GroupMemberStatus == GroupMemberStatus.Active) ? 1 : 2),
                        IsSynced       = m.Group.SyncDataViewId.HasValue,
                        MemberCount    = 0
                    })
                                .AsQueryable()
                                .Sort(sortProperty)
                                .ToList();
                }
            }
            else
            {
                var  roleGroupType   = GroupTypeCache.Read(Rock.SystemGuid.GroupType.GROUPTYPE_SECURITY_ROLE.AsGuid());
                int  roleGroupTypeId = roleGroupType != null ? roleGroupType.Id : 0;
                bool useRolePrefix   = onlySecurityGroups || groupTypeIds.Contains(roleGroupTypeId);

                if (!showInactive)
                {
                    qryGroups = qryGroups.Where(x => x.IsActive);
                }
                else if (!showActive)
                {
                    qryGroups = qryGroups.Where(x => !x.IsActive);
                }

                if (groupTypePurposeValue.HasValue && gfSettings.Visible)
                {
                    qryGroups = qryGroups.Where(t => t.GroupType.GroupTypePurposeValueId == groupTypePurposeValue);
                }

                groupList = qryGroups
                            .AsEnumerable()
                            .Where(g => g.IsAuthorized(Rock.Security.Authorization.VIEW, CurrentPerson))
                            .Select(g => new GroupListRowInfo
                {
                    Id             = g.Id,
                    Path           = string.Empty,
                    Name           = ((useRolePrefix && g.GroupType.Id != roleGroupTypeId) ? "GROUP - " : "") + g.Name,
                    GroupTypeName  = g.GroupType.Name,
                    GroupOrder     = g.Order,
                    GroupTypeOrder = g.GroupType.Order,
                    Description    = g.Description,
                    IsSystem       = g.IsSystem,
                    IsActive       = g.IsActive,
                    IsActiveOrder  = g.IsActive ? 1 : 2,
                    GroupRole      = string.Empty,
                    DateAdded      = DateTime.MinValue,
                    IsSynced       = g.SyncDataViewId.HasValue,
                    MemberCount    = g.Members.Count()
                })
                            .AsQueryable()
                            .Sort(sortProperty)
                            .ToList();
            }

            if (_showGroupPath)
            {
                foreach (var groupRow in groupList)
                {
                    groupRow.Path = groupService.GroupAncestorPathName(groupRow.Id);
                }
            }

            gGroups.DataSource   = groupList;
            gGroups.EntityTypeId = EntityTypeCache.Read <Group>().Id;
            gGroups.DataBind();

            // hide the group type column if there's only one type; must come after DataBind()
            if (_groupTypesCount == 1)
            {
                var groupTypeColumn = this.gGroups.ColumnsOfType <RockBoundField>().FirstOrDefault(a => a.DataField == "GroupTypeName");
                groupTypeColumn.Visible = false;
            }
        }
        /// <summary>
        /// Job that will sync groups.
        ///
        /// Called by the <see cref="IScheduler" /> when a
        /// <see cref="ITrigger" /> fires that is associated with
        /// the <see cref="IJob" />.
        /// </summary>
        public virtual void Execute(IJobExecutionContext context)
        {
            JobDataMap dataMap = context.JobDetail.JobDataMap;

            try
            {
                int notificationsSent   = 0;
                int errorsEncountered   = 0;
                int pendingMembersCount = 0;

                // get groups set to sync
                RockContext rockContext = new RockContext();

                Guid?groupTypeGuid       = dataMap.GetString("GroupType").AsGuidOrNull();
                Guid?systemEmailGuid     = dataMap.GetString("NotificationEmail").AsGuidOrNull();
                Guid?groupRoleFilterGuid = dataMap.GetString("GroupRoleFilter").AsGuidOrNull();
                int? pendingAge          = dataMap.GetString("PendingAge").AsIntegerOrNull();


                bool includePreviouslyNotificed = dataMap.GetString("IncludePreviouslyNotified").AsBoolean();

                // get system email
                SystemEmailService emailService = new SystemEmailService(rockContext);

                SystemEmail systemEmail = null;
                if (!systemEmailGuid.HasValue || systemEmailGuid == Guid.Empty)
                {
                    context.Result = "Job failed. Unable to find System Email";
                    throw new Exception("No system email found.");
                }

                systemEmail = emailService.Get(systemEmailGuid.Value);

                // get group members
                if (!groupTypeGuid.HasValue || groupTypeGuid == Guid.Empty)
                {
                    context.Result = "Job failed. Unable to find group type";
                    throw new Exception("No group type found");
                }

                var qry = new GroupMemberService(rockContext).Queryable("Person, Group, Group.Members.GroupRole")
                          .Where(m => m.Group.GroupType.Guid == groupTypeGuid.Value &&
                                 m.GroupMemberStatus == GroupMemberStatus.Pending);

                if (!includePreviouslyNotificed)
                {
                    qry = qry.Where(m => m.IsNotified == false);
                }

                if (groupRoleFilterGuid.HasValue)
                {
                    qry = qry.Where(m => m.GroupRole.Guid == groupRoleFilterGuid.Value);
                }

                if (pendingAge.HasValue && pendingAge.Value > 0)
                {
                    var ageDate = RockDateTime.Now.AddDays(pendingAge.Value * -1);
                    qry = qry.Where(m => m.ModifiedDateTime > ageDate);
                }

                var pendingGroupMembers = qry.ToList();

                var groups = pendingGroupMembers.GroupBy(m => m.Group);

                var errorList = new List <string>();
                foreach (var groupKey in groups)
                {
                    var group = groupKey.Key;

                    // get list of pending people
                    var qryPendingIndividuals = group.Members.Where(m => m.GroupMemberStatus == GroupMemberStatus.Pending);

                    if (!includePreviouslyNotificed)
                    {
                        qryPendingIndividuals = qryPendingIndividuals.Where(m => m.IsNotified == false);
                    }

                    if (groupRoleFilterGuid.HasValue)
                    {
                        qryPendingIndividuals = qryPendingIndividuals.Where(m => m.GroupRole.Guid == groupRoleFilterGuid.Value);
                    }

                    var pendingIndividuals = qryPendingIndividuals.Select(m => m.Person).ToList();

                    if (!pendingIndividuals.Any())
                    {
                        continue;
                    }

                    // get list of leaders
                    var groupLeaders = group.Members.Where(m => m.GroupRole.IsLeader == true && m.Person != null && m.Person.Email != null && m.Person.Email != string.Empty);

                    if (!groupLeaders.Any())
                    {
                        errorList.Add("Unable to send emails to members in group " + group.Name + " because there is no group leader");
                        continue;
                    }

                    var recipients = new List <RecipientData>();
                    foreach (var leader in groupLeaders)
                    {
                        // create merge object
                        var mergeFields = new Dictionary <string, object>();
                        mergeFields.Add("PendingIndividuals", pendingIndividuals);
                        mergeFields.Add("Group", group);
                        mergeFields.Add("ParentGroup", group.ParentGroup);
                        mergeFields.Add("Person", leader.Person);
                        recipients.Add(new RecipientData(leader.Person.Email, mergeFields));
                    }


                    var errorMessages = new List <string>();
                    var emailMessage  = new RockEmailMessage(systemEmail.Guid);
                    emailMessage.SetRecipients(recipients);
                    emailMessage.Send(out errorMessages);

                    errorsEncountered += errorMessages.Count;
                    errorList.AddRange(errorMessages);

                    // be conservative: only mark as notified if we are sure the email didn't fail
                    if (errorMessages.Any())
                    {
                        continue;
                    }

                    notificationsSent += recipients.Count();
                    // mark pending members as notified as we go in case the job fails
                    var notifiedPersonIds = pendingIndividuals.Select(p => p.Id);
                    foreach (var pendingGroupMember in pendingGroupMembers.Where(m => m.IsNotified == false && notifiedPersonIds.Contains(m.PersonId)))
                    {
                        pendingGroupMember.IsNotified = true;
                    }

                    rockContext.SaveChanges();
                }

                context.Result = string.Format("Sent {0} emails to leaders for {1} pending individuals. {2} errors encountered.", notificationsSent, pendingMembersCount, errorsEncountered);
                if (errorList.Any())
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine();
                    sb.Append("Errors: ");
                    errorList.ForEach(e => { sb.AppendLine(); sb.Append(e); });
                    string errors = sb.ToString();
                    context.Result += errors;
                    throw new Exception(errors);
                }
            }
            catch (Exception ex)
            {
                HttpContext context2 = HttpContext.Current;
                ExceptionLogService.LogException(ex, context2);
                throw;
            }
        }
        private void ListGroups()
        {
            RockContext rockContext = new RockContext();

            var qry = new GroupMemberService(rockContext)
                      .Queryable("Group");

            var parentGroupGuid = GetAttributeValue("ParentGroup").AsGuidOrNull();

            if (parentGroupGuid != null)
            {
                var availableGroupIds = (List <int>)GetCacheItem("GroupListPersonalizedLava:" + parentGroupGuid.ToString());

                if (availableGroupIds == null)
                {
                    var parentGroup = new GroupService(rockContext).Get(parentGroupGuid ?? new Guid());
                    if (parentGroup != null)
                    {
                        availableGroupIds = GetChildGroups(parentGroup).Select(g => g.Id).ToList();
                    }
                    else
                    {
                        availableGroupIds = new List <int>();
                    }
                    var    cacheLength = GetAttributeValue("CacheDuration").AsInteger();
                    string cacheTags   = GetAttributeValue("CacheTags") ?? string.Empty;
                    AddCacheItem("GroupListPersonalizedLava:" + parentGroupGuid.ToString(), availableGroupIds, cacheLength, cacheTags);
                }
                qry = qry.Where(m => availableGroupIds.Contains(m.GroupId));
            }

            qry = qry.Where(m => m.PersonId == CurrentPersonId &&
                            m.GroupMemberStatus == GroupMemberStatus.Active);

            if (_hideInactive)
            {
                qry = qry.Where(m => m.Group.IsActive == true && !m.Group.IsArchived);
            }

            List <Guid> includeGroupTypeGuids = GetAttributeValue("IncludeGroupTypes").SplitDelimitedValues().Select(a => Guid.Parse(a)).ToList();

            if (includeGroupTypeGuids.Count > 0)
            {
                qry = qry.Where(t => includeGroupTypeGuids.Contains(t.Group.GroupType.Guid));
            }

            List <Guid> excludeGroupTypeGuids = GetAttributeValue("ExcludeGroupTypes").SplitDelimitedValues().Select(a => Guid.Parse(a)).ToList();

            if (excludeGroupTypeGuids.Count > 0)
            {
                qry = qry.Where(t => !excludeGroupTypeGuids.Contains(t.Group.GroupType.Guid));
            }

            var groups = new List <GroupInvolvementSummary>();

            foreach (var groupMember in qry.ToList())
            {
                if (groupMember.Group.IsAuthorized(Authorization.VIEW, CurrentPerson))
                {
                    groups.Add(new GroupInvolvementSummary
                    {
                        Group     = groupMember.Group,
                        Role      = groupMember.GroupRole.Name,
                        IsLeader  = groupMember.GroupRole.IsLeader,
                        GroupType = groupMember.Group.GroupType.Name
                    });
                }
            }

            var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage, this.CurrentPerson);

            mergeFields.Add("Groups", groups);

            Dictionary <string, object> linkedPages = new Dictionary <string, object>();

            linkedPages.Add("DetailPage", LinkedPageRoute("DetailPage"));
            mergeFields.Add("LinkedPages", linkedPages);

            if (this.GetAttributeValue("DisplayInactiveGroups").AsBoolean())
            {
                mergeFields.Add("ShowInactive", this.GetAttributeValue("DisplayInactiveGroups"));
                mergeFields.Add("InitialActive", this.GetAttributeValue("InitialActiveSetting"));
                mergeFields.Add("InactiveParameter", this.GetAttributeValue("InactiveParameterName"));
            }

            string template = GetAttributeValue("LavaTemplate");

            lContent.Text = template.ResolveMergeFields(mergeFields);
        }