public void Execute(IJobExecutionContext context)
        {
            var rockContext = new RockContext();

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

            while (familyMembers.Any())
            {
                //Chunk to prevent foreach saving thread errors
                foreach (var chunk in familyMembers.OrderBy(f => f.Id).QueryChunksOfSize(100))
                {
                    foreach (var familyMember in chunk)
                    {
                        familyMember.Person.GivingGroupId = familyMember.GroupId;
                    }
                    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);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Loads the drop downs.
        /// </summary>
        private void LoadDropDowns(BenevolenceRequest benevolenceRequest)
        {
            ddlRequestStatus.BindToDefinedType(DefinedTypeCache.Read(new Guid(Rock.SystemGuid.DefinedType.BENEVOLENCE_REQUEST_STATUS)), false);
            ddlConnectionStatus.BindToDefinedType(DefinedTypeCache.Read(new Guid(Rock.SystemGuid.DefinedType.PERSON_CONNECTION_STATUS)), true);

            Guid groupGuid  = GetAttributeValue("CaseWorkerRole").AsGuid();
            var  personList = new GroupMemberService(new RockContext())
                              .Queryable("Person, Group")
                              .Where(gm => gm.Group.Guid == groupGuid)
                              .Select(gm => gm.Person)
                              .ToList();

            string caseWorkerPersonAliasValue = benevolenceRequest.CaseWorkerPersonAliasId.ToString();

            if (benevolenceRequest.CaseWorkerPersonAlias != null &&
                benevolenceRequest.CaseWorkerPersonAlias.Person != null &&
                !personList.Select(p => p.Id).ToList().Contains(benevolenceRequest.CaseWorkerPersonAlias.Person.Id))
            {
                personList.Add(benevolenceRequest.CaseWorkerPersonAlias.Person);
            }

            ddlCaseWorker.DataSource     = personList.OrderBy(p => p.NickName).ThenBy(p => p.LastName).ToList();
            ddlCaseWorker.DataTextField  = "FullName";
            ddlCaseWorker.DataValueField = "PrimaryAliasId";
            ddlCaseWorker.DataBind();
            ddlCaseWorker.Items.Insert(0, new ListItem());
        }
Esempio n. 3
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();
            }
        }
Esempio n. 4
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();
            }
        }
        /// <summary>
        /// Gets the GroupMember record for a person from the specified personId and groupId.
        /// If the person is in there more than once, prefer the IsLeader role.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="groupId">The group identifier.</param>
        /// <param name="personId">The person identifier.</param>
        /// <returns></returns>
        private GroupMember GetGroupMemberRecord(RockContext rockContext, int groupId, int personId)
        {
            var groupMemberQuery = new GroupMemberService(rockContext)
                                   .GetByGroupIdAndPersonId(groupId, personId);

            var groupMember = groupMemberQuery.OrderBy(a => a.GroupRole.IsLeader).FirstOrDefault();

            return(groupMember);
        }
