/// <summary>
        /// Handles the Click event of the btnSave 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 btnSave_Click( object sender, EventArgs e )
        {
            // confirmation was disabled by btnSave on client-side.  So if returning without a redirect,
            // it should be enabled.  If returning with a redirect, the control won't be updated to reflect
            // confirmation being enabled, so it's ok to enable it here
            confirmExit.Enabled = true;

            if ( Page.IsValid )
            {
                confirmExit.Enabled = true;

                RockTransactionScope.WrapTransaction( () =>
                {
                    var rockContext = new RockContext();
                    var familyService = new GroupService( rockContext );
                    var familyMemberService = new GroupMemberService( rockContext );
                    var personService = new PersonService( rockContext );
                    var historyService = new HistoryService( rockContext );

                    var familyChanges = new List<string>();

                    // SAVE FAMILY
                    _family = familyService.Get( _family.Id );

                    History.EvaluateChange( familyChanges, "Family Name", _family.Name, tbFamilyName.Text );
                    _family.Name = tbFamilyName.Text;

                    int? campusId = cpCampus.SelectedValueAsInt();
                    if ( _family.CampusId != campusId )
                    {
                        History.EvaluateChange( familyChanges, "Campus",
                            _family.CampusId.HasValue ? CampusCache.Read( _family.CampusId.Value ).Name : string.Empty,
                            campusId.HasValue ? CampusCache.Read( campusId.Value ).Name : string.Empty );
                        _family.CampusId = campusId;
                    }

                    var familyGroupTypeId = _family.GroupTypeId;

                    rockContext.SaveChanges();

                    // SAVE FAMILY MEMBERS
                    int? recordStatusValueID = ddlRecordStatus.SelectedValueAsInt();
                    int? reasonValueId = ddlReason.SelectedValueAsInt();
                    var newFamilies = new List<Group>();

                    foreach ( var familyMember in FamilyMembers )
                    {
                        var memberChanges = new List<string>();
                        var demographicChanges = new List<string>();

                        var role = familyRoles.Where( r => r.Guid.Equals( familyMember.RoleGuid ) ).FirstOrDefault();
                        if ( role == null )
                        {
                            role = familyRoles.FirstOrDefault();
                        }

                        bool isChild = role != null && role.Guid.Equals( new Guid( Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_CHILD ) );

                        // People added to family (new or from other family)
                        if ( !familyMember.ExistingFamilyMember )
                        {
                            var groupMember = new GroupMember();

                            if ( familyMember.Id == -1 )
                            {
                                // added new person
                                demographicChanges.Add( "Created" );

                                var person = new Person();
                                person.FirstName = familyMember.FirstName;
                                person.NickName = familyMember.NickName;
                                History.EvaluateChange( demographicChanges, "First Name", string.Empty, person.FirstName );

                                person.LastName = familyMember.LastName;
                                History.EvaluateChange( demographicChanges, "Last Name", string.Empty, person.LastName );

                                person.Gender = familyMember.Gender;
                                History.EvaluateChange( demographicChanges, "Gender", null, person.Gender );

                                person.BirthDate = familyMember.BirthDate;
                                History.EvaluateChange( demographicChanges, "Birth Date", null, person.BirthDate );

                                if ( !isChild )
                                {
                                    person.GivingGroupId = _family.Id;
                                    History.EvaluateChange( demographicChanges, "Giving Group", string.Empty, _family.Name );
                                }

                                person.EmailPreference = EmailPreference.EmailAllowed;

                                groupMember.Person = person;
                            }
                            else
                            {
                                // added from other family
                                groupMember.Person = personService.Get( familyMember.Id );
                            }

                            if ( recordStatusValueID > 0 )
                            {
                                History.EvaluateChange( demographicChanges, "Record Status", DefinedValueCache.GetName( groupMember.Person.RecordStatusValueId ), DefinedValueCache.GetName( recordStatusValueID ) );
                                groupMember.Person.RecordStatusValueId = recordStatusValueID;

                                History.EvaluateChange( demographicChanges, "Record Status Reason", DefinedValueCache.GetName( groupMember.Person.RecordStatusReasonValueId ), DefinedValueCache.GetName( reasonValueId ) );
                                groupMember.Person.RecordStatusReasonValueId = reasonValueId;
                            }

                            groupMember.GroupId = _family.Id;
                            if ( role != null )
                            {
                                History.EvaluateChange( memberChanges, "Role", string.Empty, role.Name );
                                groupMember.GroupRoleId = role.Id;
                            }

                            if ( groupMember.Person != null )
                            {
                                familyMemberService.Add( groupMember );
                                rockContext.SaveChanges();
                                familyMember.Id = groupMember.Person.Id;
                            }

                        }
                        else
                        {
                            // existing family members
                            var groupMember = familyMemberService.Queryable( "Person" ).Where( m =>
                                m.PersonId == familyMember.Id &&
                                m.Group.GroupTypeId == familyGroupTypeId &&
                                m.GroupId == _family.Id ).FirstOrDefault();

                            if ( groupMember != null )
                            {
                                if ( familyMember.Removed )
                                {
                                    var newFamilyChanges = new List<string>();

                                    // Family member was removed and should be created in their own new family
                                    var newFamily = new Group();
                                    newFamily.Name = familyMember.LastName + " Family";
                                    History.EvaluateChange( newFamilyChanges, "Family", string.Empty, newFamily.Name );

                                    newFamily.GroupTypeId = familyGroupTypeId;

                                    if ( _family.CampusId.HasValue )
                                    {
                                        History.EvaluateChange( newFamilyChanges, "Campus", string.Empty, CampusCache.Read( _family.CampusId.Value ).Name );
                                    }
                                    newFamily.CampusId = _family.CampusId;

                                    familyService.Add( newFamily );
                                    rockContext.SaveChanges();

                                    // If person's previous giving group was this family, set it to their new family id
                                    if ( groupMember.Person.GivingGroup != null && groupMember.Person.GivingGroupId == _family.Id )
                                    {
                                        History.EvaluateChange( demographicChanges, "Giving Group", groupMember.Person.GivingGroup.Name, _family.Name );
                                        groupMember.Person.GivingGroupId = newFamily.Id;
                                    }

                                    groupMember.Group = newFamily;
                                    rockContext.SaveChanges();

                                    var newMemberChanges = new List<string>();
                                    History.EvaluateChange( newMemberChanges, "Role", string.Empty, groupMember.GroupRole.Name );

                                    HistoryService.SaveChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_FAMILY_CHANGES.AsGuid(),
                                        groupMember.Person.Id, newFamilyChanges, newFamily.Name, typeof( Group ), newFamily.Id );

                                    newFamilies.Add( newFamily );

                                    History.EvaluateChange( memberChanges, "Role", groupMember.GroupRole.Name, string.Empty );
                                }
                                else
                                {
                                    // Existing member was not remvoved
                                    if ( role != null )
                                    {
                                        History.EvaluateChange( memberChanges, "Role",
                                            groupMember.GroupRole != null ? groupMember.GroupRole.Name : string.Empty, role.Name );
                                        groupMember.GroupRoleId = role.Id;

                                        if ( recordStatusValueID > 0 )
                                        {
                                            History.EvaluateChange( demographicChanges, "Record Status", DefinedValueCache.GetName( groupMember.Person.RecordStatusValueId ), DefinedValueCache.GetName( recordStatusValueID ) );
                                            groupMember.Person.RecordStatusValueId = recordStatusValueID;

                                            History.EvaluateChange( demographicChanges, "Record Status Reason", DefinedValueCache.GetName( groupMember.Person.RecordStatusReasonValueId ), DefinedValueCache.GetName( reasonValueId ) );
                                            groupMember.Person.RecordStatusReasonValueId = reasonValueId;
                                        }

                                        rockContext.SaveChanges();
                                    }
                                }
                            }
                        }

                        // Remove anyone that was moved from another family
                        if ( familyMember.RemoveFromOtherFamilies )
                        {
                            var otherFamilies = familyMemberService.Queryable()
                                .Where( m =>
                                    m.PersonId == familyMember.Id &&
                                    m.Group.GroupTypeId == familyGroupTypeId &&
                                    m.GroupId != _family.Id )
                                .ToList();

                            foreach ( var otherFamilyMember in otherFamilies )
                            {
                                var fm = familyMemberService.Get( otherFamilyMember.Id );

                                // If the person's giving group id was the family they are being removed from, update it to this new family's id
                                if ( fm.Person.GivingGroupId == fm.GroupId )
                                {
                                    var person = personService.Get( fm.PersonId );

                                    History.EvaluateChange( demographicChanges, "Giving Group", person.GivingGroup.Name, _family.Name );
                                    person.GivingGroupId = _family.Id;

                                    rockContext.SaveChanges();
                                }

                                var oldMemberChanges = new List<string>();
                                History.EvaluateChange( oldMemberChanges, "Role", fm.GroupRole.Name, string.Empty );
                                History.EvaluateChange( oldMemberChanges, "Family", fm.Group.Name, string.Empty );
                                HistoryService.SaveChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_FAMILY_CHANGES.AsGuid(),
                                    fm.Person.Id, oldMemberChanges, fm.Group.Name, typeof( Group ), fm.Group.Id );

                                familyMemberService.Delete( fm );
                                rockContext.SaveChanges();

                                var f = familyService.Queryable()
                                    .Where( g =>
                                        g.Id == otherFamilyMember.GroupId &&
                                        !g.Members.Any() )
                                    .FirstOrDefault();
                                if ( f != null )
                                {
                                    familyService.Delete( f );
                                    rockContext.SaveChanges();
                                }

                            }
                        }

                        HistoryService.SaveChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_DEMOGRAPHIC_CHANGES.AsGuid(),
                            familyMember.Id, demographicChanges );

                        HistoryService.SaveChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_FAMILY_CHANGES.AsGuid(),
                            familyMember.Id, memberChanges, _family.Name, typeof( Group ), _family.Id );
                    }

                    // SAVE LOCATIONS
                    var groupLocationService = new GroupLocationService( rockContext );

                    // delete any group locations that were removed
                    var remainingLocationIds = FamilyAddresses.Where( a => a.Id > 0 ).Select( a => a.Id ).ToList();
                    foreach ( var removedLocation in groupLocationService.Queryable( "GroupLocationTypeValue,Location" )
                        .Where( l => l.GroupId == _family.Id &&
                            !remainingLocationIds.Contains( l.Id ) ) )
                    {
                        History.EvaluateChange( familyChanges, removedLocation.GroupLocationTypeValue.Name + " Location",
                            removedLocation.Location.ToString(), string.Empty );
                        groupLocationService.Delete( removedLocation );
                    }
                    rockContext.SaveChanges();

                    foreach ( var familyAddress in FamilyAddresses )
                    {
                        Location updatedAddress = null;
                        if ( familyAddress.LocationIsDirty )
                        {
                            updatedAddress = new LocationService( rockContext ).Get(
                                familyAddress.Street1, familyAddress.Street2, familyAddress.City,
                                familyAddress.State, familyAddress.Zip );
                        }

                        GroupLocation groupLocation = null;
                        if ( familyAddress.Id > 0 )
                        {
                            groupLocation = groupLocationService.Get( familyAddress.Id );
                        }
                        if ( groupLocation == null )
                        {
                            groupLocation = new GroupLocation();
                            groupLocation.GroupId = _family.Id;
                            groupLocationService.Add( groupLocation );
                        }

                        History.EvaluateChange( familyChanges, "Location Type",
                            groupLocation.GroupLocationTypeValueId.HasValue ? DefinedValueCache.Read( groupLocation.GroupLocationTypeValueId.Value ).Name : string.Empty,
                            familyAddress.LocationTypeName );
                        groupLocation.GroupLocationTypeValueId = familyAddress.LocationTypeId;

                        History.EvaluateChange( familyChanges, familyAddress.LocationTypeName + " Is Mailing",
                            groupLocation.IsMailingLocation.ToString(), familyAddress.IsMailing.ToString() );
                        groupLocation.IsMailingLocation = familyAddress.IsMailing;

                        History.EvaluateChange( familyChanges, familyAddress.LocationTypeName + " Is Map Location",
                            groupLocation.IsMappedLocation.ToString(), familyAddress.IsLocation.ToString() );
                        groupLocation.IsMappedLocation = familyAddress.IsLocation;

                        if ( updatedAddress != null )
                        {
                            History.EvaluateChange( familyChanges, familyAddress.LocationTypeName + " Location",
                                groupLocation.Location != null ? groupLocation.Location.ToString() : "", updatedAddress.ToString() );
                            groupLocation.Location = updatedAddress;
                        }

                        rockContext.SaveChanges();

                        // Add the same locations to any new families created by removing an existing family member
                        if ( newFamilies.Any() )
                        {
                            //reload grouplocation for access to child properties
                            groupLocation = groupLocationService.Get( groupLocation.Id );
                            foreach ( var newFamily in newFamilies )
                            {
                                var newFamilyLocation = new GroupLocation();
                                newFamilyLocation.GroupId = newFamily.Id;
                                newFamilyLocation.LocationId = groupLocation.LocationId;
                                newFamilyLocation.GroupLocationTypeValueId = groupLocation.GroupLocationTypeValueId;
                                newFamilyLocation.IsMailingLocation = groupLocation.IsMailingLocation;
                                newFamilyLocation.IsMappedLocation = groupLocation.IsMappedLocation;
                                groupLocationService.Add( newFamilyLocation );
                            }

                            rockContext.SaveChanges();
                        }
                    }

                    foreach ( var fm in _family.Members )
                    {
                        HistoryService.SaveChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_FAMILY_CHANGES.AsGuid(),
                            fm.PersonId, familyChanges, _family.Name, typeof( Group ), _family.Id );
                    }

                    _family = familyService.Get( _family.Id );
                    if ( _family.Members.Any( m => m.PersonId == Person.Id ) )
                    {
                        Response.Redirect( string.Format( "~/Person/{0}", Person.Id ), false );
                    }
                    else
                    {
                        var fm = _family.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 )
                            .FirstOrDefault();
                        if ( fm == null )
                        {
                            fm = _family.Members
                                .Where( m =>
                                    m.GroupRole.Guid.Equals( new Guid( Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT ) ) )
                                .OrderByDescending( m => m.Person.Age )
                                .FirstOrDefault();
                        }
                        if ( fm == null )
                        {
                            fm = _family.Members
                                .OrderByDescending( m => m.Person.Age )
                                .FirstOrDefault();
                        }
                        if ( fm != null )
                        {
                            Response.Redirect( string.Format( "~/Person/{0}", fm.PersonId ), false );
                        }
                        else
                        {
                            Response.Redirect( "~", false );
                        }
                    }

                } );
            }
        }
        /// <summary>
        /// Handles the Click event of the btnSave 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 btnSave_Click( object sender, EventArgs e )
        {
            using ( new UnitOfWorkScope() )
            {
                GroupLocationService groupLocationService = new GroupLocationService();
                ScheduleService scheduleService = new ScheduleService();

                RockTransactionScope.WrapTransaction( () =>
                {
                    var gridViewRows = gGroupLocationSchedule.Rows;
                    foreach ( GridViewRow row in gridViewRows.OfType<GridViewRow>() )
                    {
                        int groupLocationId = int.Parse( gGroupLocationSchedule.DataKeys[row.RowIndex].Value as string );
                        GroupLocation groupLocation = groupLocationService.Get( groupLocationId );
                        if ( groupLocation != null )
                        {
                            foreach ( var fieldCell in row.Cells.OfType<DataControlFieldCell>() )
                            {
                                CheckBoxEditableField checkBoxTemplateField = fieldCell.ContainingField as CheckBoxEditableField;
                                if ( checkBoxTemplateField != null )
                                {
                                    CheckBox checkBox = fieldCell.Controls[0] as CheckBox;
                                    string dataField = ( fieldCell.ContainingField as CheckBoxEditableField ).DataField;
                                    int scheduleId = int.Parse( dataField.Replace( "scheduleField_", string.Empty ) );

                                    // update GroupLocationSchedule depending on if the Schedule is Checked or not
                                    if ( checkBox.Checked )
                                    {
                                        // This schedule is selected, so if GroupLocationSchedule doesn't already have this schedule, add it
                                        if ( !groupLocation.Schedules.Any( a => a.Id == scheduleId ) )
                                        {
                                            var schedule = scheduleService.Get( scheduleId );
                                            groupLocation.Schedules.Add( schedule );
                                        }
                                    }
                                    else
                                    {
                                        // This schedule is not selected, so if GroupLocationSchedule has this schedule, delete it
                                        if ( groupLocation.Schedules.Any( a => a.Id == scheduleId ) )
                                        {
                                            groupLocation.Schedules.Remove( groupLocation.Schedules.FirstOrDefault( a => a.Id == scheduleId ) );
                                        }
                                    }
                                }
                            }

                            groupLocationService.Save( groupLocation, this.CurrentPersonId );
                        }
                    }

                } );
            }

            NavigateToParentPage();
        }
