/// <summary>
        /// Handles the Delete event of the gFollowings control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="RowEventArgs" /> instance containing the event data.</param>
        protected void gFollowings_Delete( object sender, RowEventArgs e )
        {
            var rockContext = new RockContext();
            var service = new FollowingService( rockContext );

            int personEntityTypeId = EntityTypeCache.Read( "Rock.Model.Person" ).Id;
            foreach (var following in service.Queryable()
                .Where( f =>
                    f.EntityTypeId == personEntityTypeId &&
                    f.EntityId == e.RowKeyId &&
                    f.PersonAliasId == CurrentPersonAlias.Id ) )
            {
                service.Delete( following );
            }

            rockContext.SaveChanges();

            BindGrid();
        }
        /// <summary>
        /// Handles the Click event of the btnConfirm control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        protected void btnConfirm_Click( object sender, EventArgs e )
        {
            if ( Page.IsValid )
            {
                var rockContext = new RockContext();
                var personService = new PersonService( rockContext );
                var ids = Individuals.Select( i => i.PersonId ).ToList();

                #region Individual Details Updates

                int? newTitleId = ddlTitle.SelectedValueAsInt();
                int? newSuffixId = ddlSuffix.SelectedValueAsInt();
                int? newConnectionStatusId = ddlStatus.SelectedValueAsInt();
                int? newRecordStatusId = ddlRecordStatus.SelectedValueAsInt();
                int? newInactiveReasonId = ddlInactiveReason.SelectedValueAsInt();
                string newInactiveReasonNote = tbInactiveReasonNote.Text;
                Gender newGender = ddlGender.SelectedValue.ConvertToEnum<Gender>();
                int? newMaritalStatusId = ddlMaritalStatus.SelectedValueAsInt();

                int? newGraduationYear = null;
                if ( ypGraduation.SelectedYear.HasValue )
                {
                    newGraduationYear = ypGraduation.SelectedYear.Value;
                }

                int? newCampusId = cpCampus.SelectedCampusId;

                bool? newEmailActive = null;
                if ( !string.IsNullOrWhiteSpace( ddlIsEmailActive.SelectedValue ) )
                {
                    newEmailActive = ddlIsEmailActive.SelectedValue == "Active";
                }

                EmailPreference? newEmailPreference = ddlEmailPreference.SelectedValue.ConvertToEnumOrNull<EmailPreference>();

                string newEmailNote = tbEmailNote.Text;

                int? newReviewReason = ddlReviewReason.SelectedValueAsInt();
                string newSystemNote = tbSystemNote.Text;
                string newReviewReasonNote = tbReviewReasonNote.Text;

                int inactiveStatusId = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_INACTIVE ).Id;

                var allChanges = new Dictionary<int, List<string>>();

                var people = personService.Queryable().Where( p => ids.Contains( p.Id ) ).ToList();
                foreach ( var person in people )
                {
                    var changes = new List<string>();
                    allChanges.Add( person.Id, changes );

                    if ( SelectedFields.Contains( ddlTitle.ClientID ) )
                    {
                        History.EvaluateChange( changes, "Title", DefinedValueCache.GetName( person.TitleValueId ), DefinedValueCache.GetName( newTitleId ) );
                        person.TitleValueId = newTitleId;
                    }

                    if ( SelectedFields.Contains( ddlSuffix.ClientID ) )
                    {
                        History.EvaluateChange( changes, "Suffix", DefinedValueCache.GetName( person.SuffixValueId ), DefinedValueCache.GetName( newSuffixId ) );
                        person.SuffixValueId = newSuffixId;
                    }

                    if ( SelectedFields.Contains( ddlStatus.ClientID ) )
                    {
                        History.EvaluateChange( changes, "Connection Status", DefinedValueCache.GetName( person.ConnectionStatusValueId ), DefinedValueCache.GetName( newConnectionStatusId ) );
                        person.ConnectionStatusValueId = newConnectionStatusId;
                    }

                    if ( SelectedFields.Contains( ddlRecordStatus.ClientID ) )
                    {
                        History.EvaluateChange( changes, "Record Status", DefinedValueCache.GetName( person.RecordStatusValueId ), DefinedValueCache.GetName( newRecordStatusId ) );
                        person.RecordStatusValueId = newRecordStatusId;

                        if ( newRecordStatusId.HasValue && newRecordStatusId.Value == inactiveStatusId )
                        {
                            History.EvaluateChange( changes, "Inactive Reason", DefinedValueCache.GetName( person.RecordStatusReasonValueId ), DefinedValueCache.GetName( newInactiveReasonId ) );
                            person.RecordStatusReasonValueId = newInactiveReasonId;

                            if ( !string.IsNullOrWhiteSpace( newInactiveReasonNote ) )
                            {
                                History.EvaluateChange( changes, "Inactive Reason Note", person.InactiveReasonNote, newInactiveReasonNote );
                                person.InactiveReasonNote = newInactiveReasonNote;
                            }
                        }
                    }

                    if ( SelectedFields.Contains( ddlGender.ClientID ) )
                    {
                        History.EvaluateChange( changes, "Gender", person.Gender, newGender );
                        person.Gender = newGender;
                    }

                    if ( SelectedFields.Contains( ddlMaritalStatus.ClientID ) )
                    {
                        History.EvaluateChange( changes, "Marital Status", DefinedValueCache.GetName( person.MaritalStatusValueId ), DefinedValueCache.GetName( newMaritalStatusId ) );
                        person.MaritalStatusValueId = newMaritalStatusId;
                    }

                    if ( SelectedFields.Contains( ddlGradePicker.ClientID ) )
                    {
                        History.EvaluateChange( changes, "Graduation Year", person.GraduationYear, newGraduationYear );
                        person.GraduationYear = newGraduationYear;
                    }

                    if ( SelectedFields.Contains( ddlIsEmailActive.ClientID ) )
                    {
                        History.EvaluateChange( changes, "Email Is Active", person.IsEmailActive ?? true, newEmailActive.Value );
                        person.IsEmailActive = newEmailActive;
                    }

                    if ( SelectedFields.Contains( ddlEmailPreference.ClientID ) )
                    {
                        History.EvaluateChange( changes, "Email Preference", person.EmailPreference, newEmailPreference );
                        person.EmailPreference = newEmailPreference.Value;
                    }

                    if ( SelectedFields.Contains( tbEmailNote.ClientID ) )
                    {
                        History.EvaluateChange( changes, "Email Note", person.EmailNote, newEmailNote );
                        person.EmailNote = newEmailNote;
                    }

                    if ( SelectedFields.Contains( tbSystemNote.ClientID ) )
                    {
                        History.EvaluateChange( changes, "System Note", person.SystemNote, newSystemNote );
                        person.SystemNote = newSystemNote;
                    }

                    if ( SelectedFields.Contains( ddlReviewReason.ClientID ) )
                    {
                        History.EvaluateChange( changes, "Review Reason", DefinedValueCache.GetName( person.ReviewReasonValueId ), DefinedValueCache.GetName( newReviewReason ) );
                        person.ReviewReasonValueId = newReviewReason;
                    }

                    if ( SelectedFields.Contains( tbReviewReasonNote.ClientID ) )
                    {
                        History.EvaluateChange( changes, "Review Reason Note", person.ReviewReasonNote, newReviewReasonNote );
                        person.ReviewReasonNote = newReviewReasonNote;
                    }
                }

                if ( SelectedFields.Contains( cpCampus.ClientID ) && cpCampus.SelectedCampusId.HasValue )
                {
                    int campusId = cpCampus.SelectedCampusId.Value;

                    Guid familyGuid = new Guid( Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY );

                    var familyMembers = new GroupMemberService( rockContext ).Queryable()
                        .Where( m => ids.Contains( m.PersonId ) && m.Group.GroupType.Guid == familyGuid )
                        .Select( m => new { m.PersonId, m.GroupId } )
                        .Distinct()
                        .ToList();

                    var families = new GroupMemberService( rockContext ).Queryable()
                        .Where( m => ids.Contains( m.PersonId ) && m.Group.GroupType.Guid == familyGuid )
                        .Select( m => m.Group )
                        .Distinct()
                        .ToList();

                    foreach ( int personId in ids )
                    {
                        var familyIds = familyMembers.Where( m => m.PersonId == personId ).Select( m => m.GroupId ).ToList();
                        if ( familyIds.Count == 1 )
                        {
                            int familyId = familyIds.FirstOrDefault();
                            var family = families.Where( g => g.Id == familyId ).FirstOrDefault();
                            {
                                if ( family != null )
                                {
                                    family.CampusId = campusId;
                                }
                                familyMembers.RemoveAll( m => m.GroupId == familyId );
                            }
                        }
                    }

                    rockContext.SaveChanges();
                }

                // Update following
                if ( SelectedFields.Contains( ddlFollow.ClientID ) )
                {
                    var personAliasEntityType = EntityTypeCache.Read( "Rock.Model.PersonAlias" );
                    if ( personAliasEntityType != null )
                    {
                        int personAliasEntityTypeId = personAliasEntityType.Id;

                        bool follow = true;
                        if ( !string.IsNullOrWhiteSpace( ddlFollow.SelectedValue ) )
                        {
                            follow = ddlFollow.SelectedValue == "Add";
                        }

                        var personAliasService = new PersonAliasService( rockContext );
                        var followingService = new FollowingService( rockContext );
                        if ( follow )
                        {
                            var paQry = personAliasService.Queryable();

                            var alreadyFollowingIds = followingService.Queryable()
                                .Where( f =>
                                    f.EntityTypeId == personAliasEntityTypeId &&
                                    f.PersonAlias.Id == CurrentPersonAlias.Id )
                                .Join( paQry, f => f.EntityId, p => p.Id, ( f, p ) => new { PersonAlias = p } )
                                .Select( p => p.PersonAlias.PersonId )
                                .Distinct()
                                .ToList();

                            foreach ( int id in ids.Where( id => !alreadyFollowingIds.Contains( id ) ) )
                            {
                                var following = new Following
                                {
                                    EntityTypeId = personAliasEntityTypeId,
                                    EntityId = ( people.FirstOrDefault( p => p.Id == id ).PrimaryAliasId ) ?? 0,
                                    PersonAliasId = CurrentPersonAlias.Id
                                };
                                followingService.Add( following );
                            }
                        }
                        else
                        {
                            var paQry = personAliasService.Queryable()
                                .Where( p => ids.Contains( p.PersonId ) )
                                .Select( p => p.Id );

                            foreach ( var following in followingService.Queryable()
                                .Where( f =>
                                    f.EntityTypeId == personAliasEntityTypeId &&
                                    paQry.Contains( f.EntityId ) &&
                                    f.PersonAlias.Id == CurrentPersonAlias.Id ) )
                            {
                                followingService.Delete( following );
                            }
                        }
                    }
                }

                rockContext.SaveChanges();

                #endregion

                #region Attributes

                var selectedCategories = new List<CategoryCache>();
                foreach ( string categoryGuid in GetAttributeValue( "AttributeCategories" ).SplitDelimitedValues() )
                {
                    var category = CategoryCache.Read( categoryGuid.AsGuid(), rockContext );
                    if ( category != null )
                    {
                        selectedCategories.Add( category );
                    }
                }

                var attributes = new List<AttributeCache>();
                var attributeValues = new Dictionary<int, string>();

                int categoryIndex = 0;
                foreach ( var category in selectedCategories.OrderBy( c => c.Name ) )
                {
                    PanelWidget pw = null;
                    string controlId = "pwAttributes_" + category.Id.ToString();
                    if ( categoryIndex % 2 == 0 )
                    {
                        pw = phAttributesCol1.FindControl( controlId ) as PanelWidget;
                    }
                    else
                    {
                        pw = phAttributesCol2.FindControl( controlId ) as PanelWidget;
                    }
                    categoryIndex++;

                    if ( pw != null )
                    {
                        var orderedAttributeList = new AttributeService( rockContext ).GetByCategoryId( category.Id )
                            .OrderBy( a => a.Order ).ThenBy( a => a.Name );
                        foreach ( var attribute in orderedAttributeList )
                        {
                            if ( attribute.IsAuthorized( Authorization.EDIT, CurrentPerson ) )
                            {
                                var attributeCache = AttributeCache.Read( attribute.Id );

                                Control attributeControl = pw.FindControl( string.Format( "attribute_field_{0}", attribute.Id ) );

                                if ( attributeControl != null && SelectedFields.Contains( attributeControl.ClientID ) )
                                {
                                    string newValue = attributeCache.FieldType.Field.GetEditValue( attributeControl, attributeCache.QualifierValues );
                                    attributes.Add( attributeCache );
                                    attributeValues.Add( attributeCache.Id, newValue );
                                }
                            }
                        }
                    }
                }

                if ( attributes.Any() )
                {
                    foreach ( var person in people )
                    {
                        person.LoadAttributes();
                        foreach ( var attribute in attributes )
                        {
                            string originalValue = person.GetAttributeValue( attribute.Key );
                            string newValue = attributeValues[attribute.Id];
                            if ( ( originalValue ?? string.Empty ).Trim() != ( newValue ?? string.Empty ).Trim() )
                            {
                                Rock.Attribute.Helper.SaveAttributeValue( person, attribute, newValue, rockContext );

                                string formattedOriginalValue = string.Empty;
                                if ( !string.IsNullOrWhiteSpace( originalValue ) )
                                {
                                    formattedOriginalValue = attribute.FieldType.Field.FormatValue( null, originalValue, attribute.QualifierValues, false );
                                }

                                string formattedNewValue = string.Empty;
                                if ( !string.IsNullOrWhiteSpace( newValue ) )
                                {
                                    formattedNewValue = attribute.FieldType.Field.FormatValue( null, newValue, attribute.QualifierValues, false );
                                }

                                History.EvaluateChange( allChanges[person.Id], attribute.Name, formattedOriginalValue, formattedNewValue );
                            }
                        }
                    }
                }

                // Create the history records
                foreach ( var changes in allChanges )
                {
                    if ( changes.Value.Any() )
                    {
                        HistoryService.AddChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_DEMOGRAPHIC_CHANGES.AsGuid(),
                            changes.Key, changes.Value );
                    }
                }
                rockContext.SaveChanges();

                #endregion

                #region Add Note

                if ( !string.IsNullOrWhiteSpace( tbNote.Text ) && CurrentPerson != null )
                {
                    string text = tbNote.Text;
                    bool isAlert = cbIsAlert.Checked;
                    bool isPrivate = cbIsPrivate.Checked;

                    var noteTypeService = new NoteTypeService( rockContext );
                    var noteType = noteTypeService.Get( Rock.SystemGuid.NoteType.PERSON_TIMELINE.AsGuid() );
                    if ( noteType != null )
                    {
                        var notes = new List<Note>();
                        var noteService = new NoteService( rockContext );

                        foreach ( int id in ids )
                        {
                            var note = new Note();
                            note.IsSystem = false;
                            note.EntityId = id;
                            note.Caption = isPrivate ? "You - Personal Note" : string.Empty;
                            note.Text = tbNote.Text;
                            note.IsAlert = cbIsAlert.Checked;
                            note.NoteType = noteType;
                            notes.Add( note );
                            noteService.Add( note );
                        }

                        rockContext.WrapTransaction( () =>
                        {
                            rockContext.SaveChanges();
                            foreach ( var note in notes )
                            {
                                note.AllowPerson( Authorization.EDIT, CurrentPerson, rockContext );
                                if ( isPrivate )
                                {
                                    note.MakePrivate( Authorization.VIEW, CurrentPerson, rockContext );
                                }
                            }
                        } );

                    }
                }

                #endregion

                #region Group

                int? groupId = gpGroup.SelectedValue.AsIntegerOrNull();
                if ( groupId.HasValue )
                {
                    var group = new GroupService( rockContext ).Get( groupId.Value );
                    if ( group != null )
                    {
                        var groupMemberService = new GroupMemberService( rockContext );

                        var existingMembers = groupMemberService.Queryable( "Group" )
                            .Where( m =>
                                m.GroupId == group.Id &&
                                ids.Contains( m.PersonId ) )
                            .ToList();

                        string action = ddlGroupAction.SelectedValue;
                        if ( action == "Remove" )
                        {
                            groupMemberService.DeleteRange( existingMembers );
                            rockContext.SaveChanges();
                        }
                        else
                        {
                            var roleId = ddlGroupRole.SelectedValueAsInt();
                            var status = ddlGroupMemberStatus.SelectedValueAsEnum<GroupMemberStatus>();

                            // Get the attribute values updated
                            var gm = new GroupMember();
                            gm.Group = group;
                            gm.GroupId = group.Id;
                            gm.LoadAttributes( rockContext );
                            var selectedGroupAttributes = new List<AttributeCache>();
                            var selectedGroupAttributeValues = new Dictionary<string, string>();
                            foreach ( var attributeCache in gm.Attributes.Select( a => a.Value ) )
                            {
                                Control attributeControl = phAttributes.FindControl( string.Format( "attribute_field_{0}", attributeCache.Id ) );
                                if ( attributeControl != null && ( action == "Add" || SelectedFields.Contains( attributeControl.ClientID ) ) )
                                {
                                    string newValue = attributeCache.FieldType.Field.GetEditValue( attributeControl, attributeCache.QualifierValues );
                                    selectedGroupAttributes.Add( attributeCache );
                                    selectedGroupAttributeValues.Add( attributeCache.Key, newValue );
                                }
                            }

                            if ( action == "Add" )
                            {
                                if ( roleId.HasValue )
                                {
                                    var newGroupMembers = new List<GroupMember>();

                                    var existingIds = existingMembers.Select( m => m.PersonId ).Distinct().ToList();
                                    foreach ( int id in ids.Where( id => !existingIds.Contains( id ) ) )
                                    {
                                        var groupMember = new GroupMember();
                                        groupMember.GroupId = group.Id;
                                        groupMember.GroupRoleId = roleId.Value;
                                        groupMember.GroupMemberStatus = status;
                                        groupMember.PersonId = id;
                                        groupMemberService.Add( groupMember );
                                        newGroupMembers.Add( groupMember );
                                    }

                                    rockContext.SaveChanges();

                                    if ( selectedGroupAttributes.Any() )
                                    {
                                        foreach ( var groupMember in newGroupMembers )
                                        {
                                            foreach ( var attribute in selectedGroupAttributes )
                                            {
                                                Rock.Attribute.Helper.SaveAttributeValue( groupMember, attribute, selectedGroupAttributeValues[attribute.Key], rockContext );
                                            }
                                        }
                                    }
                                }
                            }
                            else // Update
                            {
                                if ( SelectedFields.Contains( ddlGroupRole.ClientID ) && roleId.HasValue )
                                {
                                    foreach ( var member in existingMembers.Where( m => m.GroupRoleId != roleId.Value ) )
                                    {
                                        if ( !existingMembers.Where( m => m.PersonId == member.PersonId && m.GroupRoleId == roleId.Value ).Any() )
                                        {
                                            member.GroupRoleId = roleId.Value;
                                        }
                                    }
                                }

                                if ( SelectedFields.Contains( ddlGroupMemberStatus.ClientID ) )
                                {
                                    foreach ( var member in existingMembers )
                                    {
                                        member.GroupMemberStatus = status;
                                    }
                                }

                                rockContext.SaveChanges();

                                if ( selectedGroupAttributes.Any() )
                                {
                                    foreach ( var groupMember in existingMembers )
                                    {
                                        foreach ( var attribute in selectedGroupAttributes )
                                        {
                                            Rock.Attribute.Helper.SaveAttributeValue( groupMember, attribute, selectedGroupAttributeValues[attribute.Key], rockContext );
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                #endregion

                pnlEntry.Visible = false;
                pnlConfirm.Visible = false;

                nbResult.Text = string.Format( "{0} {1} succesfully updated.",
                    ids.Count().ToString( "N0" ), ( ids.Count() > 1 ? "people were" : "person was" ) ); ;
                pnlResult.Visible = true;
            }
        }
        /// <summary>
        /// Handles the Click event of the lbUnfollow control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        void lbUnfollow_Click( object sender, EventArgs e )
        {
            var itemsSelected = new List<int>();
            gFollowings.SelectedKeys.ToList().ForEach( f => itemsSelected.Add( f.ToString().AsInteger() ) );

            if ( itemsSelected.Any() )
            {
                var rockContext = new RockContext();
                var personAliasService = new PersonAliasService( rockContext );
                var followingService = new FollowingService( rockContext );

                var paQry = personAliasService.Queryable()
                    .Where( p => itemsSelected.Contains( p.PersonId ) )
                    .Select( p => p.Id );

                int personAliasEntityTypeId = EntityTypeCache.Read( "Rock.Model.PersonAlias" ).Id;
                foreach ( var following in followingService.Queryable()
                    .Where( f =>
                        f.EntityTypeId == personAliasEntityTypeId &&
                        paQry.Contains( f.EntityId ) &&
                        f.PersonAliasId == CurrentPersonAlias.Id ) )
                {
                    followingService.Delete( following );
                }

                rockContext.SaveChanges();
            }

            BindGrid();
        }
Exemple #4
0
        /// <summary>
        /// Handles the Click event of the btnComplete control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void btnComplete_Click( object sender, EventArgs e )
        {
            if ( Page.IsValid )
            {
                var rockContext = new RockContext();
                var personService = new PersonService( rockContext );
                var ids = Individuals.Select( i => i.PersonId ).ToList();

                var personEntityType = EntityTypeCache.Read( "Rock.Model.Person" );
                if ( personEntityType != null )
                {
                    int personEntityTypeId = personEntityType.Id;

                    var people = personService.Queryable().Where( p => ids.Contains( p.Id ) ).ToList();

                    #region Individual Details Updates

                    int? newTitleId = ddlTitle.SelectedValueAsInt();
                    int? newSuffixId = ddlSuffix.SelectedValueAsInt();
                    int? newConnectionStatusId = ddlStatus.SelectedValueAsInt();
                    int? newRecordStatusId = ddlRecordStatus.SelectedValueAsInt();
                    int? newInactiveReasonId = ddlInactiveReason.SelectedValueAsInt();
                    string newInactiveReasonNote = tbInactiveReasonNote.Text;
                    Gender? newGender = ddlGender.SelectedValue.ConvertToEnumOrNull<Gender>();

                    int? newMaritalStatusId = ddlMaritalStatus.SelectedValueAsInt();

                    DateTime? newGraduationDate = null;
                    if ( ypGraduation.SelectedYear.HasValue )
                    {
                        newGraduationDate = new DateTime( ypGraduation.SelectedYear.Value, _gradeTransitionDate.Month, _gradeTransitionDate.Day );
                    }

                    int? newCampusId = cpCampus.SelectedCampusId;
                    bool? newEmailActive = null;
                    if ( !string.IsNullOrWhiteSpace( ddlIsEmailActive.SelectedValue ) )
                    {
                        newEmailActive = ddlIsEmailActive.SelectedValue == "Active";
                    }
                    EmailPreference? newEmailPreference = ddlEmailPreference.SelectedValue.ConvertToEnumOrNull<EmailPreference>();
                    string newEmailNote = tbEmailNote.Text;
                    bool? newFollow = null;
                    if ( !string.IsNullOrWhiteSpace( ddlFollow.SelectedValue ) )
                    {
                        newFollow = ddlFollow.SelectedValue == "Add";
                    }
                    int? newReviewReason = ddlReviewReason.SelectedValueAsInt();
                    string newSystemNote = tbSystemNote.Text;
                    string newReviewReasonNote = tbReviewReasonNote.Text;

                    var allChanges = new Dictionary<int, List<string>>();

                    foreach ( var person in people )
                    {
                        var changes = new List<string>();
                        allChanges.Add( person.Id, changes );

                        if ( newTitleId.HasValue )
                        {
                            History.EvaluateChange( changes, "Title", DefinedValueCache.GetName( person.TitleValueId ), DefinedValueCache.GetName( newTitleId ) );
                            person.TitleValueId = newTitleId;
                        }

                        if ( newSuffixId.HasValue )
                        {
                            History.EvaluateChange( changes, "Suffix", DefinedValueCache.GetName( person.SuffixValueId ), DefinedValueCache.GetName( newSuffixId ) );
                            person.SuffixValueId = newSuffixId;
                        }

                        if ( newConnectionStatusId.HasValue )
                        {
                            History.EvaluateChange( changes, "Connection Status", DefinedValueCache.GetName( person.ConnectionStatusValueId ), DefinedValueCache.GetName( newConnectionStatusId ) );
                            person.ConnectionStatusValueId = newConnectionStatusId;
                        }

                        if ( newRecordStatusId.HasValue )
                        {
                            History.EvaluateChange( changes, "Record Status", DefinedValueCache.GetName( person.RecordStatusValueId ), DefinedValueCache.GetName( newRecordStatusId ) );
                            person.RecordStatusValueId = newRecordStatusId;
                        }

                        if ( newInactiveReasonId.HasValue )
                        {
                            History.EvaluateChange( changes, "Inactive Reason", DefinedValueCache.GetName( person.RecordStatusReasonValueId ), DefinedValueCache.GetName( newInactiveReasonId ) );
                            person.RecordStatusReasonValueId = newInactiveReasonId;
                        }

                        if ( !string.IsNullOrWhiteSpace( newInactiveReasonNote ) )
                        {
                            History.EvaluateChange( changes, "Inactive Reason Note", person.InactiveReasonNote, newInactiveReasonNote );
                            person.InactiveReasonNote = newInactiveReasonNote;
                        }

                        if ( newGender.HasValue )
                        {
                            History.EvaluateChange( changes, "Gender", person.Gender, newGender.Value );
                            person.Gender = newGender.Value;
                        }

                        if ( newMaritalStatusId.HasValue )
                        {
                            History.EvaluateChange( changes, "Marital Status", DefinedValueCache.GetName( person.MaritalStatusValueId ), DefinedValueCache.GetName( newMaritalStatusId ) );
                            person.MaritalStatusValueId = newMaritalStatusId;
                        }

                        if ( newGraduationDate.HasValue )
                        {
                            History.EvaluateChange( changes, "Graduation Date", person.GraduationDate, newGraduationDate );
                            person.GraduationDate = newGraduationDate;
                        }

                        if ( newEmailActive.HasValue )
                        {
                            History.EvaluateChange( changes, "Email Is Active", person.IsEmailActive ?? true, newEmailActive.Value );
                            person.IsEmailActive = newEmailActive;
                        }

                        if ( newEmailPreference.HasValue )
                        {
                            History.EvaluateChange( changes, "Email Preference", person.EmailPreference, newEmailPreference );
                            person.EmailPreference = newEmailPreference.Value;
                        }

                        if ( !string.IsNullOrWhiteSpace( newEmailNote ) )
                        {
                            History.EvaluateChange( changes, "Email Note", person.EmailNote, newEmailNote );
                            person.EmailNote = newEmailNote;
                        }

                        if ( !string.IsNullOrWhiteSpace( newSystemNote ) )
                        {
                            History.EvaluateChange( changes, "System Note", person.SystemNote, newSystemNote );
                            person.SystemNote = newSystemNote;
                        }

                        if ( newReviewReason.HasValue )
                        {
                            History.EvaluateChange( changes, "Review Reason", DefinedValueCache.GetName( person.ReviewReasonValueId ), DefinedValueCache.GetName( newReviewReason ) );
                            person.ReviewReasonValueId = newReviewReason;
                        }

                        if ( !string.IsNullOrWhiteSpace( newReviewReasonNote ) )
                        {
                            History.EvaluateChange( changes, "Review Reason Note", person.ReviewReasonNote, newReviewReasonNote );
                            person.ReviewReasonNote = newReviewReasonNote;
                        }
                    }

                    // Update following
                    if ( newFollow.HasValue && CurrentPersonAlias != null )
                    {
                        var followingService = new FollowingService( rockContext );
                        if ( newFollow.Value )
                        {
                            var alreadyFollingIds = followingService.Queryable()
                                .Where( f =>
                                    f.EntityTypeId == personEntityTypeId &&
                                    f.PersonAlias.Id == CurrentPersonAlias.Id )
                                .Select( f => f.EntityId )
                                .Distinct()
                                .ToList();
                            foreach ( int id in ids.Where( id => !alreadyFollingIds.Contains( id ) ) )
                            {
                                var following = new Following
                                {
                                    EntityTypeId = personEntityTypeId,
                                    EntityId = id,
                                    PersonAliasId = CurrentPersonAlias.Id
                                };
                                followingService.Add( following );
                            }
                        }
                        else
                        {
                            foreach ( var following in followingService.Queryable()
                                .Where( f =>
                                    f.EntityTypeId == personEntityTypeId &&
                                    ids.Contains( f.EntityId ) &&
                                    f.PersonAlias.Id == CurrentPersonAlias.Id ) )
                            {
                                followingService.Delete( following );
                            }
                        }
                    }

                    rockContext.SaveChanges();

                    #endregion

                    #region Attributes

                    var selectedCategories = new List<CategoryCache>();
                    foreach ( string categoryGuid in GetAttributeValue( "AttributeCategories" ).SplitDelimitedValues() )
                    {
                        var category = CategoryCache.Read( categoryGuid.AsGuid(), rockContext );
                        if ( category != null )
                        {
                            selectedCategories.Add( category );
                        }
                    }

                    var attributes = new List<AttributeCache>();
                    var attributeValues = new Dictionary<int, string>();

                    int categoryIndex = 0;
                    foreach ( var category in selectedCategories.OrderBy( c => c.Name ) )
                    {
                        PanelWidget pw = null;
                        string controlId = "pwAttributes_" + category.Id.ToString();
                        if ( categoryIndex % 2 == 0 )
                        {
                            pw = phAttributesCol1.FindControl( controlId ) as PanelWidget;
                        }
                        else
                        {
                            pw = phAttributesCol2.FindControl( controlId) as PanelWidget;
                        }
                        categoryIndex++;

                        if ( pw != null )
                        {
                            var orderedAttributeList = new AttributeService( rockContext ).GetByCategoryId( category.Id )
                                .OrderBy( a => a.Order ).ThenBy( a => a.Name );
                            foreach ( var attribute in orderedAttributeList )
                            {
                                if ( attribute.IsAuthorized( Authorization.EDIT, CurrentPerson ) )
                                {
                                    var attributeCache = AttributeCache.Read( attribute.Id );

                                    Control attributeControl = pw.FindControl( string.Format( "attribute_field_{0}", attribute.Id ) );
                                    if ( attributeControl != null )
                                    {
                                        string newValue = attributeCache.FieldType.Field.GetEditValue( attributeControl, attributeCache.QualifierValues );
                                        if (!string.IsNullOrWhiteSpace(newValue))
                                        {
                                            attributes.Add( attributeCache);
                                            attributeValues.Add( attributeCache.Id, newValue );
                                        }
                                    }
                                }
                            }
                        }
                    }

                    if (attributes.Any())
                    {
                        foreach ( var person in people )
                        {
                            person.LoadAttributes();
                            foreach ( var attribute in attributes )
                            {
                                string originalValue = person.GetAttributeValue( attribute.Key );
                                string newValue = attributeValues[attribute.Id];
                                if ( ( originalValue ?? string.Empty ).Trim() != ( newValue ?? string.Empty ).Trim() )
                                {
                                    Rock.Attribute.Helper.SaveAttributeValue( person, attribute, newValue, rockContext );

                                    string formattedOriginalValue = string.Empty;
                                    if ( !string.IsNullOrWhiteSpace( originalValue ) )
                                    {
                                        formattedOriginalValue = attribute.FieldType.Field.FormatValue( null, originalValue, attribute.QualifierValues, false );
                                    }

                                    string formattedNewValue = string.Empty;
                                    if ( !string.IsNullOrWhiteSpace( newValue ) )
                                    {
                                        formattedNewValue = attribute.FieldType.Field.FormatValue( null, newValue, attribute.QualifierValues, false );
                                    }

                                    History.EvaluateChange( allChanges[person.Id], attribute.Name, formattedOriginalValue, formattedNewValue );
                                }
                            }
                        }
                    }

                    // Create the history records
                    foreach ( var changes in allChanges )
                    {
                        if ( changes.Value.Any() )
                        {
                            HistoryService.AddChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_DEMOGRAPHIC_CHANGES.AsGuid(),
                                changes.Key, changes.Value );
                        }
                    }
                    rockContext.SaveChanges();

                    #endregion

                    #region Add Note

                    if ( !string.IsNullOrWhiteSpace( tbNote.Text ) && CurrentPerson != null )
                    {
                        string text = tbNote.Text;
                        bool isAlert = cbIsAlert.Checked;
                        bool isPrivate = cbIsPrivate.Checked;

                        var noteTypeService = new NoteTypeService( rockContext );
                        var noteService = new NoteService( rockContext );

                        string noteTypeName = GetAttributeValue( "NoteType" );
                        var noteType = noteTypeService.Get( personEntityTypeId, noteTypeName );

                        if ( noteType != null )
                        {
                            var notes = new List<Note>();

                            foreach ( int id in ids )
                            {
                                var note = new Note();
                                note.IsSystem = false;
                                note.EntityId = id;
                                note.Caption = isPrivate ? "You - Personal Note" : string.Empty;
                                note.Text = tbNote.Text;
                                note.IsAlert = cbIsAlert.Checked;
                                note.NoteType = noteType;

                                notes.Add( note );
                                noteService.Add( note );
                            }

                            rockContext.WrapTransaction( () =>
                            {
                                rockContext.SaveChanges();
                                foreach( var note in notes)
                                {
                                    note.AllowPerson( Authorization.EDIT, CurrentPerson, rockContext );
                                    if ( isPrivate)
                                    {
                                        note.MakePrivate( Authorization.VIEW, CurrentPerson, rockContext );
                                    }
                                }
                            } );

                        }
                    }

                    #endregion

                }

                string message = string.Format("{0} {1} succesfully updated!",
                    ids.Count().ToString("N0"), (ids.Count() > 1 ? "people were" : "person was") );
                ShowResult( message );
            }
        }