Esempio n. 6
0
        /// <summary>
        /// Loads the drop downs.
        /// </summary>
        private void LoadDropDowns(BenevolenceRequest benevolenceRequest)
        {
            dvpRequestStatus.DefinedTypeId    = DefinedTypeCache.Get(new Guid(Rock.SystemGuid.DefinedType.BENEVOLENCE_REQUEST_STATUS)).Id;
            dvpConnectionStatus.DefinedTypeId = DefinedTypeCache.Get(new Guid(Rock.SystemGuid.DefinedType.PERSON_CONNECTION_STATUS)).Id;

            if (_caseWorkerGroupGuid.HasValue)
            {
                var personList = new GroupMemberService(new RockContext())
                                 .Queryable("Person, Group")
                                 .Where(gm => gm.Group.Guid == _caseWorkerGroupGuid.Value)
                                 .Select(gm => gm.Person)
                                 .ToList();

                string caseWorkerPersonAliasValue = benevolenceRequest.CaseWorkerPersonAliasId.ToString();
                if (benevolenceRequest.CaseWorkerPersonAlias != null &&
                    benevolenceRequest.CaseWorkerPersonAlias.Person != null &&
                    !personList.Select(p => p.Id).ToList().Contains(benevolenceRequest.CaseWorkerPersonAlias.Person.Id))
                {
                    personList.Add(benevolenceRequest.CaseWorkerPersonAlias.Person);
                }

                ddlCaseWorker.DataSource     = personList.OrderBy(p => p.NickName).ThenBy(p => p.LastName).ToList();
                ddlCaseWorker.DataTextField  = "FullName";
                ddlCaseWorker.DataValueField = "PrimaryAliasId";
                ddlCaseWorker.DataBind();
                ddlCaseWorker.Items.Insert(0, new ListItem());

                ppCaseWorker.Visible  = false;
                ddlCaseWorker.Visible = true;
            }
            else
            {
                ppCaseWorker.Visible  = true;
                ddlCaseWorker.Visible = false;
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Handles the ItemDataBound event of the rptrGroups control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.RepeaterItemEventArgs"/> instance containing the event data.</param>
        protected void rptrGroups_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                var group = e.Item.DataItem as Group;
                if (group != null)
                {
                    HyperLink hlEditGroup = e.Item.FindControl("hlEditGroup") as HyperLink;
                    if (hlEditGroup != null)
                    {
                        hlEditGroup.Visible = _allowEdit;
                        var pageParams = new Dictionary <string, string>();
                        pageParams.Add("PersonId", Person.Id.ToString());
                        pageParams.Add("GroupId", group.Id.ToString());
                        hlEditGroup.NavigateUrl = LinkedPageUrl(AttributeKey.GroupEditPage, pageParams);
                    }

                    var lReorderIcon = e.Item.FindControl("lReorderIcon") as Control;
                    lReorderIcon.Visible = _showReorderIcon;

                    Repeater rptrMembers = e.Item.FindControl("rptrMembers") as Repeater;
                    if (rptrMembers != null)
                    {
                        // use the _bindGroupsRockContext that is created/disposed in BindFamilies()
                        var members = new GroupMemberService(_bindGroupsRockContext).Queryable("GroupRole,Person", true)
                                      .Where(m =>
                                             m.GroupId == group.Id &&
                                             m.PersonId != Person.Id)
                                      .OrderBy(m => m.GroupRole.Order)
                                      .ToList();

                        var groupHeaderLava = GetAttributeValue(AttributeKey.GroupHeaderLava);
                        var groupFooterLava = GetAttributeValue(AttributeKey.GroupFooterLava);

                        if (groupHeaderLava.IsNotNullOrWhiteSpace() || groupFooterLava.IsNotNullOrWhiteSpace())
                        {
                            // add header and footer information
                            var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage, CurrentPerson, new Rock.Lava.CommonMergeFieldsOptions {
                                GetLegacyGlobalMergeFields = false
                            });
                            mergeFields.Add("Group", group);
                            mergeFields.Add("GroupMembers", members);

                            Literal lGroupHeader = e.Item.FindControl("lGroupHeader") as Literal;
                            Literal lGroupFooter = e.Item.FindControl("lGroupFooter") as Literal;

                            lGroupHeader.Text = groupHeaderLava.ResolveMergeFields(mergeFields);
                            lGroupFooter.Text = groupFooterLava.ResolveMergeFields(mergeFields);
                        }

                        var orderedMembers = new List <GroupMember>();

                        if (_IsFamilyGroupType)
                        {
                            // Add adult males
                            orderedMembers.AddRange(members
                                                    .Where(m => m.GroupRole.Guid.Equals(new Guid(Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT)) &&
                                                           m.Person.Gender == Gender.Male)
                                                    .OrderByDescending(m => m.Person.Age));

                            // Add adult females
                            orderedMembers.AddRange(members
                                                    .Where(m => m.GroupRole.Guid.Equals(new Guid(Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT)) &&
                                                           m.Person.Gender != Gender.Male)
                                                    .OrderByDescending(m => m.Person.Age));

                            // Add non-adults
                            orderedMembers.AddRange(members
                                                    .Where(m => !m.GroupRole.Guid.Equals(new Guid(Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT)))
                                                    .OrderByDescending(m => m.Person.Age));
                        }
                        else
                        {
                            orderedMembers = members
                                             .OrderBy(m => m.GroupRole.Order)
                                             .ThenBy(m => m.Person.LastName)
                                             .ThenBy(m => m.Person.NickName)
                                             .ToList();
                        }
                        rptrMembers.ItemDataBound += rptrMembers_ItemDataBound;
                        rptrMembers.DataSource     = orderedMembers;
                        rptrMembers.DataBind();
                    }

                    Repeater rptrAddresses = e.Item.FindControl("rptrAddresses") as Repeater;
                    if (rptrAddresses != null)
                    {
                        rptrAddresses.ItemDataBound += rptrAddresses_ItemDataBound;
                        rptrAddresses.ItemCommand   += rptrAddresses_ItemCommand;
                        rptrAddresses.DataSource     = new GroupLocationService(_bindGroupsRockContext).Queryable("Location,GroupLocationTypeValue")
                                                       .Where(l => l.GroupId == group.Id)
                                                       .OrderBy(l => l.GroupLocationTypeValue.Order)
                                                       .ToList();
                        rptrAddresses.DataBind();
                    }

                    Panel       pnlGroupAttributes    = e.Item.FindControl("pnlGroupAttributes") as Panel;
                    HyperLink   hlShowMoreAttributes  = e.Item.FindControl("hlShowMoreAttributes") as HyperLink;
                    PlaceHolder phGroupAttributes     = e.Item.FindControl("phGroupAttributes") as PlaceHolder;
                    PlaceHolder phMoreGroupAttributes = e.Item.FindControl("phMoreGroupAttributes") as PlaceHolder;

                    if (pnlGroupAttributes != null && hlShowMoreAttributes != null && phGroupAttributes != null && phMoreGroupAttributes != null)
                    {
                        hlShowMoreAttributes.Visible = false;
                        phGroupAttributes.Controls.Clear();
                        phMoreGroupAttributes.Controls.Clear();

                        group.LoadAttributes();
                        var attributes = group.GetAuthorizedAttributes(Authorization.VIEW, CurrentPerson)
                                         .Select(a => a.Value)
                                         .OrderBy(a => a.Order)
                                         .ToList();

                        foreach (var attribute in attributes)
                        {
                            if (attribute.IsAuthorized(Authorization.VIEW, CurrentPerson))
                            {
                                string value = attribute.DefaultValue;
                                if (group.AttributeValues.ContainsKey(attribute.Key) && group.AttributeValues[attribute.Key] != null)
                                {
                                    value = group.AttributeValues[attribute.Key].ValueFormatted;
                                }

                                if (!string.IsNullOrWhiteSpace(value))
                                {
                                    var literalControl = new RockLiteral();
                                    literalControl.ID    = string.Format("familyAttribute_{0}", attribute.Id);
                                    literalControl.Label = attribute.Name;
                                    literalControl.Text  = value;

                                    var div = new HtmlGenericControl("div");
                                    div.AddCssClass("col-md-3 col-sm-6");
                                    div.Controls.Add(literalControl);

                                    if (attribute.IsGridColumn)
                                    {
                                        phGroupAttributes.Controls.Add(div);
                                    }
                                    else
                                    {
                                        hlShowMoreAttributes.Visible = true;
                                        phMoreGroupAttributes.Controls.Add(div);
                                    }
                                }
                            }
                        }

                        pnlGroupAttributes.Visible = phGroupAttributes.Controls.Count > 0 || phMoreGroupAttributes.Controls.Count > 0;
                    }
                }
            }
        }
        /// <summary>
        /// Handles the ItemDataBound event of the rptrGroups control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.RepeaterItemEventArgs"/> instance containing the event data.</param>
        protected void rptrGroups_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                var group = e.Item.DataItem as Group;
                if (group != null)
                {
                    HyperLink hlEditGroup = e.Item.FindControl("hlEditGroup") as HyperLink;
                    if (hlEditGroup != null)
                    {
                        hlEditGroup.Visible = _allowEdit;
                        var pageParams = new Dictionary <string, string>();
                        pageParams.Add("PersonId", Person.Id.ToString());
                        pageParams.Add("GroupId", group.Id.ToString());
                        hlEditGroup.NavigateUrl = LinkedPageUrl("GroupEditPage", pageParams);
                    }

                    Literal lEditGroup = e.Item.FindControl("lEditGroup") as Literal;
                    if (lEditGroup != null)
                    {
                        lEditGroup.Text = "Edit " + _groupType.Name;
                    }

                    Repeater rptrMembers = e.Item.FindControl("rptrMembers") as Repeater;
                    if (rptrMembers != null)
                    {
                        // use the _bindGroupsRockContext that is created/disposed in BindFamilies()
                        var members = new GroupMemberService(_bindGroupsRockContext).Queryable("GroupRole,Person", true)
                                      .Where(m =>
                                             m.GroupId == group.Id &&
                                             m.PersonId != Person.Id)
                                      .OrderBy(m => m.GroupRole.Order)
                                      .ToList();

                        var orderedMembers = new List <GroupMember>();

                        if (_IsFamilyGroupType)
                        {
                            // Add adult males
                            orderedMembers.AddRange(members
                                                    .Where(m => m.GroupRole.Guid.Equals(new Guid(Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT)) &&
                                                           m.Person.Gender == Gender.Male)
                                                    .OrderByDescending(m => m.Person.Age));

                            // Add adult females
                            orderedMembers.AddRange(members
                                                    .Where(m => m.GroupRole.Guid.Equals(new Guid(Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT)) &&
                                                           m.Person.Gender != Gender.Male)
                                                    .OrderByDescending(m => m.Person.Age));

                            // Add non-adults
                            orderedMembers.AddRange(members
                                                    .Where(m => !m.GroupRole.Guid.Equals(new Guid(Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT)))
                                                    .OrderByDescending(m => m.Person.Age));
                        }
                        else
                        {
                            orderedMembers = members
                                             .OrderBy(m => m.GroupRole.Order)
                                             .ThenBy(m => m.Person.LastName)
                                             .ThenBy(m => m.Person.NickName)
                                             .ToList();
                        }
                        rptrMembers.ItemDataBound += rptrMembers_ItemDataBound;
                        rptrMembers.DataSource     = orderedMembers;
                        rptrMembers.DataBind();
                    }

                    Repeater rptrAddresses = e.Item.FindControl("rptrAddresses") as Repeater;
                    {
                        rptrAddresses.ItemDataBound += rptrAddresses_ItemDataBound;
                        rptrAddresses.ItemCommand   += rptrAddresses_ItemCommand;
                        rptrAddresses.DataSource     = new GroupLocationService(_bindGroupsRockContext).Queryable("Location,GroupLocationTypeValue")
                                                       .Where(l => l.GroupId == group.Id)
                                                       .OrderBy(l => l.GroupLocationTypeValue.Order)
                                                       .ToList();
                        rptrAddresses.DataBind();
                    }
                }
            }
        }
