/// <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 );
                        }
                    }

                } );
            }
        }
Exemple #2
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 )
        {
            var rockContext = new RockContext();
            rockContext.WrapTransaction( () =>
            {
                var personService = new PersonService( rockContext );

                var changes = new List<string>();

                var person = personService.Get( CurrentPersonId ?? 0 );
                if ( person != null )
                {
                    int? orphanedPhotoId = null;
                    if ( person.PhotoId != imgPhoto.BinaryFileId )
                    {
                        orphanedPhotoId = person.PhotoId;
                        person.PhotoId = imgPhoto.BinaryFileId;

                        if ( orphanedPhotoId.HasValue )
                        {
                            if ( person.PhotoId.HasValue )
                            {
                                changes.Add( "Modified the photo." );
                            }
                            else
                            {
                                changes.Add( "Deleted the photo." );
                            }
                        }
                        else if ( person.PhotoId.HasValue )
                        {
                            changes.Add( "Added a photo." );
                        }
                    }

                    int? newTitleId = ddlTitle.SelectedValueAsInt();
                    History.EvaluateChange( changes, "Title", DefinedValueCache.GetName( person.TitleValueId ), DefinedValueCache.GetName( newTitleId ) );
                    person.TitleValueId = newTitleId;

                    History.EvaluateChange( changes, "First Name", person.FirstName, tbFirstName.Text );
                    person.FirstName = tbFirstName.Text;

                    History.EvaluateChange(changes, "Nick Name", person.NickName, tbNickName.Text);
                    person.NickName = tbNickName.Text;

                    History.EvaluateChange( changes, "Last Name", person.LastName, tbLastName.Text );
                    person.LastName = tbLastName.Text;

                    int? newSuffixId = ddlSuffix.SelectedValueAsInt();
                    History.EvaluateChange( changes, "Suffix", DefinedValueCache.GetName( person.SuffixValueId ), DefinedValueCache.GetName( newSuffixId ) );
                    person.SuffixValueId = newSuffixId;

                    var birthMonth = person.BirthMonth;
                    var birthDay = person.BirthDay;
                    var birthYear = person.BirthYear;

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

                        person.BirthMonth = birthday.Value.Month;
                        person.BirthDay = birthday.Value.Day;
                        if ( birthday.Value.Year != DateTime.MinValue.Year )
                        {
                            person.BirthYear = birthday.Value.Year;
                        }
                        else
                        {
                            person.BirthYear = null;
                        }
                    }
                    else
                    {
                        person.SetBirthDate( null );
                    }

                    History.EvaluateChange( changes, "Birth Month", birthMonth, person.BirthMonth );
                    History.EvaluateChange( changes, "Birth Day", birthDay, person.BirthDay );
                    History.EvaluateChange( changes, "Birth Year", birthYear, person.BirthYear );

                    var newGender = rblGender.SelectedValue.ConvertToEnum<Gender>();
                    History.EvaluateChange( changes, "Gender", person.Gender, newGender );
                    person.Gender = newGender;

                    var phoneNumberTypeIds = new List<int>();

                    bool smsSelected = false;

                    foreach ( RepeaterItem item in rContactInfo.Items )
                    {
                        HiddenField hfPhoneType = item.FindControl( "hfPhoneType" ) as HiddenField;
                        PhoneNumberBox pnbPhone = item.FindControl( "pnbPhone" ) as PhoneNumberBox;
                        CheckBox cbUnlisted = item.FindControl( "cbUnlisted" ) as CheckBox;
                        CheckBox cbSms = item.FindControl( "cbSms" ) as CheckBox;

                        if ( hfPhoneType != null &&
                            pnbPhone != null &&
                            cbSms != null &&
                            cbUnlisted != null )
                        {
                            if ( !string.IsNullOrWhiteSpace( PhoneNumber.CleanNumber( pnbPhone.Number ) ) )
                            {
                                int phoneNumberTypeId;
                                if ( int.TryParse( hfPhoneType.Value, out phoneNumberTypeId ) )
                                {
                                    var phoneNumber = person.PhoneNumbers.FirstOrDefault( n => n.NumberTypeValueId == phoneNumberTypeId );
                                    string oldPhoneNumber = string.Empty;
                                    if ( phoneNumber == null )
                                    {
                                        phoneNumber = new PhoneNumber { NumberTypeValueId = phoneNumberTypeId };
                                        person.PhoneNumbers.Add( phoneNumber );
                                    }
                                    else
                                    {
                                        oldPhoneNumber = phoneNumber.NumberFormattedWithCountryCode;
                                    }

                                    phoneNumber.CountryCode = PhoneNumber.CleanNumber( pnbPhone.CountryCode );
                                    phoneNumber.Number = PhoneNumber.CleanNumber( pnbPhone.Number );

                                    // Only allow one number to have SMS selected
                                    if ( smsSelected )
                                    {
                                        phoneNumber.IsMessagingEnabled = false;
                                    }
                                    else
                                    {
                                        phoneNumber.IsMessagingEnabled = cbSms.Checked;
                                        smsSelected = cbSms.Checked;
                                    }

                                    phoneNumber.IsUnlisted = cbUnlisted.Checked;
                                    phoneNumberTypeIds.Add( phoneNumberTypeId );

                                    History.EvaluateChange(
                                        changes,
                                        string.Format( "{0} Phone", DefinedValueCache.GetName( phoneNumberTypeId ) ),
                                        oldPhoneNumber,
                                        phoneNumber.NumberFormattedWithCountryCode );
                                }
                            }
                        }
                    }

                    // Remove any blank numbers
                    var phoneNumberService = new PhoneNumberService( rockContext );
                    foreach ( var phoneNumber in person.PhoneNumbers
                        .Where( n => n.NumberTypeValueId.HasValue && !phoneNumberTypeIds.Contains( n.NumberTypeValueId.Value ) )
                        .ToList() )
                    {
                        History.EvaluateChange(
                            changes,
                            string.Format( "{0} Phone", DefinedValueCache.GetName( phoneNumber.NumberTypeValueId ) ),
                            phoneNumber.ToString(),
                            string.Empty );

                        person.PhoneNumbers.Remove( phoneNumber );
                        phoneNumberService.Delete( phoneNumber );
                    }

                    History.EvaluateChange( changes, "Email", person.Email, tbEmail.Text );
                    person.Email = tbEmail.Text.Trim();

                    var newEmailPreference = rblEmailPreference.SelectedValue.ConvertToEnum<EmailPreference>();
                    History.EvaluateChange( changes, "Email Preference", person.EmailPreference, newEmailPreference );
                    person.EmailPreference = newEmailPreference;

                    if ( person.IsValid )
                    {
                        if ( rockContext.SaveChanges() > 0 )
                        {
                            if ( changes.Any() )
                            {
                                HistoryService.SaveChanges(
                                    rockContext,
                                    typeof( Person ),
                                    Rock.SystemGuid.Category.HISTORY_PERSON_DEMOGRAPHIC_CHANGES.AsGuid(),
                                    person.Id,
                                    changes );
                            }

                            if ( orphanedPhotoId.HasValue )
                            {
                                BinaryFileService binaryFileService = new BinaryFileService( rockContext );
                                var binaryFile = binaryFileService.Get( orphanedPhotoId.Value );
                                if ( binaryFile != null )
                                {
                                    // marked the old images as IsTemporary so they will get cleaned up later
                                    binaryFile.IsTemporary = true;
                                    rockContext.SaveChanges();
                                }
                            }

                            // if they used the ImageEditor, and cropped it, the uncropped file is still in BinaryFile. So clean it up
                            if ( imgPhoto.CropBinaryFileId.HasValue )
                            {
                                if ( imgPhoto.CropBinaryFileId != person.PhotoId )
                                {
                                    BinaryFileService binaryFileService = new BinaryFileService( rockContext );
                                    var binaryFile = binaryFileService.Get( imgPhoto.CropBinaryFileId.Value );
                                    if ( binaryFile != null && binaryFile.IsTemporary )
                                    {
                                        string errorMessage;
                                        if ( binaryFileService.CanDelete( binaryFile, out errorMessage ) )
                                        {
                                            binaryFileService.Delete( binaryFile );
                                            rockContext.SaveChanges();
                                        }
                                    }
                                }
                            }
                        }

                        // save address
                        if ( pnlAddress.Visible )
                        {
                            Guid? familyGroupTypeGuid = Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY.AsGuidOrNull();
                            if ( familyGroupTypeGuid.HasValue )
                            {
                                var familyGroup = new GroupService( rockContext ).Queryable()
                                                .Where( f => f.GroupType.Guid == familyGroupTypeGuid.Value
                                                    && f.Members.Any( m => m.PersonId == person.Id ) )
                                                .FirstOrDefault();
                                if ( familyGroup != null )
                                {
                                    Guid? addressTypeGuid = GetAttributeValue("LocationType").AsGuidOrNull();
                                    if ( addressTypeGuid.HasValue )
                                    {
                                        var groupLocationService = new GroupLocationService( rockContext );

                                        var dvHomeAddressType = DefinedValueCache.Read( addressTypeGuid.Value );
                                        var familyAddress = groupLocationService.Queryable().Where( l => l.GroupId == familyGroup.Id && l.GroupLocationTypeValueId == dvHomeAddressType.Id ).FirstOrDefault();
                                        if ( familyAddress != null && string.IsNullOrWhiteSpace( acAddress.Street1 ) )
                                        {
                                            // delete the current address
                                            History.EvaluateChange( changes, familyAddress.GroupLocationTypeValue.Value + " Location", familyAddress.Location.ToString(), string.Empty );
                                            groupLocationService.Delete( familyAddress );
                                            rockContext.SaveChanges();
                                        }
                                        else
                                        {
                                            if ( !string.IsNullOrWhiteSpace( acAddress.Street1 ) )
                                            {
                                                if ( familyAddress == null )
                                                {
                                                    familyAddress = new GroupLocation();
                                                    groupLocationService.Add( familyAddress );
                                                    familyAddress.GroupLocationTypeValueId = dvHomeAddressType.Id;
                                                    familyAddress.GroupId = familyGroup.Id;
                                                    familyAddress.IsMailingLocation = true;
                                                    familyAddress.IsMappedLocation = true;
                                                }
                                                else if ( hfStreet1.Value != string.Empty ) {

                                                    // user clicked move so create a previous address
                                                    var previousAddress = new GroupLocation();
                                                    groupLocationService.Add( previousAddress );

                                                    var previousAddressValue = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_PREVIOUS.AsGuid() );
                                                    if ( previousAddressValue  != null )
                                                    {
                                                        previousAddress.GroupLocationTypeValueId = previousAddressValue.Id;
                                                        previousAddress.GroupId = familyGroup.Id;

                                                        Location previousAddressLocation = new Location();
                                                        previousAddressLocation.Street1 = hfStreet1.Value;
                                                        previousAddressLocation.Street2 = hfStreet2.Value;
                                                        previousAddressLocation.City = hfCity.Value;
                                                        previousAddressLocation.State = hfState.Value;
                                                        previousAddressLocation.PostalCode = hfPostalCode.Value;
                                                        previousAddressLocation.Country = hfCountry.Value;

                                                        previousAddress.Location = previousAddressLocation;
                                                    }
                                                }

                                                familyAddress.IsMailingLocation = cbIsMailingAddress.Checked;
                                                familyAddress.IsMappedLocation = cbIsPhysicalAddress.Checked;

                                                var updatedHomeAddress = new Location();
                                                acAddress.GetValues( updatedHomeAddress );

                                                History.EvaluateChange( changes, dvHomeAddressType.Value + " Location", familyAddress.Location != null ? familyAddress.Location.ToString() : string.Empty, updatedHomeAddress.ToString() );

                                                familyAddress.Location = updatedHomeAddress;
                                                rockContext.SaveChanges();
                                            }
                                        }

                                        HistoryService.SaveChanges(
                                            rockContext,
                                            typeof( Person ),
                                            Rock.SystemGuid.Category.HISTORY_PERSON_DEMOGRAPHIC_CHANGES.AsGuid(),
                                            person.Id,
                                            changes );
                                    }
                                }
                            }
                        }

                        NavigateToParentPage();
                    }
                }
            } );
        }