Exemple #3
0
        /// <summary>
        /// Handles the Click event of the btnSave 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 btnSave_Click( object sender, EventArgs e )
        {
            using ( var rockContext = new RockContext() )
            {
                GroupLocationService groupLocationService = new GroupLocationService( rockContext );
                ScheduleService scheduleService = new ScheduleService( rockContext );
                bool schedulesChanged = false;

                var gridViewRows = gGroupLocationSchedule.Rows;
                foreach ( GridViewRow row in gridViewRows.OfType<GridViewRow>() )
                {
                    int groupLocationId = int.Parse( gGroupLocationSchedule.DataKeys[row.RowIndex].Value as string );
                    GroupLocation groupLocation = groupLocationService.Get( groupLocationId );
                    if ( groupLocation != null )
                    {
                        foreach ( var fieldCell in row.Cells.OfType<DataControlFieldCell>() )
                        {
                            var checkBoxTemplateField = fieldCell.ContainingField as CheckBoxEditableField;
                            if ( checkBoxTemplateField != null )
                            {
                                CheckBox checkBox = fieldCell.Controls[0] as CheckBox;
                                string dataField = ( fieldCell.ContainingField as CheckBoxEditableField ).DataField;
                                int scheduleId = int.Parse( dataField.Replace( "scheduleField_", string.Empty ) );

                                // update GroupLocationSchedule depending on if the Schedule is Checked or not
                                if ( checkBox.Checked )
                                {
                                    // This schedule is selected, so if GroupLocationSchedule doesn't already have this schedule, add it
                                    if ( !groupLocation.Schedules.Any( a => a.Id == scheduleId ) )
                                    {
                                        var schedule = scheduleService.Get( scheduleId );
                                        groupLocation.Schedules.Add( schedule );
                                        schedulesChanged = true;
                                    }
                                }
                                else
                                {
                                    // This schedule is not selected, so if GroupLocationSchedule has this schedule, delete it
                                    if ( groupLocation.Schedules.Any( a => a.Id == scheduleId ) )
                                    {
                                        groupLocation.Schedules.Remove( groupLocation.Schedules.FirstOrDefault( a => a.Id == scheduleId ) );
                                        schedulesChanged = true;
                                    }
                                }
                            }
                        }
                    }
                }

                if ( schedulesChanged )
                {
                    rockContext.SaveChanges();
                    if ( this.CurrentKioskId.HasValue )
                    {
                        KioskDevice.Flush( this.CurrentKioskId.Value );
                    }
                }
            }

            NavigateToHomePage();
        }
