/// <summary> /// Handles the Click event of the btnSave control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> protected void btnSave_Click( object sender, EventArgs e ) { // confirmation was disabled by btnSave on client-side. So if returning without a redirect, // it should be enabled. If returning with a redirect, the control won't be updated to reflect // confirmation being enabled, so it's ok to enable it here confirmExit.Enabled = true; if ( Page.IsValid ) { confirmExit.Enabled = true; RockTransactionScope.WrapTransaction( () => { var rockContext = new RockContext(); var familyService = new GroupService( rockContext ); var familyMemberService = new GroupMemberService( rockContext ); var personService = new PersonService( rockContext ); var historyService = new HistoryService( rockContext ); var familyChanges = new List<string>(); // SAVE FAMILY _family = familyService.Get( _family.Id ); History.EvaluateChange( familyChanges, "Family Name", _family.Name, tbFamilyName.Text ); _family.Name = tbFamilyName.Text; int? campusId = cpCampus.SelectedValueAsInt(); if ( _family.CampusId != campusId ) { History.EvaluateChange( familyChanges, "Campus", _family.CampusId.HasValue ? CampusCache.Read( _family.CampusId.Value ).Name : string.Empty, campusId.HasValue ? CampusCache.Read( campusId.Value ).Name : string.Empty ); _family.CampusId = campusId; } var familyGroupTypeId = _family.GroupTypeId; rockContext.SaveChanges(); // SAVE FAMILY MEMBERS int? recordStatusValueID = ddlRecordStatus.SelectedValueAsInt(); int? reasonValueId = ddlReason.SelectedValueAsInt(); var newFamilies = new List<Group>(); foreach ( var familyMember in FamilyMembers ) { var memberChanges = new List<string>(); var demographicChanges = new List<string>(); var role = familyRoles.Where( r => r.Guid.Equals( familyMember.RoleGuid ) ).FirstOrDefault(); if ( role == null ) { role = familyRoles.FirstOrDefault(); } bool isChild = role != null && role.Guid.Equals( new Guid( Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_CHILD ) ); // People added to family (new or from other family) if ( !familyMember.ExistingFamilyMember ) { var groupMember = new GroupMember(); if ( familyMember.Id == -1 ) { // added new person demographicChanges.Add( "Created" ); var person = new Person(); person.FirstName = familyMember.FirstName; person.NickName = familyMember.NickName; History.EvaluateChange( demographicChanges, "First Name", string.Empty, person.FirstName ); person.LastName = familyMember.LastName; History.EvaluateChange( demographicChanges, "Last Name", string.Empty, person.LastName ); person.Gender = familyMember.Gender; History.EvaluateChange( demographicChanges, "Gender", null, person.Gender ); person.BirthDate = familyMember.BirthDate; History.EvaluateChange( demographicChanges, "Birth Date", null, person.BirthDate ); if ( !isChild ) { person.GivingGroupId = _family.Id; History.EvaluateChange( demographicChanges, "Giving Group", string.Empty, _family.Name ); } person.EmailPreference = EmailPreference.EmailAllowed; groupMember.Person = person; } else { // added from other family groupMember.Person = personService.Get( familyMember.Id ); } if ( recordStatusValueID > 0 ) { History.EvaluateChange( demographicChanges, "Record Status", DefinedValueCache.GetName( groupMember.Person.RecordStatusValueId ), DefinedValueCache.GetName( recordStatusValueID ) ); groupMember.Person.RecordStatusValueId = recordStatusValueID; History.EvaluateChange( demographicChanges, "Record Status Reason", DefinedValueCache.GetName( groupMember.Person.RecordStatusReasonValueId ), DefinedValueCache.GetName( reasonValueId ) ); groupMember.Person.RecordStatusReasonValueId = reasonValueId; } groupMember.GroupId = _family.Id; if ( role != null ) { History.EvaluateChange( memberChanges, "Role", string.Empty, role.Name ); groupMember.GroupRoleId = role.Id; } if ( groupMember.Person != null ) { familyMemberService.Add( groupMember ); rockContext.SaveChanges(); familyMember.Id = groupMember.Person.Id; } } else { // existing family members var groupMember = familyMemberService.Queryable( "Person" ).Where( m => m.PersonId == familyMember.Id && m.Group.GroupTypeId == familyGroupTypeId && m.GroupId == _family.Id ).FirstOrDefault(); if ( groupMember != null ) { if ( familyMember.Removed ) { var newFamilyChanges = new List<string>(); // Family member was removed and should be created in their own new family var newFamily = new Group(); newFamily.Name = familyMember.LastName + " Family"; History.EvaluateChange( newFamilyChanges, "Family", string.Empty, newFamily.Name ); newFamily.GroupTypeId = familyGroupTypeId; if ( _family.CampusId.HasValue ) { History.EvaluateChange( newFamilyChanges, "Campus", string.Empty, CampusCache.Read( _family.CampusId.Value ).Name ); } newFamily.CampusId = _family.CampusId; familyService.Add( newFamily ); rockContext.SaveChanges(); // If person's previous giving group was this family, set it to their new family id if ( groupMember.Person.GivingGroup != null && groupMember.Person.GivingGroupId == _family.Id ) { History.EvaluateChange( demographicChanges, "Giving Group", groupMember.Person.GivingGroup.Name, _family.Name ); groupMember.Person.GivingGroupId = newFamily.Id; } groupMember.Group = newFamily; rockContext.SaveChanges(); var newMemberChanges = new List<string>(); History.EvaluateChange( newMemberChanges, "Role", string.Empty, groupMember.GroupRole.Name ); HistoryService.SaveChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_FAMILY_CHANGES.AsGuid(), groupMember.Person.Id, newFamilyChanges, newFamily.Name, typeof( Group ), newFamily.Id ); newFamilies.Add( newFamily ); History.EvaluateChange( memberChanges, "Role", groupMember.GroupRole.Name, string.Empty ); } else { // Existing member was not remvoved if ( role != null ) { History.EvaluateChange( memberChanges, "Role", groupMember.GroupRole != null ? groupMember.GroupRole.Name : string.Empty, role.Name ); groupMember.GroupRoleId = role.Id; if ( recordStatusValueID > 0 ) { History.EvaluateChange( demographicChanges, "Record Status", DefinedValueCache.GetName( groupMember.Person.RecordStatusValueId ), DefinedValueCache.GetName( recordStatusValueID ) ); groupMember.Person.RecordStatusValueId = recordStatusValueID; History.EvaluateChange( demographicChanges, "Record Status Reason", DefinedValueCache.GetName( groupMember.Person.RecordStatusReasonValueId ), DefinedValueCache.GetName( reasonValueId ) ); groupMember.Person.RecordStatusReasonValueId = reasonValueId; } rockContext.SaveChanges(); } } } } // Remove anyone that was moved from another family if ( familyMember.RemoveFromOtherFamilies ) { var otherFamilies = familyMemberService.Queryable() .Where( m => m.PersonId == familyMember.Id && m.Group.GroupTypeId == familyGroupTypeId && m.GroupId != _family.Id ) .ToList(); foreach ( var otherFamilyMember in otherFamilies ) { var fm = familyMemberService.Get( otherFamilyMember.Id ); // If the person's giving group id was the family they are being removed from, update it to this new family's id if ( fm.Person.GivingGroupId == fm.GroupId ) { var person = personService.Get( fm.PersonId ); History.EvaluateChange( demographicChanges, "Giving Group", person.GivingGroup.Name, _family.Name ); person.GivingGroupId = _family.Id; rockContext.SaveChanges(); } var oldMemberChanges = new List<string>(); History.EvaluateChange( oldMemberChanges, "Role", fm.GroupRole.Name, string.Empty ); History.EvaluateChange( oldMemberChanges, "Family", fm.Group.Name, string.Empty ); HistoryService.SaveChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_FAMILY_CHANGES.AsGuid(), fm.Person.Id, oldMemberChanges, fm.Group.Name, typeof( Group ), fm.Group.Id ); familyMemberService.Delete( fm ); rockContext.SaveChanges(); var f = familyService.Queryable() .Where( g => g.Id == otherFamilyMember.GroupId && !g.Members.Any() ) .FirstOrDefault(); if ( f != null ) { familyService.Delete( f ); rockContext.SaveChanges(); } } } HistoryService.SaveChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_DEMOGRAPHIC_CHANGES.AsGuid(), familyMember.Id, demographicChanges ); HistoryService.SaveChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_FAMILY_CHANGES.AsGuid(), familyMember.Id, memberChanges, _family.Name, typeof( Group ), _family.Id ); } // SAVE LOCATIONS var groupLocationService = new GroupLocationService( rockContext ); // delete any group locations that were removed var remainingLocationIds = FamilyAddresses.Where( a => a.Id > 0 ).Select( a => a.Id ).ToList(); foreach ( var removedLocation in groupLocationService.Queryable( "GroupLocationTypeValue,Location" ) .Where( l => l.GroupId == _family.Id && !remainingLocationIds.Contains( l.Id ) ) ) { History.EvaluateChange( familyChanges, removedLocation.GroupLocationTypeValue.Name + " Location", removedLocation.Location.ToString(), string.Empty ); groupLocationService.Delete( removedLocation ); } rockContext.SaveChanges(); foreach ( var familyAddress in FamilyAddresses ) { Location updatedAddress = null; if ( familyAddress.LocationIsDirty ) { updatedAddress = new LocationService( rockContext ).Get( familyAddress.Street1, familyAddress.Street2, familyAddress.City, familyAddress.State, familyAddress.Zip ); } GroupLocation groupLocation = null; if ( familyAddress.Id > 0 ) { groupLocation = groupLocationService.Get( familyAddress.Id ); } if ( groupLocation == null ) { groupLocation = new GroupLocation(); groupLocation.GroupId = _family.Id; groupLocationService.Add( groupLocation ); } History.EvaluateChange( familyChanges, "Location Type", groupLocation.GroupLocationTypeValueId.HasValue ? DefinedValueCache.Read( groupLocation.GroupLocationTypeValueId.Value ).Name : string.Empty, familyAddress.LocationTypeName ); groupLocation.GroupLocationTypeValueId = familyAddress.LocationTypeId; History.EvaluateChange( familyChanges, familyAddress.LocationTypeName + " Is Mailing", groupLocation.IsMailingLocation.ToString(), familyAddress.IsMailing.ToString() ); groupLocation.IsMailingLocation = familyAddress.IsMailing; History.EvaluateChange( familyChanges, familyAddress.LocationTypeName + " Is Map Location", groupLocation.IsMappedLocation.ToString(), familyAddress.IsLocation.ToString() ); groupLocation.IsMappedLocation = familyAddress.IsLocation; if ( updatedAddress != null ) { History.EvaluateChange( familyChanges, familyAddress.LocationTypeName + " Location", groupLocation.Location != null ? groupLocation.Location.ToString() : "", updatedAddress.ToString() ); groupLocation.Location = updatedAddress; } rockContext.SaveChanges(); // Add the same locations to any new families created by removing an existing family member if ( newFamilies.Any() ) { //reload grouplocation for access to child properties groupLocation = groupLocationService.Get( groupLocation.Id ); foreach ( var newFamily in newFamilies ) { var newFamilyLocation = new GroupLocation(); newFamilyLocation.GroupId = newFamily.Id; newFamilyLocation.LocationId = groupLocation.LocationId; newFamilyLocation.GroupLocationTypeValueId = groupLocation.GroupLocationTypeValueId; newFamilyLocation.IsMailingLocation = groupLocation.IsMailingLocation; newFamilyLocation.IsMappedLocation = groupLocation.IsMappedLocation; groupLocationService.Add( newFamilyLocation ); } rockContext.SaveChanges(); } } foreach ( var fm in _family.Members ) { HistoryService.SaveChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_FAMILY_CHANGES.AsGuid(), fm.PersonId, familyChanges, _family.Name, typeof( Group ), _family.Id ); } _family = familyService.Get( _family.Id ); if ( _family.Members.Any( m => m.PersonId == Person.Id ) ) { Response.Redirect( string.Format( "~/Person/{0}", Person.Id ), false ); } else { var fm = _family.Members .Where( m => m.GroupRole.Guid.Equals( new Guid( Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT ) ) && m.Person.Gender == Gender.Male ) .OrderByDescending( m => m.Person.Age ) .FirstOrDefault(); if ( fm == null ) { fm = _family.Members .Where( m => m.GroupRole.Guid.Equals( new Guid( Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT ) ) ) .OrderByDescending( m => m.Person.Age ) .FirstOrDefault(); } if ( fm == null ) { fm = _family.Members .OrderByDescending( m => m.Person.Age ) .FirstOrDefault(); } if ( fm != null ) { Response.Redirect( string.Format( "~/Person/{0}", fm.PersonId ), false ); } else { Response.Redirect( "~", false ); } } } ); } }
/// <summary> /// Handles the Click event of the btnSave control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param> protected void btnSave_Click( object sender, EventArgs e ) { 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(); } } } ); }
/// <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 ); } }
/// <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 ); } ); } }
/// <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 ); }
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"; }