Exemple #3
0
        /// <summary>
        /// Generic method to delete the members of a group and then the group.
        /// </summary>
        /// <param name="group">The group.</param>
        /// <param name="rockContext">The rock context.</param>
        /// <exception cref="System.InvalidOperationException">Unable to delete group:  + group.Name</exception>
        private void DeleteGroupAndMemberData( Group group, RockContext rockContext )
        {
            GroupService groupService = new GroupService( rockContext );

            // delete addresses
            GroupLocationService groupLocationService = new GroupLocationService( rockContext );
            if ( group.GroupLocations.Count > 0 )
            {
                foreach ( var groupLocations in group.GroupLocations.ToList() )
                {
                    group.GroupLocations.Remove( groupLocations );
                    groupLocationService.Delete( groupLocations );
                }
            }

            // delete members
            var groupMemberService = new GroupMemberService( rockContext );
            var members = group.Members;
            foreach ( var member in members.ToList() )
            {
                group.Members.Remove( member );
                groupMemberService.Delete( member );
            }

            // delete attribute values
            group.LoadAttributes( rockContext );
            if ( group.AttributeValues != null )
            {
                var attributeValueService = new AttributeValueService( rockContext );
                foreach ( var entry in group.AttributeValues )
                {
                    var attributeValue = attributeValueService.GetByAttributeIdAndEntityId( entry.Value.AttributeId, group.Id );
                    if ( attributeValue != null )
                    {
                        attributeValueService.Delete( attributeValue );
                    }
                }
            }

            // now delete the group
            if ( groupService.Delete( group ) )
            {
                // ok
            }
            else
            {
                throw new InvalidOperationException( "Unable to delete group: " + group.Name );
            }
        }
        /// <summary>
        /// Handles the Click event of the lbSave 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 lbSave_Click( object sender, EventArgs e )
        {
            var rockContext = new RockContext();
            rockContext.WrapTransaction( () =>
            {
                var personService = new PersonService( rockContext );
                var changes = new List<string>();
                Person business = null;

                if ( int.Parse( hfBusinessId.Value ) != 0 )
                {
                    business = personService.Get( int.Parse( hfBusinessId.Value ) );
                }

                if ( business == null )
                {
                    business = new Person();
                    personService.Add( business );
                }

                // Business Name
                History.EvaluateChange( changes, "Last Name", business.LastName, tbBusinessName.Text );
                business.LastName = tbBusinessName.Text;

                // Phone Number
                var businessPhoneTypeId = new DefinedValueService( rockContext ).GetByGuid( new Guid( Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_WORK ) ).Id;

                string oldPhoneNumber = string.Empty;
                string newPhoneNumber = string.Empty;

                var phoneNumber = business.PhoneNumbers.FirstOrDefault( n => n.NumberTypeValueId == businessPhoneTypeId );
                if ( phoneNumber != null )
                {
                    oldPhoneNumber = phoneNumber.NumberFormattedWithCountryCode;
                }

                if ( !string.IsNullOrWhiteSpace( PhoneNumber.CleanNumber( pnbPhone.Number ) ) )
                {
                    if ( phoneNumber == null )
                    {
                        phoneNumber = new PhoneNumber { NumberTypeValueId = businessPhoneTypeId };
                        business.PhoneNumbers.Add( phoneNumber );
                    }
                    phoneNumber.CountryCode = PhoneNumber.CleanNumber( pnbPhone.CountryCode );
                    phoneNumber.Number = PhoneNumber.CleanNumber( pnbPhone.Number );
                    phoneNumber.IsMessagingEnabled = cbSms.Checked;
                    phoneNumber.IsUnlisted = cbUnlisted.Checked;

                    newPhoneNumber = phoneNumber.NumberFormattedWithCountryCode;
                }
                else
                {
                    if ( phoneNumber != null )
                    {
                        business.PhoneNumbers.Remove( phoneNumber );
                        new PhoneNumberService( rockContext ).Delete( phoneNumber );
                    }
                }

                History.EvaluateChange(
                    changes,
                    string.Format( "{0} Phone", DefinedValueCache.GetName( businessPhoneTypeId ) ),
                    oldPhoneNumber,
                    newPhoneNumber );

                // Record Type - this is always "business". it will never change.
                business.RecordTypeValueId = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.PERSON_RECORD_TYPE_BUSINESS.AsGuid() ).Id;

                // Record Status
                int? newRecordStatusId = ddlRecordStatus.SelectedValueAsInt();
                History.EvaluateChange( changes, "Record Status", DefinedValueCache.GetName( business.RecordStatusValueId ), DefinedValueCache.GetName( newRecordStatusId ) );
                business.RecordStatusValueId = newRecordStatusId;

                // Record Status Reason
                int? newRecordStatusReasonId = null;
                if ( business.RecordStatusValueId.HasValue && business.RecordStatusValueId.Value == DefinedValueCache.Read( new Guid( Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_INACTIVE ) ).Id )
                {
                    newRecordStatusReasonId = ddlReason.SelectedValueAsInt();
                }

                History.EvaluateChange( changes, "Record Status Reason", DefinedValueCache.GetName( business.RecordStatusReasonValueId ), DefinedValueCache.GetName( newRecordStatusReasonId ) );
                business.RecordStatusReasonValueId = newRecordStatusReasonId;

                // Email
                business.IsEmailActive = true;
                History.EvaluateChange( changes, "Email", business.Email, tbEmail.Text );
                business.Email = tbEmail.Text.Trim();

                var newEmailPreference = rblEmailPreference.SelectedValue.ConvertToEnum<EmailPreference>();
                History.EvaluateChange( changes, "EmailPreference", business.EmailPreference, newEmailPreference );
                business.EmailPreference = newEmailPreference;

                if ( business.IsValid )
                {
                    if ( rockContext.SaveChanges() > 0 )
                    {
                        if ( changes.Any() )
                        {
                            HistoryService.SaveChanges(
                                rockContext,
                                typeof( Person ),
                                Rock.SystemGuid.Category.HISTORY_PERSON_DEMOGRAPHIC_CHANGES.AsGuid(),
                                business.Id,
                                changes );
                        }
                    }
                }

                // Add/Update Family Group
                var familyGroupType = GroupTypeCache.GetFamilyGroupType();
                int adultRoleId = familyGroupType.Roles
                    .Where( r => r.Guid.Equals( Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT.AsGuid() ) )
                    .Select( r => r.Id )
                    .FirstOrDefault();
                var adultFamilyMember = UpdateGroupMember( business.Id, familyGroupType, business.LastName + " Business", ddlCampus.SelectedValueAsInt(), adultRoleId, rockContext );
                business.GivingGroup = adultFamilyMember.Group;

                // Add/Update Known Relationship Group Type
                var knownRelationshipGroupType = GroupTypeCache.Read( Rock.SystemGuid.GroupType.GROUPTYPE_KNOWN_RELATIONSHIPS.AsGuid() );
                int knownRelationshipOwnerRoleId = knownRelationshipGroupType.Roles
                    .Where( r => r.Guid.Equals( Rock.SystemGuid.GroupRole.GROUPROLE_KNOWN_RELATIONSHIPS_OWNER.AsGuid() ) )
                    .Select( r => r.Id )
                    .FirstOrDefault();
                var knownRelationshipOwner = UpdateGroupMember( business.Id, knownRelationshipGroupType, "Known Relationship", null, knownRelationshipOwnerRoleId, rockContext );

                // Add/Update Implied Relationship Group Type
                var impliedRelationshipGroupType = GroupTypeCache.Read( Rock.SystemGuid.GroupType.GROUPTYPE_IMPLIED_RELATIONSHIPS.AsGuid() );
                int impliedRelationshipOwnerRoleId = impliedRelationshipGroupType.Roles
                    .Where( r => r.Guid.Equals( Rock.SystemGuid.GroupRole.GROUPROLE_IMPLIED_RELATIONSHIPS_OWNER.AsGuid() ) )
                    .Select( r => r.Id )
                    .FirstOrDefault();
                var impliedRelationshipOwner = UpdateGroupMember( business.Id, impliedRelationshipGroupType, "Implied Relationship", null, impliedRelationshipOwnerRoleId, rockContext );

                rockContext.SaveChanges();

                // Every business should have an alias record with same id.  If it's missing, create it
                if ( !business.Aliases.Any( a => a.AliasPersonId == business.Id ) )
                {
                    // refetch the business to make sure we have an Id
                    business = personService.Get( business.Id );
                    if ( business != null )
                    {
                        business.Aliases.Add( new PersonAlias { AliasPersonId = business.Id, AliasPersonGuid = business.Guid } );
                        rockContext.SaveChanges();
                    }
                }

                // Location
                int workLocationTypeId = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.GROUP_LOCATION_TYPE_WORK ).Id;

                var groupLocationService = new GroupLocationService( rockContext );
                var workLocation = groupLocationService.Queryable( "Location" )
                    .Where( gl =>
                        gl.GroupId == adultFamilyMember.Group.Id &&
                        gl.GroupLocationTypeValueId == workLocationTypeId )
                    .FirstOrDefault();

                if ( string.IsNullOrWhiteSpace( acAddress.Street1 ) )
                {
                    if ( workLocation != null )
                    {
                        groupLocationService.Delete( workLocation );
                        History.EvaluateChange( changes, "Address", workLocation.Location.ToString(), string.Empty );
                    }
                }
                else
                {
                    var oldValue = string.Empty;

                    var newLocation = new LocationService( rockContext ).Get(
                        acAddress.Street1, acAddress.Street2, acAddress.City, acAddress.State, acAddress.PostalCode, acAddress.Country );

                    if ( workLocation != null )
                    {
                        oldValue = workLocation.Location.ToString();
                    }
                    else
                    {
                        workLocation = new GroupLocation();
                        groupLocationService.Add( workLocation );
                        workLocation.GroupId = adultFamilyMember.Group.Id;
                        workLocation.GroupLocationTypeValueId = workLocationTypeId;
                    }
                    workLocation.Location = newLocation;

                    History.EvaluateChange( changes, "Address", oldValue, newLocation.ToString() );
                }

                rockContext.SaveChanges();

                hfBusinessId.Value = business.Id.ToString();
            } );

            ShowSummary( hfBusinessId.Value.AsInteger() );
        }
        /// <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 )
        {
            bool hasValidationErrors = false;

            var rockContext = new RockContext();

            GroupTypeService groupTypeService = new GroupTypeService( rockContext );
            GroupService groupService = new GroupService( rockContext );
            AttributeService attributeService = new AttributeService( rockContext );
            GroupLocationService groupLocationService = new GroupLocationService( rockContext );

            int parentGroupTypeId = hfParentGroupTypeId.ValueAsInt();

            var groupTypeUIList = new List<GroupType>();

            foreach ( var checkinGroupTypeEditor in phCheckinGroupTypes.Controls.OfType<CheckinGroupTypeEditor>().ToList() )
            {
                var groupType = checkinGroupTypeEditor.GetCheckinGroupType( rockContext );
                groupTypeUIList.Add( groupType );
            }

            var groupTypeDBList = new List<GroupType>();

            var groupTypesToDelete = new List<GroupType>();
            var groupsToDelete = new List<Group>();

            var groupTypesToAddUpdate = new List<GroupType>();
            var groupsToAddUpdate = new List<Group>();

            GroupType parentGroupTypeDB = groupTypeService.Get( parentGroupTypeId );
            GroupType parentGroupTypeUI = parentGroupTypeDB.Clone( false );
            parentGroupTypeUI.ChildGroupTypes = groupTypeUIList;

            PopulateDeleteLists( groupTypesToDelete, groupsToDelete, parentGroupTypeDB, parentGroupTypeUI );
            PopulateAddUpdateLists( groupTypesToAddUpdate, groupsToAddUpdate, parentGroupTypeUI );

            int binaryFileFieldTypeID = FieldTypeCache.Read( Rock.SystemGuid.FieldType.BINARY_FILE.AsGuid() ).Id;

            rockContext.WrapTransaction( () =>
            {
                // delete in reverse order to get deepest child items first
                groupsToDelete.Reverse();
                foreach ( var groupToDelete in groupsToDelete )
                {
                    groupService.Delete( groupToDelete );
                }

                // delete in reverse order to get deepest child items first
                groupTypesToDelete.Reverse();
                foreach ( var groupTypeToDelete in groupTypesToDelete )
                {
                    groupTypeService.Delete( groupTypeToDelete );
                }

                rockContext.SaveChanges();

                // Add/Update grouptypes and groups that are in the UI
                // Note:  We'll have to save all the groupTypes without changing the DB value of ChildGroupTypes, then come around again and save the ChildGroupTypes
                // since the ChildGroupTypes may not exist in the database yet
                foreach ( GroupType groupTypeUI in groupTypesToAddUpdate )
                {
                    GroupType groupTypeDB = groupTypeService.Get( groupTypeUI.Guid );
                    if ( groupTypeDB == null )
                    {
                        groupTypeDB = new GroupType();
                        groupTypeDB.Id = 0;
                        groupTypeDB.Guid = groupTypeUI.Guid;
                        groupTypeDB.IsSystem = false;
                        groupTypeDB.ShowInNavigation = false;
                        groupTypeDB.ShowInGroupList = false;
                        groupTypeDB.TakesAttendance = true;
                        groupTypeDB.AttendanceRule = AttendanceRule.None;
                        groupTypeDB.AttendancePrintTo = PrintTo.Default;
                        groupTypeDB.AllowMultipleLocations = true;
                        groupTypeDB.EnableLocationSchedules = true;
                    }

                    groupTypeDB.Name = groupTypeUI.Name;
                    groupTypeDB.Order = groupTypeUI.Order;
                    groupTypeDB.InheritedGroupTypeId = groupTypeUI.InheritedGroupTypeId;

                    groupTypeDB.Attributes = groupTypeUI.Attributes;
                    groupTypeDB.AttributeValues = groupTypeUI.AttributeValues;

                    if ( groupTypeDB.Id == 0 )
                    {
                        groupTypeService.Add( groupTypeDB );
                    }

                    if ( !groupTypeDB.IsValid )
                    {
                        hasValidationErrors = true;
                        CheckinGroupTypeEditor groupTypeEditor = phCheckinGroupTypes.ControlsOfTypeRecursive<CheckinGroupTypeEditor>().First( a => a.GroupTypeGuid == groupTypeDB.Guid );
                        groupTypeEditor.Expanded = true;

                        return;
                    }

                    rockContext.SaveChanges();

                    groupTypeDB.SaveAttributeValues( rockContext );

                    // get fresh from database to make sure we have Id so we can update the CheckinLabel Attributes
                    groupTypeDB = groupTypeService.Get( groupTypeDB.Guid );

                    // rebuild the CheckinLabel attributes from the UI (brute-force)
                    foreach ( var labelAttributeDB in CheckinGroupTypeEditor.GetCheckinLabelAttributes( groupTypeDB.Attributes, rockContext ) )
                    {
                        var attribute = attributeService.Get( labelAttributeDB.Value.Guid );
                        Rock.Web.Cache.AttributeCache.Flush( attribute.Id );
                        attributeService.Delete( attribute );
                    }

                    rockContext.SaveChanges();

                    foreach ( var checkinLabelAttributeInfo in GroupTypeCheckinLabelAttributesState[groupTypeUI.Guid] )
                    {
                        var attribute = new Rock.Model.Attribute();
                        attribute.AttributeQualifiers.Add( new AttributeQualifier { Key = "binaryFileType", Value = Rock.SystemGuid.BinaryFiletype.CHECKIN_LABEL } );
                        attribute.Guid = Guid.NewGuid();
                        attribute.FieldTypeId = binaryFileFieldTypeID;
                        attribute.EntityTypeId = EntityTypeCache.GetId( typeof( GroupType ) );
                        attribute.EntityTypeQualifierColumn = "Id";
                        attribute.EntityTypeQualifierValue = groupTypeDB.Id.ToString();
                        attribute.DefaultValue = checkinLabelAttributeInfo.BinaryFileGuid.ToString();
                        attribute.Key = checkinLabelAttributeInfo.AttributeKey;
                        attribute.Name = checkinLabelAttributeInfo.FileName;

                        if ( !attribute.IsValid )
                        {
                            hasValidationErrors = true;
                            CheckinGroupTypeEditor groupTypeEditor = phCheckinGroupTypes.ControlsOfTypeRecursive<CheckinGroupTypeEditor>().First( a => a.GroupTypeGuid == groupTypeDB.Guid );
                            groupTypeEditor.Expanded = true;

                            return;
                        }

                        attributeService.Add( attribute );
                    }

                    rockContext.SaveChanges();
                }

                // Add/Update Groups
                foreach ( var groupUI in groupsToAddUpdate )
                {
                    Group groupDB = groupService.Get( groupUI.Guid );
                    if ( groupDB == null )
                    {
                        groupDB = new Group();
                        groupDB.Guid = groupUI.Guid;
                    }

                    groupDB.Name = groupUI.Name;

                    // delete any GroupLocations that were removed in the UI
                    foreach ( var groupLocationDB in groupDB.GroupLocations.ToList() )
                    {
                        if ( !groupUI.GroupLocations.Select( a => a.LocationId ).Contains( groupLocationDB.LocationId ) )
                        {
                            groupLocationService.Delete( groupLocationDB );
                        }
                    }

                    // add any GroupLocations that were added in the UI
                    foreach ( var groupLocationUI in groupUI.GroupLocations )
                    {
                        if ( !groupDB.GroupLocations.Select( a => a.LocationId ).Contains( groupLocationUI.LocationId ) )
                        {
                            GroupLocation groupLocationDB = new GroupLocation { LocationId = groupLocationUI.LocationId };
                            groupDB.GroupLocations.Add( groupLocationDB );
                        }
                    }

                    groupDB.Order = groupUI.Order;

                    // get GroupTypeId from database in case the groupType is new
                    groupDB.GroupTypeId = groupTypeService.Get( groupUI.GroupType.Guid ).Id;
                    groupDB.Attributes = groupUI.Attributes;
                    groupDB.AttributeValues = groupUI.AttributeValues;

                    if ( groupDB.Id == 0 )
                    {
                        groupService.Add( groupDB );
                    }

                    if ( !groupDB.IsValid )
                    {
                        hasValidationErrors = true;
                        hasValidationErrors = true;
                        CheckinGroupEditor groupEditor = phCheckinGroupTypes.ControlsOfTypeRecursive<CheckinGroupEditor>().First( a => a.GroupGuid == groupDB.Guid );
                        groupEditor.Expanded = true;

                        return;
                    }

                    rockContext.SaveChanges();

                    groupDB.SaveAttributeValues();
                }

                /* now that we have all the grouptypes saved, now lets go back and save them again with the current UI ChildGroupTypes */

                // save main parentGroupType with current UI ChildGroupTypes
                parentGroupTypeDB.ChildGroupTypes = new List<GroupType>();
                parentGroupTypeDB.ChildGroupTypes.Clear();
                foreach ( var childGroupTypeUI in parentGroupTypeUI.ChildGroupTypes )
                {
                    var childGroupTypeDB = groupTypeService.Get( childGroupTypeUI.Guid );
                    parentGroupTypeDB.ChildGroupTypes.Add( childGroupTypeDB );
                }

                rockContext.SaveChanges();

                // loop thru all the other GroupTypes in the UI and save their childgrouptypes
                foreach ( var groupTypeUI in groupTypesToAddUpdate )
                {
                    var groupTypeDB = groupTypeService.Get( groupTypeUI.Guid );
                    groupTypeDB.ChildGroupTypes = new List<GroupType>();
                    groupTypeDB.ChildGroupTypes.Clear();
                    foreach ( var childGroupTypeUI in groupTypeUI.ChildGroupTypes )
                    {
                        var childGroupTypeDB = groupTypeService.Get( childGroupTypeUI.Guid );
                        groupTypeDB.ChildGroupTypes.Add( childGroupTypeDB );
                    }
                }

                rockContext.SaveChanges();
            } );

            if ( !hasValidationErrors )
            {
                NavigateToParentPage();
            }
        }
        /// <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 )
        {
            Group group;
            bool wasSecurityRole = false;

            RockContext rockContext = new RockContext();

            GroupService groupService = new GroupService( rockContext );
            GroupLocationService groupLocationService = new GroupLocationService( rockContext );
            AttributeService attributeService = new AttributeService( rockContext );
            AttributeQualifierService attributeQualifierService = new AttributeQualifierService( rockContext );
            CategoryService categoryService = new CategoryService( rockContext );

            if ( ( ddlGroupType.SelectedValueAsInt() ?? 0 ) == 0 )
            {
                ddlGroupType.ShowErrorMessage( Rock.Constants.WarningMessage.CannotBeBlank( GroupType.FriendlyTypeName ) );
                return;
            }

            int groupId = int.Parse( hfGroupId.Value );

            if ( groupId == 0 )
            {
                group = new Group();
                group.IsSystem = false;
                group.Name = string.Empty;
            }
            else
            {
                group = groupService.Get( groupId );
                wasSecurityRole = group.IsSecurityRole;

                var selectedLocations = GroupLocationsState.Select( l => l.Guid );
                foreach ( var groupLocation in group.GroupLocations.Where( l => !selectedLocations.Contains( l.Guid ) ).ToList() )
                {
                    group.GroupLocations.Remove( groupLocation );
                    groupLocationService.Delete( groupLocation );
                }
            }

            foreach ( var groupLocationState in GroupLocationsState )
            {
                GroupLocation groupLocation = group.GroupLocations.Where( l => l.Guid == groupLocationState.Guid ).FirstOrDefault();
                if ( groupLocation == null )
                {
                    groupLocation = new GroupLocation();
                    group.GroupLocations.Add( groupLocation );
                }
                else
                {
                    groupLocationState.Id = groupLocation.Id;
                    groupLocationState.Guid = groupLocation.Guid;
                }

                groupLocation.CopyPropertiesFrom( groupLocationState );
            }

            group.Name = tbName.Text;
            group.Description = tbDescription.Text;
            group.CampusId = ddlCampus.SelectedValue.Equals( None.IdValue ) ? (int?)null : int.Parse( ddlCampus.SelectedValue );
            group.GroupTypeId = int.Parse( ddlGroupType.SelectedValue );
            group.ParentGroupId = gpParentGroup.SelectedValue.Equals( None.IdValue ) ? (int?)null : int.Parse( gpParentGroup.SelectedValue );
            group.IsSecurityRole = cbIsSecurityRole.Checked;
            group.IsActive = cbIsActive.Checked;

            if ( group.ParentGroupId == group.Id )
            {
                gpParentGroup.ShowErrorMessage( "Group cannot be a Parent Group of itself." );
                return;
            }

            group.LoadAttributes();

            Rock.Attribute.Helper.GetEditValues( phGroupAttributes, group );

            if ( !Page.IsValid )
            {
                return;
            }

            if ( !group.IsValid )
            {
                // Controls will render the error messages
                return;
            }

            // use WrapTransaction since SaveAttributeValues does it's own RockContext.SaveChanges()
            RockTransactionScope.WrapTransaction( () =>
            {
                if ( group.Id.Equals( 0 ) )
                {
                    groupService.Add( group );
                }
                rockContext.SaveChanges();

                group.SaveAttributeValues( rockContext );

                /* Take care of Group Member Attributes */
                var entityTypeId = EntityTypeCache.Read( typeof( GroupMember ) ).Id;
                string qualifierColumn = "GroupId";
                string qualifierValue = group.Id.ToString();

                // Get the existing attributes for this entity type and qualifier value
                var attributes = attributeService.Get( entityTypeId, qualifierColumn, qualifierValue );

                // Delete any of those attributes that were removed in the UI
                var selectedAttributeGuids = GroupMemberAttributesState.Select( a => a.Guid );
                foreach ( var attr in attributes.Where( a => !selectedAttributeGuids.Contains( a.Guid ) ) )
                {
                    Rock.Web.Cache.AttributeCache.Flush( attr.Id );

                    attributeService.Delete( attr );
                }

                // Update the Attributes that were assigned in the UI
                foreach ( var attributeState in GroupMemberAttributesState )
                {
                    Rock.Attribute.Helper.SaveAttributeEdits( attributeState, entityTypeId, qualifierColumn, qualifierValue, rockContext );
                }

                rockContext.SaveChanges();
            } );

            if ( group != null && wasSecurityRole )
            {
                if ( !group.IsSecurityRole )
                {
                    // if this group was a SecurityRole, but no longer is, flush
                    Rock.Security.Role.Flush( group.Id );
                    Rock.Security.Authorization.Flush();
                }
            }
            else
            {
                if ( group.IsSecurityRole )
                {
                    // new security role, flush
                    Rock.Security.Authorization.Flush();
                }
            }

            var qryParams = new Dictionary<string, string>();
            qryParams["GroupId"] = group.Id.ToString();

            NavigateToPage( RockPage.Guid, qryParams );
        }
        /// <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 )
        {
            Group group;
            bool wasSecurityRole = false;

            RockContext rockContext = new RockContext();

            GroupService groupService = new GroupService( rockContext );
            GroupLocationService groupLocationService = new GroupLocationService( rockContext );
            ScheduleService scheduleService = new ScheduleService( rockContext );
            AttributeService attributeService = new AttributeService( rockContext );
            AttributeQualifierService attributeQualifierService = new AttributeQualifierService( rockContext );
            CategoryService categoryService = new CategoryService( rockContext );

            if ( ( ddlGroupType.SelectedValueAsInt() ?? 0 ) == 0 )
            {
                ddlGroupType.ShowErrorMessage( Rock.Constants.WarningMessage.CannotBeBlank( GroupType.FriendlyTypeName ) );
                return;
            }

            int groupId = int.Parse( hfGroupId.Value );

            if ( groupId == 0 )
            {
                group = new Group();
                group.IsSystem = false;
                group.Name = string.Empty;
            }
            else
            {
                group = groupService.Queryable( "Schedule,GroupLocations.Schedules" ).Where( g => g.Id == groupId ).FirstOrDefault();
                wasSecurityRole = group.IsSecurityRole;

                var selectedLocations = GroupLocationsState.Select( l => l.Guid );
                foreach ( var groupLocation in group.GroupLocations.Where( l => !selectedLocations.Contains( l.Guid ) ).ToList() )
                {
                    group.GroupLocations.Remove( groupLocation );
                    groupLocationService.Delete( groupLocation );
                }
            }

            foreach ( var groupLocationState in GroupLocationsState )
            {
                GroupLocation groupLocation = group.GroupLocations.Where( l => l.Guid == groupLocationState.Guid ).FirstOrDefault();
                if ( groupLocation == null )
                {
                    groupLocation = new GroupLocation();
                    group.GroupLocations.Add( groupLocation );
                }
                else
                {
                    groupLocationState.Id = groupLocation.Id;
                    groupLocationState.Guid = groupLocation.Guid;

                    var selectedSchedules = groupLocationState.Schedules.Select( s => s.Guid ).ToList();
                    foreach( var schedule in groupLocation.Schedules.Where( s => !selectedSchedules.Contains( s.Guid)).ToList())
                    {
                        groupLocation.Schedules.Remove( schedule );
                    }
                }

                groupLocation.CopyPropertiesFrom( groupLocationState );

                var existingSchedules = groupLocation.Schedules.Select( s => s.Guid ).ToList();
                foreach ( var scheduleState in groupLocationState.Schedules.Where( s => !existingSchedules.Contains( s.Guid )).ToList())
                {
                    var schedule = scheduleService.Get( scheduleState.Guid );
                    if ( schedule != null )
                    {
                        groupLocation.Schedules.Add( schedule );
                    }
                }
            }

            group.Name = tbName.Text;
            group.Description = tbDescription.Text;
            group.CampusId = ddlCampus.SelectedValue.Equals( None.IdValue ) ? (int?)null : int.Parse( ddlCampus.SelectedValue );
            group.GroupTypeId = int.Parse( ddlGroupType.SelectedValue );
            group.ParentGroupId = gpParentGroup.SelectedValue.Equals( None.IdValue ) ? (int?)null : int.Parse( gpParentGroup.SelectedValue );
            group.IsSecurityRole = cbIsSecurityRole.Checked;
            group.IsActive = cbIsActive.Checked;

            string iCalendarContent = string.Empty;

            // If unique schedule option was selected, but a schedule was not defined, set option to 'None'
            var scheduleType = rblScheduleSelect.SelectedValueAsEnum<ScheduleType>( ScheduleType.None );
            if ( scheduleType == ScheduleType.Custom )
            {
                iCalendarContent = sbSchedule.iCalendarContent;
                var calEvent = ScheduleICalHelper.GetCalenderEvent( iCalendarContent );
                if ( calEvent == null || calEvent.DTStart == null )
                {
                    scheduleType = ScheduleType.None;
                }
            }

            if ( scheduleType == ScheduleType.Weekly )
            {
                if ( !dowWeekly.SelectedDayOfWeek.HasValue )
                {
                    scheduleType = ScheduleType.None;
                }
            }

            int? oldScheduleId = hfUniqueScheduleId.Value.AsIntegerOrNull();
            if ( scheduleType == ScheduleType.Custom || scheduleType == ScheduleType.Weekly )
            {
                if ( !oldScheduleId.HasValue || group.Schedule == null )
                {
                    group.Schedule = new Schedule();
                }

                if ( scheduleType == ScheduleType.Custom )
                {
                    group.Schedule.iCalendarContent = iCalendarContent;
                    group.Schedule.WeeklyDayOfWeek = null;
                    group.Schedule.WeeklyTimeOfDay = null;
                }
                else
                {
                    group.Schedule.iCalendarContent = null;
                    group.Schedule.WeeklyDayOfWeek = dowWeekly.SelectedDayOfWeek;
                    group.Schedule.WeeklyTimeOfDay = timeWeekly.SelectedTime;
                }
            }
            else
            {
                // If group did have a unique schedule, delete that schedule
                if ( oldScheduleId.HasValue )
                {
                    var schedule = scheduleService.Get( oldScheduleId.Value );
                    if ( schedule != null && string.IsNullOrEmpty(schedule.Name) )
                    {
                        scheduleService.Delete(schedule);
                    }
                }

                if ( scheduleType == ScheduleType.Named )
                {
                    group.ScheduleId = spSchedule.SelectedValueAsId();
                }
                else
                {
                    group.ScheduleId = null;
                }
            }

            if ( group.ParentGroupId == group.Id )
            {
                gpParentGroup.ShowErrorMessage( "Group cannot be a Parent Group of itself." );
                return;
            }

            group.LoadAttributes();

            Rock.Attribute.Helper.GetEditValues( phGroupAttributes, group );

            group.GroupType = new GroupTypeService( rockContext ).Get( group.GroupTypeId );
            if ( group.ParentGroupId.HasValue )
            {
                group.ParentGroup = groupService.Get( group.ParentGroupId.Value );
            }

            // Check to see if user is still allowed to edit with selected group type and parent group
            if ( !group.IsAuthorized( Authorization.EDIT, CurrentPerson ))
            {
                nbNotAllowedToEdit.Visible = true;
                return;
            }

            if ( !Page.IsValid )
            {
                return;
            }

            if ( !group.IsValid )
            {
                // Controls will render the error messages
                return;
            }

            // use WrapTransaction since SaveAttributeValues does it's own RockContext.SaveChanges()
            rockContext.WrapTransaction( () =>
            {
                var adding = group.Id.Equals( 0 );
                if ( adding )
                {
                    groupService.Add( group );
                }

                rockContext.SaveChanges();

                if (adding)
                {
                    // add ADMINISTRATE to the person who added the group
                    Rock.Security.Authorization.AllowPerson( group, Authorization.ADMINISTRATE, this.CurrentPerson, rockContext );
                }

                group.SaveAttributeValues( rockContext );

                /* Take care of Group Member Attributes */
                var entityTypeId = EntityTypeCache.Read( typeof( GroupMember ) ).Id;
                string qualifierColumn = "GroupId";
                string qualifierValue = group.Id.ToString();

                // Get the existing attributes for this entity type and qualifier value
                var attributes = attributeService.Get( entityTypeId, qualifierColumn, qualifierValue );

                // Delete any of those attributes that were removed in the UI
                var selectedAttributeGuids = GroupMemberAttributesState.Select( a => a.Guid );
                foreach ( var attr in attributes.Where( a => !selectedAttributeGuids.Contains( a.Guid ) ) )
                {
                    Rock.Web.Cache.AttributeCache.Flush( attr.Id );

                    attributeService.Delete( attr );
                }

                // Update the Attributes that were assigned in the UI
                foreach ( var attributeState in GroupMemberAttributesState )
                {
                    Rock.Attribute.Helper.SaveAttributeEdits( attributeState, entityTypeId, qualifierColumn, qualifierValue, rockContext );
                }

                rockContext.SaveChanges();
            } );

            if ( group != null && wasSecurityRole )
            {
                if ( !group.IsSecurityRole )
                {
                    // if this group was a SecurityRole, but no longer is, flush
                    Rock.Security.Role.Flush( group.Id );
                    Rock.Security.Authorization.Flush();
                }
            }
            else
            {
                if ( group.IsSecurityRole )
                {
                    // new security role, flush
                    Rock.Security.Authorization.Flush();
                }
            }

            var qryParams = new Dictionary<string, string>();
            qryParams["GroupId"] = group.Id.ToString();
            qryParams["ExpandedIds"] = PageParameter( "ExpandedIds" );

            NavigateToPage( RockPage.Guid, qryParams );
        }
        /// <summary>
        /// Generic method to delete the members of a group and then the group.
        /// </summary>
        /// <param name="group">The group.</param>
        /// <param name="rockContext">The rock context.</param>
        /// <exception cref="System.InvalidOperationException">Unable to delete group:  + group.Name</exception>
        private void DeleteGroupAndMemberData( Group group, RockContext rockContext )
        {
            GroupService groupService = new GroupService( rockContext );

            // delete addresses
            GroupLocationService groupLocationService = new GroupLocationService( rockContext );
            if ( group.GroupLocations.Count > 0 )
            {
                foreach ( var groupLocations in group.GroupLocations.ToList() )
                {
                    group.GroupLocations.Remove( groupLocations );
                    groupLocationService.Delete( groupLocations );
                }
            }

            // delete members
            var groupMemberService = new GroupMemberService( rockContext );
            var members = group.Members;
            foreach ( var member in members.ToList() )
            {
                group.Members.Remove( member );
                groupMemberService.Delete( member );
            }

            // now delete the group
            if ( groupService.Delete( group ) )
            {
                // ok
            }
            else
            {
                throw new InvalidOperationException( "Unable to delete group: " + group.Name );
            }
        }