Exemple #4
0
        /// <summary>
        /// Handles the Click event of the btnSave 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 btnSave_Click( object sender, EventArgs e )
        {
            // if a Location is getting edited, validate and save it
            if ( gLocations.EditIndex >= 0 )
            {
                var row = gLocations.Rows[gLocations.EditIndex];
                AddressControl acAddress = row.FindControl( "acAddress" ) as AddressControl;
                if ( acAddress.IsValid )
                {
                    gLocations_RowUpdating( sender, new GridViewUpdateEventArgs( gLocations.EditIndex ) );
                }
                else
                {
                    // acAddress will render an error message
                    return;
                }
            }

            if ( !IsUserAuthorized( Rock.Security.Authorization.EDIT ) )
            {
                return;
            }

            // confirmation was disabled by btnSave on client-side.  So if returning without a redirect,
            // it should be enabled.  If returning with a redirect, the control won't be updated to reflect
            // confirmation being enabled, so it's ok to enable it here
            confirmExit.Enabled = true;

            if ( Page.IsValid )
            {
                confirmExit.Enabled = true;

                var rockContext = new RockContext();
                rockContext.WrapTransaction( () =>
                {
                    var groupService = new GroupService( rockContext );
                    var groupMemberService = new GroupMemberService( rockContext );
                    var personService = new PersonService( rockContext );
                    var historyService = new HistoryService( rockContext );

                    var groupChanges = new List<string>();

                    // SAVE GROUP
                    _group = groupService.Get( _group.Id );

                    History.EvaluateChange( groupChanges, "Group Name", _group.Name, tbGroupName.Text );
                    _group.Name = tbGroupName.Text;

                    int? campusId = cpCampus.SelectedValueAsInt();
                    if ( _group.CampusId != campusId )
                    {
                        History.EvaluateChange(
                            groupChanges,
                            "Campus",
                            _group.CampusId.HasValue ? CampusCache.Read( _group.CampusId.Value ).Name : string.Empty,
                            campusId.HasValue ? CampusCache.Read( campusId.Value ).Name : string.Empty );

                        _group.CampusId = campusId;
                    }

                    rockContext.SaveChanges();

                    // SAVE GROUP MEMBERS
                    int? recordStatusValueID = ddlRecordStatus.SelectedValueAsInt();
                    int? reasonValueId = ddlReason.SelectedValueAsInt();
                    var newGroups = new List<Group>();

                    foreach ( var groupMemberInfo in GroupMembers )
                    {
                        var memberChanges = new List<string>();
                        var demographicChanges = new List<string>();

                        var role = _groupType.Roles.Where( r => r.Guid.Equals( groupMemberInfo.RoleGuid ) ).FirstOrDefault();
                        if ( role == null )
                        {
                            role = _groupType.Roles.FirstOrDefault();
                        }

                        bool isAdult = role != null && role.Guid.Equals( Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT );

                        // People added to group (new or from other group )
                        if ( !groupMemberInfo.ExistingGroupMember )
                        {
                            Person person = null;
                            if ( groupMemberInfo.Id == -1 )
                            {
                                // added new person
                                demographicChanges.Add( "Created" );

                                person = new Person();

                                person.TitleValueId = groupMemberInfo.TitleValueId;
                                person.FirstName = groupMemberInfo.FirstName;
                                person.NickName = groupMemberInfo.NickName;
                                person.LastName = groupMemberInfo.LastName;
                                person.SuffixValueId = groupMemberInfo.SuffixValueId;
                                person.Gender = groupMemberInfo.Gender;

                                DateTime? birthdate = groupMemberInfo.BirthDate;
                                if ( birthdate.HasValue )
                                {
                                    // If setting a future birthdate, subtract a century until birthdate is not greater than today.
                                    var today = RockDateTime.Today;
                                    while ( birthdate.Value.CompareTo( today ) > 0 )
                                    {
                                        birthdate = birthdate.Value.AddYears( -100 );
                                    }
                                }

                                person.SetBirthDate( birthdate );

                                person.MaritalStatusValueId = groupMemberInfo.MaritalStatusValueId;
                                person.GradeOffset = groupMemberInfo.GradeOffset;
                                person.ConnectionStatusValueId = groupMemberInfo.ConnectionStatusValueId;
                                if ( isAdult )
                                {
                                    person.GivingGroupId = _group.Id;
                                }

                                person.IsEmailActive = true;
                                person.EmailPreference = EmailPreference.EmailAllowed;
                                person.RecordTypeValueId = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_PERSON.AsGuid() ).Id;
                            }
                            else
                            {
                                person = personService.Get( groupMemberInfo.Id );
                            }

                            if ( person == null )
                            {
                                // shouldn't happen
                                return;
                            }

                            if ( _isFamilyGroupType )
                            {
                                if ( person.RecordStatusValueId != recordStatusValueID )
                                {
                                    History.EvaluateChange( demographicChanges, "Record Status", DefinedValueCache.GetName( person.RecordStatusValueId ), DefinedValueCache.GetName( recordStatusValueID ) );
                                    person.RecordStatusValueId = recordStatusValueID;
                                }

                                if ( person.RecordStatusValueId != recordStatusValueID )
                                {
                                    History.EvaluateChange( demographicChanges, "Record Status Reason", DefinedValueCache.GetName( person.RecordStatusReasonValueId ), DefinedValueCache.GetName( reasonValueId ) );
                                    person.RecordStatusReasonValueId = reasonValueId;
                                }
                            }

                            PersonService.AddPersonToGroup( person, person.Id == 0, _group.Id, role.Id, rockContext );
                        }
                        else
                        {
                            // existing group members
                            var groupMember = groupMemberService.Queryable( "Person", true ).Where( m =>
                                m.PersonId == groupMemberInfo.Id &&
                                m.Group.GroupTypeId == _groupType.Id &&
                                m.GroupId == _group.Id ).FirstOrDefault();

                            if ( groupMember != null )
                            {
                                if ( groupMemberInfo.Removed )
                                {
                                    if ( !groupMemberInfo.IsInOtherGroups )
                                    {
                                        var newFamilyChanges = new List<string>();

                                        // Family member was removed and should be created in their own new family
                                        var newGroup = new Group();
                                        newGroup.Name = groupMemberInfo.LastName + " " + _groupType.Name;
                                        History.EvaluateChange( newFamilyChanges, "Family", string.Empty, newGroup.Name );

                                        newGroup.GroupTypeId = _groupType.Id;

                                        if ( _group.CampusId.HasValue )
                                        {
                                            History.EvaluateChange( newFamilyChanges, "Campus", string.Empty, CampusCache.Read( _group.CampusId.Value ).Name );
                                        }

                                        newGroup.CampusId = _group.CampusId;

                                        groupService.Add( newGroup );
                                        rockContext.SaveChanges();

                                        // If person's previous giving group was this family, set it to their new family id
                                        if ( _isFamilyGroupType && groupMember.Person.GivingGroup != null && groupMember.Person.GivingGroupId == _group.Id )
                                        {
                                            History.EvaluateChange( demographicChanges, "Giving Group", groupMember.Person.GivingGroup.Name, _group.Name );
                                            groupMember.Person.GivingGroupId = newGroup.Id;
                                        }

                                        groupMember.Group = newGroup;
                                        rockContext.SaveChanges();

                                        var newMemberChanges = new List<string>();

                                        if ( _isFamilyGroupType )
                                        {
                                            History.EvaluateChange( newMemberChanges, "Role", string.Empty, groupMember.GroupRole.Name );

                                            HistoryService.SaveChanges(
                                                rockContext,
                                                typeof( Person ),
                                                Rock.SystemGuid.Category.HISTORY_PERSON_FAMILY_CHANGES.AsGuid(),
                                                groupMember.Person.Id,
                                                newFamilyChanges,
                                                newGroup.Name,
                                                typeof( Group ),
                                                newGroup.Id );
                                        }
                                        newGroups.Add( newGroup );

                                        History.EvaluateChange( memberChanges, "Role", groupMember.GroupRole.Name, string.Empty );
                                    }
                                    else
                                    {
                                        History.EvaluateChange( groupChanges, "Family", groupMember.Group.Name, string.Empty );

                                        groupMemberService.Delete( groupMember );
                                        rockContext.SaveChanges();
                                    }
                                }
                                else
                                {
                                    // Existing member was not remvoved
                                    if ( role != null )
                                    {
                                        History.EvaluateChange( memberChanges, "Role", groupMember.GroupRole != null ? groupMember.GroupRole.Name : string.Empty, role.Name );
                                        groupMember.GroupRoleId = role.Id;

                                        if ( _isFamilyGroupType )
                                        {
                                            if ( recordStatusValueID > 0 )
                                            {
                                                History.EvaluateChange( demographicChanges, "Record Status", DefinedValueCache.GetName( groupMember.Person.RecordStatusValueId ), DefinedValueCache.GetName( recordStatusValueID ) );
                                                groupMember.Person.RecordStatusValueId = recordStatusValueID;

                                                History.EvaluateChange( demographicChanges, "Record Status Reason", DefinedValueCache.GetName( groupMember.Person.RecordStatusReasonValueId ), DefinedValueCache.GetName( reasonValueId ) );
                                                groupMember.Person.RecordStatusReasonValueId = reasonValueId;
                                            }
                                        }

                                        rockContext.SaveChanges();
                                    }
                                }
                            }
                        }

                        // Remove anyone that was moved from another family
                        if ( groupMemberInfo.RemoveFromOtherGroups )
                        {
                            PersonService.RemovePersonFromOtherFamilies( _group.Id, groupMemberInfo.Id, rockContext );
                        }

                        HistoryService.SaveChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_DEMOGRAPHIC_CHANGES.AsGuid(), groupMemberInfo.Id, demographicChanges );

                        if ( _isFamilyGroupType )
                        {
                            HistoryService.SaveChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_FAMILY_CHANGES.AsGuid(), groupMemberInfo.Id, memberChanges, _group.Name, typeof( Group ), _group.Id );
                        }
                    }

                    // SAVE LOCATIONS
                    var groupLocationService = new GroupLocationService( rockContext );

                    // delete any group locations that were removed
                    var remainingLocationIds = GroupAddresses.Where( a => a.Id > 0 ).Select( a => a.Id ).ToList();
                    foreach ( var removedLocation in groupLocationService.Queryable( "GroupLocationTypeValue,Location" )
                        .Where( l => l.GroupId == _group.Id &&
                            !remainingLocationIds.Contains( l.Id ) ) )
                    {
                        History.EvaluateChange( groupChanges,
                            ( removedLocation.GroupLocationTypeValue != null ? removedLocation.GroupLocationTypeValue.Value : "Unknown" ) + " Location",
                            removedLocation.Location.ToString(), string.Empty );
                        groupLocationService.Delete( removedLocation );
                    }

                    rockContext.SaveChanges();

                    foreach ( var groupAddressInfo in GroupAddresses.Where( a => a.Id >= 0 ) )
                    {
                        Location updatedAddress = null;
                        if ( groupAddressInfo.LocationIsDirty )
                        {
                            updatedAddress = new LocationService( rockContext ).Get( groupAddressInfo.Street1, groupAddressInfo.Street2, groupAddressInfo.City, groupAddressInfo.State, groupAddressInfo.PostalCode, groupAddressInfo.Country );
                        }

                        GroupLocation groupLocation = null;
                        if ( groupAddressInfo.Id > 0 )
                        {
                            groupLocation = groupLocationService.Get( groupAddressInfo.Id );
                        }

                        if ( groupLocation == null )
                        {
                            groupLocation = new GroupLocation();
                            groupLocation.GroupId = _group.Id;
                            groupLocationService.Add( groupLocation );
                        }

                        History.EvaluateChange(
                            groupChanges,
                            "Location Type",
                            groupLocation.GroupLocationTypeValueId.HasValue ? DefinedValueCache.Read( groupLocation.GroupLocationTypeValueId.Value ).Value : string.Empty,
                            groupAddressInfo.LocationTypeName );
                        groupLocation.GroupLocationTypeValueId = groupAddressInfo.LocationTypeId;

                        History.EvaluateChange(
                            groupChanges,
                            groupAddressInfo.LocationTypeName + " Is Mailing",
                            groupLocation.IsMailingLocation.ToString(),
                            groupAddressInfo.IsMailing.ToString() );

                        groupLocation.IsMailingLocation = groupAddressInfo.IsMailing;

                        History.EvaluateChange(
                            groupChanges,
                            groupAddressInfo.LocationTypeName + " Is Map Location",
                            groupLocation.IsMappedLocation.ToString(),
                            groupAddressInfo.IsLocation.ToString() );

                        groupLocation.IsMappedLocation = groupAddressInfo.IsLocation;

                        if ( updatedAddress != null )
                        {
                            History.EvaluateChange(
                                groupChanges,
                                groupAddressInfo.LocationTypeName + " Location",
                                groupLocation.Location != null ? groupLocation.Location.ToString() : string.Empty,
                                updatedAddress.ToString() );
                            groupLocation.Location = updatedAddress;
                        }

                        rockContext.SaveChanges();

                        // Add the same locations to any new families created by removing an existing family member
                        if ( newGroups.Any() )
                        {
                            // reload grouplocation for access to child properties
                            groupLocation = groupLocationService.Get( groupLocation.Id );
                            foreach ( var newGroup in newGroups )
                            {
                                var newGroupLocation = new GroupLocation();
                                newGroupLocation.GroupId = newGroup.Id;
                                newGroupLocation.LocationId = groupLocation.LocationId;
                                newGroupLocation.GroupLocationTypeValueId = groupLocation.GroupLocationTypeValueId;
                                newGroupLocation.IsMailingLocation = groupLocation.IsMailingLocation;
                                newGroupLocation.IsMappedLocation = groupLocation.IsMappedLocation;
                                groupLocationService.Add( newGroupLocation );
                            }

                            rockContext.SaveChanges();
                        }
                    }

                    _group.LoadAttributes();
                    Rock.Attribute.Helper.GetEditValues( phGroupAttributes, _group );
                    _group.SaveAttributeValues( rockContext );

                    if ( _isFamilyGroupType )
                    {
                        foreach ( var fm in _group.Members )
                        {
                            HistoryService.SaveChanges(
                                rockContext,
                                typeof( Person ),
                                Rock.SystemGuid.Category.HISTORY_PERSON_FAMILY_CHANGES.AsGuid(),
                                fm.PersonId,
                                groupChanges,
                                _group.Name,
                                typeof( Group ),
                                _group.Id );
                        }
                    }

                    Response.Redirect( string.Format( "~/Person/{0}", Person.Id ), false );

                } );
            }
        }