Esempio n. 9
0
        /// <summary>
        /// Binds the group members grid.
        /// </summary>
        /// <remarks>Multiple methods depend on the GroupMember object type</remarks>
        /// <param name="isExporting">if set to <c>true</c> [is exporting].</param>
        protected void BindGroupMembersGrid(bool isExporting = false)
        {
            if (_group != null && _group.GroupType.Roles.Any())
            {
                pnlGroupMembers.Visible = true;

                using (var rockContext = new RockContext())
                {
                    // Start query for group members
                    var qry = new GroupMemberService(rockContext)
                              .Queryable("Person,GroupRole", true)
                              .Where(m => m.GroupId == _group.Id && m.Person != null);

                    // Sort the query
                    IOrderedQueryable <GroupMember> orderedQry = null;
                    var sortProperty = pnlGroupMembers.SortProperty;
                    if (sortProperty != null)
                    {
                        orderedQry = qry.Sort(sortProperty);
                    }
                    else
                    {
                        orderedQry = qry
                                     .OrderBy(r => r.Person.LastName)
                                     .ThenBy(r => r.Person.NickName);
                    }

                    // increase the timeout just in case. A complex filter on the grid might slow things down
                    rockContext.Database.CommandTimeout = 180;

                    // Set the grids LinqDataSource which will run query and set results for current page
                    pnlGroupMembers.SetLinqDataSource(orderedQry);

                    var homePhoneType = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_HOME);
                    var cellPhoneType = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_MOBILE);

                    var groupAttributes = GetGroupAttributes();
                    if (groupAttributes.Any())
                    {
                        // Get the query results for the current page
                        var currentGroupMembers = pnlGroupMembers.DataSource as List <GroupMember>;
                        if (currentGroupMembers != null)
                        {
                            // Get all the person ids in current page of query results
                            var personIds = currentGroupMembers
                                            .Select(r => r.PersonId)
                                            .Distinct()
                                            .ToList();

                            var groupMemberIds = currentGroupMembers
                                                 .Select(r => r.Id)
                                                 .Distinct()
                                                 .ToList();

                            var groupMemberAttributesIds = groupAttributes.Select(a => a.Id).Distinct().ToList();

                            // If there are any attributes that were selected to be displayed, we're going
                            // to try and read all attribute values in one query and then put them into a
                            // custom grid ObjectList property so that the AttributeField columns don't need
                            // to do the LoadAttributes and querying of values for each row/column
                            if (groupMemberAttributesIds.Any())
                            {
                                // Query the attribute values for all rows and attributes
                                var attributeValues = new AttributeValueService(rockContext)
                                                      .Queryable("Attribute").AsNoTracking()
                                                      .Where(v =>
                                                             v.EntityId.HasValue &&
                                                             groupMemberAttributesIds.Contains(v.AttributeId) &&
                                                             groupMemberIds.Contains(v.EntityId.Value)
                                                             )
                                                      .ToList();

                                // Get the attributes to add to each row's object
                                var attributes = new Dictionary <string, AttributeCache>();
                                groupAttributes.ForEach(a =>
                                                        attributes.Add(a.Id + a.Key, a));

                                // Initialize the grid's object list
                                pnlGroupMembers.ObjectList   = new Dictionary <string, object>();
                                pnlGroupMembers.EntityTypeId = EntityTypeCache.Get(Rock.SystemGuid.EntityType.GROUP_MEMBER.AsGuid()).Id;

                                // Loop through each of the current group's members and build an attribute
                                // field object for storing attributes and the values for each of the members
                                foreach (var groupMember in currentGroupMembers)
                                {
                                    // Create a row attribute object
                                    var attributeFieldObject = new AttributeFieldObject
                                    {
                                        // Add the attributes to the attribute object
                                        Attributes = attributes
                                    };

                                    // Add any group member attribute values to object
                                    if (groupMember.Id > 0)
                                    {
                                        attributeValues
                                        .Where(v =>
                                               groupMemberAttributesIds.Contains(v.AttributeId) &&
                                               v.EntityId.Value == groupMember.Id)
                                        .ToList()
                                        .ForEach(v => attributeFieldObject.AttributeValues
                                                 .Add(v.AttributeId + v.Attribute.Key, new AttributeValueCache(v)));
                                    }

                                    // Add row attribute object to grid's object list
                                    pnlGroupMembers.ObjectList.Add(groupMember.Id.ToString(), attributeFieldObject);
                                }
                            }
                        }
                    }

                    pnlGroupMembers.DataBind();
                }
            }
        }