Exemple #9
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 );

                } );
            }
        }
Exemple #10
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 )
        {
            Group group;
            bool wasSecurityRole = false;
            bool triggersUpdated = false;

            RockContext rockContext = new RockContext();

            GroupService groupService = new GroupService( rockContext );
            GroupLocationService groupLocationService = new GroupLocationService( rockContext );
            GroupRequirementService groupRequirementService = new GroupRequirementService( rockContext );
            GroupMemberWorkflowTriggerService groupMemberWorkflowTriggerService = new GroupMemberWorkflowTriggerService( rockContext );
            ScheduleService scheduleService = new ScheduleService( rockContext );
            AttributeService attributeService = new AttributeService( rockContext );
            AttributeQualifierService attributeQualifierService = new AttributeQualifierService( rockContext );
            CategoryService categoryService = new CategoryService( rockContext );

            var roleGroupType = GroupTypeCache.Read( Rock.SystemGuid.GroupType.GROUPTYPE_SECURITY_ROLE.AsGuid() );
            int roleGroupTypeId = roleGroupType != null ? roleGroupType.Id : int.MinValue;

            if ( CurrentGroupTypeId == 0 )
            {
                ddlGroupType.ShowErrorMessage( Rock.Constants.WarningMessage.CannotBeBlank( GroupType.FriendlyTypeName ) );
                return;
            }

            int groupId = hfGroupId.Value.AsInteger();

            if ( groupId == 0 )
            {
                group = new Group();
                group.IsSystem = false;
                group.Name = string.Empty;
            }
            else
            {
                group = groupService.Queryable( "Schedule,GroupLocations.Schedules" ).Where( g => g.Id == groupId ).FirstOrDefault();
                wasSecurityRole = group.IsActive && ( group.IsSecurityRole || group.GroupTypeId == roleGroupTypeId );

                // remove any locations that removed in the UI
                var selectedLocations = GroupLocationsState.Select( l => l.Guid );
                foreach ( var groupLocation in group.GroupLocations.Where( l => !selectedLocations.Contains( l.Guid ) ).ToList() )
                {
                    group.GroupLocations.Remove( groupLocation );
                    groupLocationService.Delete( groupLocation );
                }

                // remove any group requirements that removed in the UI
                var selectedGroupRequirements = GroupRequirementsState.Select( a => a.Guid );
                foreach ( var groupRequirement in group.GroupRequirements.Where( a => !selectedGroupRequirements.Contains( a.Guid ) ).ToList() )
                {
                    group.GroupRequirements.Remove( groupRequirement );
                    groupRequirementService.Delete( groupRequirement );
                }

                // Remove any triggers that were removed in the UI
                var selectedTriggerGuids = MemberWorkflowTriggersState.Select( r => r.Guid );
                foreach ( var trigger in group.GroupMemberWorkflowTriggers.Where( r => !selectedTriggerGuids.Contains( r.Guid ) ).ToList() )
                {
                    group.GroupMemberWorkflowTriggers.Remove( trigger );
                    groupMemberWorkflowTriggerService.Delete( trigger );
                    triggersUpdated = true;
                }
            }

            // add/update any group requirements that were added or changed in the UI (we already removed the ones that were removed above)
            foreach ( var groupRequirementState in GroupRequirementsState )
            {
                GroupRequirement groupRequirement = group.GroupRequirements.Where( a => a.Guid == groupRequirementState.Guid ).FirstOrDefault();
                if ( groupRequirement == null )
                {
                    groupRequirement = new GroupRequirement();
                    group.GroupRequirements.Add( groupRequirement );
                }

                groupRequirement.CopyPropertiesFrom( groupRequirementState );
            }

            // add/update any group locations that were added or changed in the UI (we already removed the ones that were removed above)
            foreach ( var groupLocationState in GroupLocationsState )
            {
                GroupLocation groupLocation = group.GroupLocations.Where( l => l.Guid == groupLocationState.Guid ).FirstOrDefault();
                if ( groupLocation == null )
                {
                    groupLocation = new GroupLocation();
                    group.GroupLocations.Add( groupLocation );
                }
                else
                {
                    groupLocationState.Id = groupLocation.Id;
                    groupLocationState.Guid = groupLocation.Guid;

                    var selectedSchedules = groupLocationState.Schedules.Select( s => s.Guid ).ToList();
                    foreach ( var schedule in groupLocation.Schedules.Where( s => !selectedSchedules.Contains( s.Guid ) ).ToList() )
                    {
                        groupLocation.Schedules.Remove( schedule );
                    }
                }

                groupLocation.CopyPropertiesFrom( groupLocationState );

                var existingSchedules = groupLocation.Schedules.Select( s => s.Guid ).ToList();
                foreach ( var scheduleState in groupLocationState.Schedules.Where( s => !existingSchedules.Contains( s.Guid ) ).ToList() )
                {
                    var schedule = scheduleService.Get( scheduleState.Guid );
                    if ( schedule != null )
                    {
                        groupLocation.Schedules.Add( schedule );
                    }
                }
            }

            foreach ( var triggerState in MemberWorkflowTriggersState )
            {
                GroupMemberWorkflowTrigger trigger = group.GroupMemberWorkflowTriggers.Where( r => r.Guid == triggerState.Guid ).FirstOrDefault();
                if ( trigger == null )
                {
                    trigger = new GroupMemberWorkflowTrigger();
                    group.GroupMemberWorkflowTriggers.Add( trigger );
                }
                else
                {
                    triggerState.Id = trigger.Id;
                    triggerState.Guid = trigger.Guid;
                }

                trigger.CopyPropertiesFrom( triggerState );

                triggersUpdated = true;
            }

            group.Name = tbName.Text;
            group.Description = tbDescription.Text;
            group.CampusId = ddlCampus.SelectedValueAsInt();
            group.GroupTypeId = CurrentGroupTypeId;
            group.ParentGroupId = gpParentGroup.SelectedValueAsInt();
            group.GroupCapacity = nbGroupCapacity.Text.AsIntegerOrNull();
            group.RequiredSignatureDocumentTemplateId = ddlSignatureDocumentTemplate.SelectedValueAsInt();
            group.IsSecurityRole = cbIsSecurityRole.Checked;
            group.IsActive = cbIsActive.Checked;
            group.IsPublic = cbIsPublic.Checked;
            group.MustMeetRequirementsToAddMember = cbMembersMustMeetRequirementsOnAdd.Checked;

            // save sync settings
            group.SyncDataViewId = dvpSyncDataview.SelectedValue.AsIntegerOrNull();
            group.WelcomeSystemEmailId = ddlWelcomeEmail.SelectedValue.AsIntegerOrNull();
            group.ExitSystemEmailId = ddlExitEmail.SelectedValue.AsIntegerOrNull();
            group.AddUserAccountsDuringSync = rbCreateLoginDuringSync.Checked;

            string iCalendarContent = string.Empty;

            // If unique schedule option was selected, but a schedule was not defined, set option to 'None'
            var scheduleType = rblScheduleSelect.SelectedValueAsEnum<ScheduleType>( ScheduleType.None );
            if ( scheduleType == ScheduleType.Custom )
            {
                iCalendarContent = sbSchedule.iCalendarContent;
                var calEvent = ScheduleICalHelper.GetCalenderEvent( iCalendarContent );
                if ( calEvent == null || calEvent.DTStart == null )
                {
                    scheduleType = ScheduleType.None;
                }
            }

            if ( scheduleType == ScheduleType.Weekly )
            {
                if ( !dowWeekly.SelectedDayOfWeek.HasValue )
                {
                    scheduleType = ScheduleType.None;
                }
            }

            int? oldScheduleId = hfUniqueScheduleId.Value.AsIntegerOrNull();
            if ( scheduleType == ScheduleType.Custom || scheduleType == ScheduleType.Weekly )
            {
                if ( !oldScheduleId.HasValue || group.Schedule == null )
                {
                    group.Schedule = new Schedule();
                }

                if ( scheduleType == ScheduleType.Custom )
                {
                    group.Schedule.iCalendarContent = iCalendarContent;
                    group.Schedule.WeeklyDayOfWeek = null;
                    group.Schedule.WeeklyTimeOfDay = null;
                }
                else
                {
                    group.Schedule.iCalendarContent = null;
                    group.Schedule.WeeklyDayOfWeek = dowWeekly.SelectedDayOfWeek;
                    group.Schedule.WeeklyTimeOfDay = timeWeekly.SelectedTime;
                }
            }
            else
            {
                // If group did have a unique schedule, delete that schedule
                if ( oldScheduleId.HasValue )
                {
                    var schedule = scheduleService.Get( oldScheduleId.Value );
                    if ( schedule != null && string.IsNullOrEmpty( schedule.Name ) )
                    {
                        // Make sure this is the only group trying to use this schedule.
                        if ( !groupService.Queryable().Where( g => g.ScheduleId == schedule.Id && g.Id != group.Id ).Any() )
                        {
                            scheduleService.Delete( schedule );
                        }
                    }
                }

                if ( scheduleType == ScheduleType.Named )
                {
                    group.ScheduleId = spSchedule.SelectedValueAsId();
                }
                else
                {
                    group.ScheduleId = null;
                }
            }

            if ( group.ParentGroupId == group.Id )
            {
                gpParentGroup.ShowErrorMessage( "Group cannot be a Parent Group of itself." );
                return;
            }

            group.LoadAttributes();

            Rock.Attribute.Helper.GetEditValues( phGroupAttributes, group );

            group.GroupType = new GroupTypeService( rockContext ).Get( group.GroupTypeId );
            if ( group.ParentGroupId.HasValue )
            {
                group.ParentGroup = groupService.Get( group.ParentGroupId.Value );
            }

            // Check to see if group type is allowed as a child of new parent group.
            if ( group.ParentGroup != null )
            {
                var allowedGroupTypeIds = GetAllowedGroupTypes( group.ParentGroup, rockContext ).Select( t => t.Id ).ToList();
                if ( !allowedGroupTypeIds.Contains( group.GroupTypeId ) )
                {
                    var groupType = CurrentGroupTypeCache;
                    nbInvalidParentGroup.Text = string.Format( "The '{0}' group does not allow child groups with a '{1}' group type.", group.ParentGroup.Name, groupType != null ? groupType.Name : string.Empty );
                    nbInvalidParentGroup.Visible = true;
                    return;
                }
            }

            // Check to see if user is still allowed to edit with selected group type and parent group
            if ( !group.IsAuthorized( Authorization.EDIT, CurrentPerson ) )
            {
                nbNotAllowedToEdit.Visible = true;
                return;
            }

            if ( !Page.IsValid )
            {
                return;
            }

            // if the groupMember IsValid is false, and the UI controls didn't report any errors, it is probably because the custom rules of GroupMember didn't pass.
            // So, make sure a message is displayed in the validation summary
            cvGroup.IsValid = group.IsValid;

            if ( !cvGroup.IsValid )
            {
                cvGroup.ErrorMessage = group.ValidationResults.Select( a => a.ErrorMessage ).ToList().AsDelimited( "<br />" );
                return;
            }

            // use WrapTransaction since SaveAttributeValues does it's own RockContext.SaveChanges()
            rockContext.WrapTransaction( () =>
            {
                var adding = group.Id.Equals( 0 );
                if ( adding )
                {
                    groupService.Add( group );
                }

                rockContext.SaveChanges();

                if ( adding )
                {
                    // add ADMINISTRATE to the person who added the group
                    Rock.Security.Authorization.AllowPerson( group, Authorization.ADMINISTRATE, this.CurrentPerson, rockContext );
                }

                group.SaveAttributeValues( rockContext );

                /* Take care of Group Member Attributes */
                var entityTypeId = EntityTypeCache.Read( typeof( GroupMember ) ).Id;
                string qualifierColumn = "GroupId";
                string qualifierValue = group.Id.ToString();

                // Get the existing attributes for this entity type and qualifier value
                var attributes = attributeService.Get( entityTypeId, qualifierColumn, qualifierValue );

                // Delete any of those attributes that were removed in the UI
                var selectedAttributeGuids = GroupMemberAttributesState.Select( a => a.Guid );
                foreach ( var attr in attributes.Where( a => !selectedAttributeGuids.Contains( a.Guid ) ) )
                {
                    Rock.Web.Cache.AttributeCache.Flush( attr.Id );

                    attributeService.Delete( attr );
                }

                // Update the Attributes that were assigned in the UI
                foreach ( var attributeState in GroupMemberAttributesState )
                {
                    Rock.Attribute.Helper.SaveAttributeEdits( attributeState, entityTypeId, qualifierColumn, qualifierValue, rockContext );
                }

                rockContext.SaveChanges();

                if ( group.IsActive == false && cbInactivateChildGroups.Checked )
                {
                    var allActiveChildGroupsId = groupService.GetAllDescendents( group.Id ).Where( a => a.IsActive ).Select( a => a.Id ).ToList();
                    var allActiveChildGroups = groupService.GetByIds( allActiveChildGroupsId );
                    foreach ( var childGroup in allActiveChildGroups )
                    {
                        if ( childGroup.IsActive )
                        {
                            childGroup.IsActive = false;
                        }
                    }

                    rockContext.SaveChanges();
                }
            } );

            bool isNowSecurityRole = group.IsActive && ( group.IsSecurityRole || group.GroupTypeId == roleGroupTypeId );

            if ( group != null && wasSecurityRole )
            {
                if ( !isNowSecurityRole )
                {
                    // if this group was a SecurityRole, but no longer is, flush
                    Rock.Security.Role.Flush( group.Id );
                    Rock.Security.Authorization.Flush();
                }
            }
            else
            {
                if ( isNowSecurityRole )
                {
                    // new security role, flush
                    Rock.Security.Authorization.Flush();
                }
            }

            AttributeCache.FlushEntityAttributes();

            if ( triggersUpdated )
            {
                GroupMemberWorkflowTriggerService.FlushCachedTriggers();
            }

            var qryParams = new Dictionary<string, string>();
            qryParams["GroupId"] = group.Id.ToString();
            qryParams["ExpandedIds"] = PageParameter( "ExpandedIds" );

            NavigateToPage( RockPage.Guid, qryParams );
        }
Exemple #11
0
        protected void btnSave_Click( object sender, EventArgs e )
        {
            hfAreaGroupClicked.Value = "true";

            using ( var rockContext = new RockContext() )
            {
                var attributeService = new AttributeService( rockContext );

                if ( checkinArea.Visible )
                {
                    var groupTypeService = new GroupTypeService( rockContext );
                    var groupType = groupTypeService.Get( checkinArea.GroupTypeGuid );
                    if ( groupType != null )
                    {
                        checkinArea.GetGroupTypeValues( groupType );

                        if ( groupType.IsValid )
                        {
                            rockContext.SaveChanges();
                            groupType.SaveAttributeValues( rockContext );

                            bool AttributesUpdated = false;

                            // rebuild the CheckinLabel attributes from the UI (brute-force)
                            foreach ( var labelAttribute in CheckinArea.GetCheckinLabelAttributes( groupType.Attributes ) )
                            {
                                var attribute = attributeService.Get( labelAttribute.Value.Guid );
                                Rock.Web.Cache.AttributeCache.Flush( attribute.Id );
                                attributeService.Delete( attribute );
                                AttributesUpdated = true;
                            }

                            // Make sure default role is set
                            if ( !groupType.DefaultGroupRoleId.HasValue && groupType.Roles.Any() )
                            {
                                groupType.DefaultGroupRoleId = groupType.Roles.First().Id;
                            }

                            rockContext.SaveChanges();

                            int labelOrder = 0;
                            int binaryFileFieldTypeID = FieldTypeCache.Read( Rock.SystemGuid.FieldType.BINARY_FILE.AsGuid() ).Id;
                            foreach ( var checkinLabelAttributeInfo in checkinArea.CheckinLabels )
                            {
                                var attribute = new Rock.Model.Attribute();
                                attribute.AttributeQualifiers.Add( new AttributeQualifier { Key = "binaryFileType", Value = Rock.SystemGuid.BinaryFiletype.CHECKIN_LABEL } );
                                attribute.Guid = Guid.NewGuid();
                                attribute.FieldTypeId = binaryFileFieldTypeID;
                                attribute.EntityTypeId = EntityTypeCache.GetId( typeof( GroupType ) );
                                attribute.EntityTypeQualifierColumn = "Id";
                                attribute.EntityTypeQualifierValue = groupType.Id.ToString();
                                attribute.DefaultValue = checkinLabelAttributeInfo.BinaryFileGuid.ToString();
                                attribute.Key = checkinLabelAttributeInfo.AttributeKey;
                                attribute.Name = checkinLabelAttributeInfo.FileName;
                                attribute.Order = labelOrder++;

                                if ( !attribute.IsValid )
                                {
                                    return;
                                }

                                attributeService.Add( attribute );
                                AttributesUpdated = true;

                            }

                            rockContext.SaveChanges();

                            GroupTypeCache.Flush( groupType.Id );
                            Rock.CheckIn.KioskDevice.FlushAll();

                            if ( AttributesUpdated )
                            {
                                AttributeCache.FlushEntityAttributes();
                            }

                            nbSaveSuccess.Visible = true;
                            BuildRows();
                        }
                        else
                        {
                            ShowInvalidResults( groupType.ValidationResults );
                        }
                    }
                }

                if ( checkinGroup.Visible )
                {
                    var groupService = new GroupService( rockContext );
                    var groupLocationService = new GroupLocationService( rockContext );

                    var group = groupService.Get( checkinGroup.GroupGuid );
                    if ( group != null )
                    {
                        group.LoadAttributes( rockContext );
                        checkinGroup.GetGroupValues( group );

                        // populate groupLocations with whatever is currently in the grid, with just enough info to repopulate it and save it later
                        var newLocationIds = checkinGroup.Locations.Select( l => l.LocationId ).ToList();
                        foreach ( var groupLocation in group.GroupLocations.Where( l => !newLocationIds.Contains( l.LocationId ) ).ToList() )
                        {
                            groupLocationService.Delete( groupLocation );
                            group.GroupLocations.Remove( groupLocation );
                        }

                        var existingLocationIds = group.GroupLocations.Select( g => g.LocationId ).ToList();
                        foreach ( var item in checkinGroup.Locations.Where( l => !existingLocationIds.Contains( l.LocationId ) ).ToList() )
                        {
                            var groupLocation = new GroupLocation();
                            groupLocation.LocationId = item.LocationId;
                            group.GroupLocations.Add( groupLocation );
                        }

                        // Set the new order
                        foreach ( var item in checkinGroup.Locations.OrderBy( l => l.Order ).ToList() )
                        {
                            var groupLocation = group.GroupLocations.FirstOrDefault( gl => gl.LocationId == item.LocationId );
                            groupLocation.Order = item.Order ?? 0;
                        }

                        if ( group.IsValid )
                        {
                            rockContext.SaveChanges();
                            group.SaveAttributeValues( rockContext );

                            Rock.CheckIn.KioskDevice.FlushAll();
                            nbSaveSuccess.Visible = true;
                            BuildRows();
                        }
                        else
                        {
                            ShowInvalidResults( group.ValidationResults );
                        }
                    }
                }
            }

            hfIsDirty.Value = "false";
        }