/// <summary> /// Configures a control to display and toggle following for the specified entity /// </summary> /// <param name="followEntity">The follow entity. NOTE: Make sure to use PersonAlias instead of Person when following a Person</param> /// <param name="followControl">The follow control.</param> /// <param name="follower">The follower.</param> public static void SetFollowing( IEntity followEntity, WebControl followControl, Person follower ) { var followingEntityType = EntityTypeCache.Read( followEntity.GetType() ); if ( follower != null && follower.PrimaryAliasId.HasValue ) { using ( var rockContext = new RockContext() ) { var personAliasService = new PersonAliasService( rockContext ); var followingService = new FollowingService( rockContext ); var followingQry = followingService.Queryable() .Where( f => f.EntityTypeId == followingEntityType.Id && f.PersonAlias.PersonId == follower.Id ); followingQry = followingQry.Where( f => f.EntityId == followEntity.Id ); if ( followingQry.Any() ) { followControl.AddCssClass( "following" ); } else { followControl.RemoveCssClass( "following" ); } } int entityId = followEntity.Id; // only show the following control if the entity has been saved to the database followControl.Visible = entityId > 0; string script = string.Format( @"Rock.controls.followingsToggler.initialize($('#{0}'), {1}, {2}, {3}, {4});", followControl.ClientID, followingEntityType.Id, entityId, follower.Id, follower.PrimaryAliasId ); ScriptManager.RegisterStartupScript( followControl, followControl.GetType(), "following", script, true ); } }
/// <summary> /// Handles the Delete event of the gFollowings control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="RowEventArgs" /> instance containing the event data.</param> protected void gFollowings_Delete( object sender, RowEventArgs e ) { var rockContext = new RockContext(); var service = new FollowingService( rockContext ); int personEntityTypeId = EntityTypeCache.Read( "Rock.Model.Person" ).Id; foreach (var following in service.Queryable() .Where( f => f.EntityTypeId == personEntityTypeId && f.EntityId == e.RowKeyId && f.PersonAliasId == CurrentPersonAlias.Id ) ) { service.Delete( following ); } rockContext.SaveChanges(); BindGrid(); }
/// <summary> /// Handles the Click event of the btnConfirm control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> protected void btnConfirm_Click( object sender, EventArgs e ) { if ( Page.IsValid ) { var rockContext = new RockContext(); var personService = new PersonService( rockContext ); var ids = Individuals.Select( i => i.PersonId ).ToList(); #region Individual Details Updates int? newTitleId = ddlTitle.SelectedValueAsInt(); int? newSuffixId = ddlSuffix.SelectedValueAsInt(); int? newConnectionStatusId = ddlStatus.SelectedValueAsInt(); int? newRecordStatusId = ddlRecordStatus.SelectedValueAsInt(); int? newInactiveReasonId = ddlInactiveReason.SelectedValueAsInt(); string newInactiveReasonNote = tbInactiveReasonNote.Text; Gender newGender = ddlGender.SelectedValue.ConvertToEnum<Gender>(); int? newMaritalStatusId = ddlMaritalStatus.SelectedValueAsInt(); int? newGraduationYear = null; if ( ypGraduation.SelectedYear.HasValue ) { newGraduationYear = ypGraduation.SelectedYear.Value; } int? newCampusId = cpCampus.SelectedCampusId; bool? newEmailActive = null; if ( !string.IsNullOrWhiteSpace( ddlIsEmailActive.SelectedValue ) ) { newEmailActive = ddlIsEmailActive.SelectedValue == "Active"; } EmailPreference? newEmailPreference = ddlEmailPreference.SelectedValue.ConvertToEnumOrNull<EmailPreference>(); string newEmailNote = tbEmailNote.Text; int? newReviewReason = ddlReviewReason.SelectedValueAsInt(); string newSystemNote = tbSystemNote.Text; string newReviewReasonNote = tbReviewReasonNote.Text; int inactiveStatusId = DefinedValueCache.Read( Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_INACTIVE ).Id; var allChanges = new Dictionary<int, List<string>>(); var people = personService.Queryable().Where( p => ids.Contains( p.Id ) ).ToList(); foreach ( var person in people ) { var changes = new List<string>(); allChanges.Add( person.Id, changes ); if ( SelectedFields.Contains( ddlTitle.ClientID ) ) { History.EvaluateChange( changes, "Title", DefinedValueCache.GetName( person.TitleValueId ), DefinedValueCache.GetName( newTitleId ) ); person.TitleValueId = newTitleId; } if ( SelectedFields.Contains( ddlSuffix.ClientID ) ) { History.EvaluateChange( changes, "Suffix", DefinedValueCache.GetName( person.SuffixValueId ), DefinedValueCache.GetName( newSuffixId ) ); person.SuffixValueId = newSuffixId; } if ( SelectedFields.Contains( ddlStatus.ClientID ) ) { History.EvaluateChange( changes, "Connection Status", DefinedValueCache.GetName( person.ConnectionStatusValueId ), DefinedValueCache.GetName( newConnectionStatusId ) ); person.ConnectionStatusValueId = newConnectionStatusId; } if ( SelectedFields.Contains( ddlRecordStatus.ClientID ) ) { History.EvaluateChange( changes, "Record Status", DefinedValueCache.GetName( person.RecordStatusValueId ), DefinedValueCache.GetName( newRecordStatusId ) ); person.RecordStatusValueId = newRecordStatusId; if ( newRecordStatusId.HasValue && newRecordStatusId.Value == inactiveStatusId ) { History.EvaluateChange( changes, "Inactive Reason", DefinedValueCache.GetName( person.RecordStatusReasonValueId ), DefinedValueCache.GetName( newInactiveReasonId ) ); person.RecordStatusReasonValueId = newInactiveReasonId; if ( !string.IsNullOrWhiteSpace( newInactiveReasonNote ) ) { History.EvaluateChange( changes, "Inactive Reason Note", person.InactiveReasonNote, newInactiveReasonNote ); person.InactiveReasonNote = newInactiveReasonNote; } } } if ( SelectedFields.Contains( ddlGender.ClientID ) ) { History.EvaluateChange( changes, "Gender", person.Gender, newGender ); person.Gender = newGender; } if ( SelectedFields.Contains( ddlMaritalStatus.ClientID ) ) { History.EvaluateChange( changes, "Marital Status", DefinedValueCache.GetName( person.MaritalStatusValueId ), DefinedValueCache.GetName( newMaritalStatusId ) ); person.MaritalStatusValueId = newMaritalStatusId; } if ( SelectedFields.Contains( ddlGradePicker.ClientID ) ) { History.EvaluateChange( changes, "Graduation Year", person.GraduationYear, newGraduationYear ); person.GraduationYear = newGraduationYear; } if ( SelectedFields.Contains( ddlIsEmailActive.ClientID ) ) { History.EvaluateChange( changes, "Email Is Active", person.IsEmailActive ?? true, newEmailActive.Value ); person.IsEmailActive = newEmailActive; } if ( SelectedFields.Contains( ddlEmailPreference.ClientID ) ) { History.EvaluateChange( changes, "Email Preference", person.EmailPreference, newEmailPreference ); person.EmailPreference = newEmailPreference.Value; } if ( SelectedFields.Contains( tbEmailNote.ClientID ) ) { History.EvaluateChange( changes, "Email Note", person.EmailNote, newEmailNote ); person.EmailNote = newEmailNote; } if ( SelectedFields.Contains( tbSystemNote.ClientID ) ) { History.EvaluateChange( changes, "System Note", person.SystemNote, newSystemNote ); person.SystemNote = newSystemNote; } if ( SelectedFields.Contains( ddlReviewReason.ClientID ) ) { History.EvaluateChange( changes, "Review Reason", DefinedValueCache.GetName( person.ReviewReasonValueId ), DefinedValueCache.GetName( newReviewReason ) ); person.ReviewReasonValueId = newReviewReason; } if ( SelectedFields.Contains( tbReviewReasonNote.ClientID ) ) { History.EvaluateChange( changes, "Review Reason Note", person.ReviewReasonNote, newReviewReasonNote ); person.ReviewReasonNote = newReviewReasonNote; } } if ( SelectedFields.Contains( cpCampus.ClientID ) && cpCampus.SelectedCampusId.HasValue ) { int campusId = cpCampus.SelectedCampusId.Value; Guid familyGuid = new Guid( Rock.SystemGuid.GroupType.GROUPTYPE_FAMILY ); var familyMembers = new GroupMemberService( rockContext ).Queryable() .Where( m => ids.Contains( m.PersonId ) && m.Group.GroupType.Guid == familyGuid ) .Select( m => new { m.PersonId, m.GroupId } ) .Distinct() .ToList(); var families = new GroupMemberService( rockContext ).Queryable() .Where( m => ids.Contains( m.PersonId ) && m.Group.GroupType.Guid == familyGuid ) .Select( m => m.Group ) .Distinct() .ToList(); foreach ( int personId in ids ) { var familyIds = familyMembers.Where( m => m.PersonId == personId ).Select( m => m.GroupId ).ToList(); if ( familyIds.Count == 1 ) { int familyId = familyIds.FirstOrDefault(); var family = families.Where( g => g.Id == familyId ).FirstOrDefault(); { if ( family != null ) { family.CampusId = campusId; } familyMembers.RemoveAll( m => m.GroupId == familyId ); } } } rockContext.SaveChanges(); } // Update following if ( SelectedFields.Contains( ddlFollow.ClientID ) ) { var personAliasEntityType = EntityTypeCache.Read( "Rock.Model.PersonAlias" ); if ( personAliasEntityType != null ) { int personAliasEntityTypeId = personAliasEntityType.Id; bool follow = true; if ( !string.IsNullOrWhiteSpace( ddlFollow.SelectedValue ) ) { follow = ddlFollow.SelectedValue == "Add"; } var personAliasService = new PersonAliasService( rockContext ); var followingService = new FollowingService( rockContext ); if ( follow ) { var paQry = personAliasService.Queryable(); var alreadyFollowingIds = followingService.Queryable() .Where( f => f.EntityTypeId == personAliasEntityTypeId && f.PersonAlias.Id == CurrentPersonAlias.Id ) .Join( paQry, f => f.EntityId, p => p.Id, ( f, p ) => new { PersonAlias = p } ) .Select( p => p.PersonAlias.PersonId ) .Distinct() .ToList(); foreach ( int id in ids.Where( id => !alreadyFollowingIds.Contains( id ) ) ) { var following = new Following { EntityTypeId = personAliasEntityTypeId, EntityId = ( people.FirstOrDefault( p => p.Id == id ).PrimaryAliasId ) ?? 0, PersonAliasId = CurrentPersonAlias.Id }; followingService.Add( following ); } } else { var paQry = personAliasService.Queryable() .Where( p => ids.Contains( p.PersonId ) ) .Select( p => p.Id ); foreach ( var following in followingService.Queryable() .Where( f => f.EntityTypeId == personAliasEntityTypeId && paQry.Contains( f.EntityId ) && f.PersonAlias.Id == CurrentPersonAlias.Id ) ) { followingService.Delete( following ); } } } } rockContext.SaveChanges(); #endregion #region Attributes var selectedCategories = new List<CategoryCache>(); foreach ( string categoryGuid in GetAttributeValue( "AttributeCategories" ).SplitDelimitedValues() ) { var category = CategoryCache.Read( categoryGuid.AsGuid(), rockContext ); if ( category != null ) { selectedCategories.Add( category ); } } var attributes = new List<AttributeCache>(); var attributeValues = new Dictionary<int, string>(); int categoryIndex = 0; foreach ( var category in selectedCategories.OrderBy( c => c.Name ) ) { PanelWidget pw = null; string controlId = "pwAttributes_" + category.Id.ToString(); if ( categoryIndex % 2 == 0 ) { pw = phAttributesCol1.FindControl( controlId ) as PanelWidget; } else { pw = phAttributesCol2.FindControl( controlId ) as PanelWidget; } categoryIndex++; if ( pw != null ) { var orderedAttributeList = new AttributeService( rockContext ).GetByCategoryId( category.Id ) .OrderBy( a => a.Order ).ThenBy( a => a.Name ); foreach ( var attribute in orderedAttributeList ) { if ( attribute.IsAuthorized( Authorization.EDIT, CurrentPerson ) ) { var attributeCache = AttributeCache.Read( attribute.Id ); Control attributeControl = pw.FindControl( string.Format( "attribute_field_{0}", attribute.Id ) ); if ( attributeControl != null && SelectedFields.Contains( attributeControl.ClientID ) ) { string newValue = attributeCache.FieldType.Field.GetEditValue( attributeControl, attributeCache.QualifierValues ); attributes.Add( attributeCache ); attributeValues.Add( attributeCache.Id, newValue ); } } } } } if ( attributes.Any() ) { foreach ( var person in people ) { person.LoadAttributes(); foreach ( var attribute in attributes ) { string originalValue = person.GetAttributeValue( attribute.Key ); string newValue = attributeValues[attribute.Id]; if ( ( originalValue ?? string.Empty ).Trim() != ( newValue ?? string.Empty ).Trim() ) { Rock.Attribute.Helper.SaveAttributeValue( person, attribute, newValue, rockContext ); string formattedOriginalValue = string.Empty; if ( !string.IsNullOrWhiteSpace( originalValue ) ) { formattedOriginalValue = attribute.FieldType.Field.FormatValue( null, originalValue, attribute.QualifierValues, false ); } string formattedNewValue = string.Empty; if ( !string.IsNullOrWhiteSpace( newValue ) ) { formattedNewValue = attribute.FieldType.Field.FormatValue( null, newValue, attribute.QualifierValues, false ); } History.EvaluateChange( allChanges[person.Id], attribute.Name, formattedOriginalValue, formattedNewValue ); } } } } // Create the history records foreach ( var changes in allChanges ) { if ( changes.Value.Any() ) { HistoryService.AddChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_DEMOGRAPHIC_CHANGES.AsGuid(), changes.Key, changes.Value ); } } rockContext.SaveChanges(); #endregion #region Add Note if ( !string.IsNullOrWhiteSpace( tbNote.Text ) && CurrentPerson != null ) { string text = tbNote.Text; bool isAlert = cbIsAlert.Checked; bool isPrivate = cbIsPrivate.Checked; var noteTypeService = new NoteTypeService( rockContext ); var noteType = noteTypeService.Get( Rock.SystemGuid.NoteType.PERSON_TIMELINE.AsGuid() ); if ( noteType != null ) { var notes = new List<Note>(); var noteService = new NoteService( rockContext ); foreach ( int id in ids ) { var note = new Note(); note.IsSystem = false; note.EntityId = id; note.Caption = isPrivate ? "You - Personal Note" : string.Empty; note.Text = tbNote.Text; note.IsAlert = cbIsAlert.Checked; note.NoteType = noteType; notes.Add( note ); noteService.Add( note ); } rockContext.WrapTransaction( () => { rockContext.SaveChanges(); foreach ( var note in notes ) { note.AllowPerson( Authorization.EDIT, CurrentPerson, rockContext ); if ( isPrivate ) { note.MakePrivate( Authorization.VIEW, CurrentPerson, rockContext ); } } } ); } } #endregion #region Group int? groupId = gpGroup.SelectedValue.AsIntegerOrNull(); if ( groupId.HasValue ) { var group = new GroupService( rockContext ).Get( groupId.Value ); if ( group != null ) { var groupMemberService = new GroupMemberService( rockContext ); var existingMembers = groupMemberService.Queryable( "Group" ) .Where( m => m.GroupId == group.Id && ids.Contains( m.PersonId ) ) .ToList(); string action = ddlGroupAction.SelectedValue; if ( action == "Remove" ) { groupMemberService.DeleteRange( existingMembers ); rockContext.SaveChanges(); } else { var roleId = ddlGroupRole.SelectedValueAsInt(); var status = ddlGroupMemberStatus.SelectedValueAsEnum<GroupMemberStatus>(); // Get the attribute values updated var gm = new GroupMember(); gm.Group = group; gm.GroupId = group.Id; gm.LoadAttributes( rockContext ); var selectedGroupAttributes = new List<AttributeCache>(); var selectedGroupAttributeValues = new Dictionary<string, string>(); foreach ( var attributeCache in gm.Attributes.Select( a => a.Value ) ) { Control attributeControl = phAttributes.FindControl( string.Format( "attribute_field_{0}", attributeCache.Id ) ); if ( attributeControl != null && ( action == "Add" || SelectedFields.Contains( attributeControl.ClientID ) ) ) { string newValue = attributeCache.FieldType.Field.GetEditValue( attributeControl, attributeCache.QualifierValues ); selectedGroupAttributes.Add( attributeCache ); selectedGroupAttributeValues.Add( attributeCache.Key, newValue ); } } if ( action == "Add" ) { if ( roleId.HasValue ) { var newGroupMembers = new List<GroupMember>(); var existingIds = existingMembers.Select( m => m.PersonId ).Distinct().ToList(); foreach ( int id in ids.Where( id => !existingIds.Contains( id ) ) ) { var groupMember = new GroupMember(); groupMember.GroupId = group.Id; groupMember.GroupRoleId = roleId.Value; groupMember.GroupMemberStatus = status; groupMember.PersonId = id; groupMemberService.Add( groupMember ); newGroupMembers.Add( groupMember ); } rockContext.SaveChanges(); if ( selectedGroupAttributes.Any() ) { foreach ( var groupMember in newGroupMembers ) { foreach ( var attribute in selectedGroupAttributes ) { Rock.Attribute.Helper.SaveAttributeValue( groupMember, attribute, selectedGroupAttributeValues[attribute.Key], rockContext ); } } } } } else // Update { if ( SelectedFields.Contains( ddlGroupRole.ClientID ) && roleId.HasValue ) { foreach ( var member in existingMembers.Where( m => m.GroupRoleId != roleId.Value ) ) { if ( !existingMembers.Where( m => m.PersonId == member.PersonId && m.GroupRoleId == roleId.Value ).Any() ) { member.GroupRoleId = roleId.Value; } } } if ( SelectedFields.Contains( ddlGroupMemberStatus.ClientID ) ) { foreach ( var member in existingMembers ) { member.GroupMemberStatus = status; } } rockContext.SaveChanges(); if ( selectedGroupAttributes.Any() ) { foreach ( var groupMember in existingMembers ) { foreach ( var attribute in selectedGroupAttributes ) { Rock.Attribute.Helper.SaveAttributeValue( groupMember, attribute, selectedGroupAttributeValues[attribute.Key], rockContext ); } } } } } } } #endregion pnlEntry.Visible = false; pnlConfirm.Visible = false; nbResult.Text = string.Format( "{0} {1} succesfully updated.", ids.Count().ToString( "N0" ), ( ids.Count() > 1 ? "people were" : "person was" ) ); ; pnlResult.Visible = true; } }
protected void LoadContent() { var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields( this.RockPage, this.CurrentPerson ); var entityType = EntityTypeCache.Read(GetAttributeValue("EntityType").AsGuid()); if ( entityType != null ) { RockContext rockContext = new RockContext(); int personId = this.CurrentPersonId.Value; var followingService = new FollowingService( rockContext ); IQueryable<IEntity> qryFollowedItems = followingService.GetFollowedItems( entityType.Id, personId ); int quantity = GetAttributeValue( "MaxResults" ).AsInteger(); var items = qryFollowedItems.Take(quantity + 1).ToList(); bool hasMore = (quantity < items.Count); mergeFields.Add( "FollowingItems", items.Take( quantity ) ); mergeFields.Add( "HasMore", hasMore ); mergeFields.Add( "EntityType", entityType.FriendlyName ); mergeFields.Add( "LinkUrl", GetAttributeValue( "LinkUrl" ) ); mergeFields.Add( "Quantity", quantity ); string template = GetAttributeValue( "LavaTemplate" ); lContent.Text = template.ResolveMergeFields( mergeFields ); // show debug info if ( GetAttributeValue( "EnableDebug" ).AsBoolean() && IsUserAuthorized( Authorization.EDIT ) ) { lDebug.Visible = true; lDebug.Text = mergeFields.lavaDebugInfo(); } } else { lContent.Text = string.Format( "<div class='alert alert-warning'>Please configure an entity in the block settings." ); } }
/// <summary> /// Adds the following records from the given XML element. /// </summary> /// <example> /// <following> /// <follows personGuid="1dfff821-e97c-4324-9883-cf59b5c5bdd6" followsGuid="1dfff821-e97c-4324-9883-cf59b5c5bdd6" type="person" /> /// </connections> /// </example> /// <param name="elemFollowing">The element with the following XML fragment.</param> /// <param name="rockContext">The rock context.</param> private void AddFollowing( XElement elemFollowing, RockContext rockContext ) { if ( elemFollowing == null ) { return; } FollowingService followingService = new FollowingService( rockContext ); int entityTypeId; int entityId; // Find the type and it's corresponding opportunity and then add a connection request for the given person. foreach ( var element in elemFollowing.Elements( "follows" ) ) { Guid personGuid = element.Attribute( "personGuid" ).Value.Trim().AsGuid(); Guid entityGuid = element.Attribute( "followsGuid" ).Value.Trim().AsGuid(); string entityTypeName = element.Attribute( "type" ).Value.Trim(); // only person (person aliases) are supported now. if ( entityTypeName.ToLower() == "person" ) { entityTypeId = EntityTypeCache.Read( typeof( Rock.Model.PersonAlias ) ).Id; entityId = _peopleAliasDictionary[entityGuid]; } else if ( entityTypeName.ToLower() == "group" ) { entityTypeId = EntityTypeCache.Read( typeof( Rock.Model.Group ) ).Id; entityId = _groupDictionary[entityGuid]; } else { // only person (person aliases) are supported as of now. continue; } Following following = new Following() { PersonAliasId = _peopleAliasDictionary[personGuid], EntityTypeId = entityTypeId, EntityId = entityId, CreatedByPersonAliasId = _peopleAliasDictionary[personGuid], CreatedDateTime = RockDateTime.Now, ModifiedDateTime = RockDateTime.Now, ModifiedByPersonAliasId = _peopleAliasDictionary[personGuid] }; followingService.Add( following ); } }
/// <summary> /// Binds the grid. /// </summary> private void BindGrid() { if ( CurrentPersonAlias != null ) { var rockContext = new RockContext(); int personAliasEntityTypeId = EntityTypeCache.Read( "Rock.Model.PersonAlias" ).Id; var personAliasIds = new FollowingService( new RockContext() ).Queryable() .Where( f => f.EntityTypeId == personAliasEntityTypeId && f.PersonAliasId == CurrentPersonAlias.Id ) .Select( f => f.EntityId ) .Distinct() .ToList(); var qry = new PersonAliasService( rockContext ).Queryable() .Where( p => personAliasIds.Contains( p.Id ) ) .Select( p => p.Person ) .Distinct(); // Sort SortProperty sortProperty = gFollowings.SortProperty; if ( sortProperty == null ) { sortProperty = new SortProperty( new GridViewSortEventArgs( "LastName,NickName", SortDirection.Ascending ) ); } Guid homePhoneGuid = Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_HOME.AsGuid(); Guid cellPhoneGuid = Rock.SystemGuid.DefinedValue.PERSON_PHONE_TYPE_MOBILE.AsGuid(); Guid adultGuid = Rock.SystemGuid.GroupRole.GROUPROLE_FAMILY_MEMBER_ADULT.AsGuid(); Guid marriedGuid = Rock.SystemGuid.DefinedValue.PERSON_MARITAL_STATUS_MARRIED.AsGuid(); gFollowings.DataSource = qry.Sort( sortProperty ) .Select( p => new { p.Id, p.LastName, p.NickName, p.BirthDate, p.Email, HomePhone = p.PhoneNumbers .Where( n => n.NumberTypeValue.Guid.Equals(homePhoneGuid)) .Select( n => n.NumberFormatted) .FirstOrDefault(), CellPhone = p.PhoneNumbers .Where( n => n.NumberTypeValue.Guid.Equals( cellPhoneGuid ) ) .Select( n => n.NumberFormatted ) .FirstOrDefault(), SpouseName = p.Members .Where( m => p.MaritalStatusValue.Guid.Equals(marriedGuid) && m.GroupRole.Guid.Equals(adultGuid)) .SelectMany( m => m.Group.Members) .Where( m => m.PersonId != p.Id && m.GroupRole.Guid.Equals(adultGuid) && m.Person.MaritalStatusValue.Guid.Equals(marriedGuid) ) .Select( s => s.Person.NickName + " " + s.Person.LastName) .FirstOrDefault() } ).ToList(); gFollowings.DataBind(); } }
/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> public void Execute( IJobExecutionContext context ) { JobDataMap dataMap = context.JobDetail.JobDataMap; Guid? groupGuid = dataMap.GetString( "EligibleFollowers" ).AsGuidOrNull(); Guid? systemEmailGuid = dataMap.GetString( "EmailTemplate" ).AsGuidOrNull(); int followingEventsSent = 0; if ( groupGuid.HasValue && systemEmailGuid.HasValue ) { var exceptionMsgs = new List<string>(); using ( var rockContext = new RockContext() ) { var followingService = new FollowingService( rockContext ); var followingEventTypeService = new FollowingEventTypeService( rockContext ); var followingEventNotificationService = new FollowingEventNotificationService( rockContext ); // Get all the active event types var eventTypes = followingEventTypeService .Queryable().AsNoTracking() .Where( e => e.EntityTypeId.HasValue && e.IsActive ) .OrderBy( e => e.Order ) .ToList(); // Get the required event types var requiredEventTypes = eventTypes .Where( e => e.IsNoticeRequired ) .ToList(); // The people who are eligible to get following event notices based on the group type setting for this job var eligiblePersonIds = new GroupMemberService( rockContext ) .Queryable().AsNoTracking() .Where( m => m.Group != null && m.Group.Guid.Equals( groupGuid.Value ) && m.GroupMemberStatus == GroupMemberStatus.Active && m.Person != null && m.Person.Email != null && m.Person.Email != "" ) .Select( m => m.PersonId ) .Distinct() .ToList(); // Get all the subscriptions for the eligible people var eventSubscriptions = new FollowingEventSubscriptionService( rockContext ) .Queryable( "PersonAlias" ).AsNoTracking() .Where( f => eligiblePersonIds.Contains( f.PersonAlias.PersonId ) ) .ToList(); // Dictionaries used to store information that will be used to create notification var personSubscriptions = new Dictionary<int, List<int>>(); // Key: personId, Value: list of event type ids that person subscribes to var personFollowings = new Dictionary<int, List<int>>(); // Key: personId, Value: list of following ids that person follows var eventsThatHappened = new Dictionary<int, Dictionary<int, string>>(); // Key: event type id Value: Dictionary of entity id and formatted event notice for the entity //Get the subscriptions for each person foreach ( int personId in eligiblePersonIds ) { var personEventTypes = eventSubscriptions .Where( s => s.PersonAlias.PersonId == personId ) .Select( s => s.EventType ) .ToList(); personEventTypes.AddRange( requiredEventTypes ); if ( personEventTypes.Any() ) { personSubscriptions.AddOrIgnore( personId, personEventTypes .OrderBy( e => e.Order ) .ThenBy( e => e.Name ) .Select( e => e.Id ) .Distinct() .ToList() ); } } // Get a distinct list of each entitytype/entity that is being followed by anyone that subscribes to events var followings = followingService .Queryable( "PersonAlias" ).AsNoTracking() .Where( f => personSubscriptions.Keys.Contains( f.PersonAlias.PersonId ) ) .ToList(); // group the followings by their type var followedEntityIds = new Dictionary<int, List<int>>(); foreach ( var followedEntity in followings .Select( f => new { f.EntityTypeId, f.EntityId } ) .Distinct() ) { followedEntityIds.AddOrIgnore( followedEntity.EntityTypeId, new List<int>() ); followedEntityIds[followedEntity.EntityTypeId].Add( followedEntity.EntityId ); } // group the followings by the follower foreach ( int personId in personSubscriptions.Select( s => s.Key ) ) { var personFollowing = followings .Where( f => f.PersonAlias.PersonId == personId ) .Select( f => f.Id ) .ToList(); personFollowings.Add( personId, personFollowing ); } var timestamp = RockDateTime.Now; // foreach followed entitytype foreach ( var keyVal in followedEntityIds ) { // Get the entitytype EntityTypeCache itemEntityType = EntityTypeCache.Read( keyVal.Key ); if ( itemEntityType.AssemblyName != null ) { // get the actual type of what is being followed Type entityType = itemEntityType.GetEntityType(); if ( entityType != null ) { var dbContext = Reflection.GetDbContextForEntityType( entityType ); if ( dbContext != null ) { var serviceInstance = Reflection.GetServiceForEntityType( entityType, dbContext ); if ( serviceInstance != null ) { MethodInfo qryMethod = serviceInstance.GetType().GetMethod( "Queryable", new Type[] { } ); var entityQry = qryMethod.Invoke( serviceInstance, new object[] { } ) as IQueryable<IEntity>; // If looking at person alias following, make sure to exclude deceased people if ( entityType == typeof( Rock.Model.PersonAlias ) ) { var personAliasQry = entityQry as IQueryable<PersonAlias>; if ( personAliasQry != null ) { entityQry = personAliasQry.Where( p => !p.Person.IsDeceased ); } } var entityList = entityQry.Where( q => keyVal.Value.Contains( q.Id ) ).ToList(); // If there are any followed entities of this type if ( entityList.Any() ) { // Get the active event types for this entity type foreach ( var eventType in eventTypes.Where( e => e.FollowedEntityTypeId == keyVal.Key ) ) { try { // Get the component var eventComponent = eventType.GetEventComponent(); if ( eventComponent != null ) { // Get the previous notificatoins for this event type var previousNotifications = followingEventNotificationService .Queryable() .Where( n => n.FollowingEventTypeId == eventType.Id ) .ToList(); // check each entity that is followed (by anyone) foreach ( IEntity entity in entityList ) { var previousNotification = previousNotifications .Where( n => n.EntityId == entity.Id ) .FirstOrDefault(); DateTime? lastNotification = previousNotification != null ? previousNotification.LastNotified : (DateTime?)null; // if the event happened if ( eventComponent.HasEventHappened( eventType, entity, lastNotification ) ) { // Store the event type id and the entity for later processing of notifications eventsThatHappened.AddOrIgnore( eventType.Id, new Dictionary<int, string>() ); eventsThatHappened[eventType.Id].Add( entity.Id, eventComponent.FormatEntityNotification( eventType, entity ) ); if ( previousNotification == null ) { previousNotification = new FollowingEventNotification(); previousNotification.FollowingEventTypeId = eventType.Id; previousNotification.EntityId = entity.Id; followingEventNotificationService.Add( previousNotification ); } previousNotification.LastNotified = timestamp; } } rockContext.SaveChanges(); } eventType.LastCheckDateTime = RockDateTime.Now; } catch ( Exception ex ) { exceptionMsgs.Add( string.Format( "An exception occurred calculating events for the '{0}' suggestion type:{1} {2}", eventType.Name, Environment.NewLine, ex.Messages().AsDelimited( Environment.NewLine + " " ) ) ); ExceptionLogService.LogException( ex, System.Web.HttpContext.Current ); } } } } } } } } // send notificatons var appRoot = Rock.Web.Cache.GlobalAttributesCache.Read( rockContext ).GetValue( "ExternalApplicationRoot" ); var possibleRecipients = new PersonService( rockContext ) .Queryable().AsNoTracking() .Where( p => personSubscriptions.Keys.Contains( p.Id ) ) .ToList(); // Loop through the possible recipients that actually subscribe to events foreach ( var personSubscription in personSubscriptions ) { // Get the recipient person int personId = personSubscription.Key; var person = possibleRecipients.Where( p => p.Id == personId ).FirstOrDefault(); if ( person != null ) { try { // Make sure person is actually following anything if ( personFollowings.ContainsKey( personId ) ) { // Dictionary to store the entities that had an event for each event type var personEventTypeNotices = new List<FollowingEventTypeNotices>(); // Get the event types that person subscribes to foreach ( var eventType in eventsThatHappened.Where( e => personSubscription.Value.Contains( e.Key ) ) ) { // Get the EntityTypeId for this event type int entityTypeId = eventTypes .Where( e => e.Id == eventType.Key ) .Select( e => e.FollowedEntityTypeId.Value ) .FirstOrDefault(); // Find all the entities with this event type that the person follows var personFollowedEntityIds = followings .Where( f => personFollowings[personId].Contains( f.Id ) && f.EntityTypeId == entityTypeId ) .Select( f => f.EntityId ) .ToList(); // Get any of those entities that had an event happen var personFollowedEntities = eventType.Value .Where( e => personFollowedEntityIds.Contains( e.Key ) ) .ToList(); // If any were found if ( personFollowedEntities.Any() ) { // Add the entry var eventTypeObj = eventTypes.Where( e => e.Id == eventType.Key ).FirstOrDefault(); if ( eventTypeObj != null ) { personEventTypeNotices.Add( new FollowingEventTypeNotices( eventTypeObj, personFollowedEntities.Select( e => e.Value ).ToList() ) ); } } } // If there are any events for any of the entities that this person follows, send a notification if ( personEventTypeNotices.Any() ) { // Send the notice var recipients = new List<RecipientData>(); var mergeFields = new Dictionary<string, object>(); mergeFields.Add( "Person", person ); mergeFields.Add( "EventTypes", personEventTypeNotices.OrderBy( e => e.EventType.Order ).ToList() ); recipients.Add( new RecipientData( person.Email, mergeFields ) ); Email.Send( systemEmailGuid.Value, recipients, appRoot ); followingEventsSent++; } } } catch ( Exception ex ) { exceptionMsgs.Add( string.Format( "An exception occurred sending event notice to '{0}':{1} {2}", person.FullName, Environment.NewLine, ex.Messages().AsDelimited( Environment.NewLine + " " ) ) ); ExceptionLogService.LogException( ex, System.Web.HttpContext.Current ); } } } } context.Result = string.Format( "{0} following events emails sent", followingEventsSent ); if ( exceptionMsgs.Any() ) { throw new Exception( "One or more exceptions occurred calculating following events..." + Environment.NewLine + exceptionMsgs.AsDelimited( Environment.NewLine ) ); } } }
/// <summary> /// Handles the Click event of the lbUnfollow control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> void lbUnfollow_Click( object sender, EventArgs e ) { var itemsSelected = new List<int>(); gFollowings.SelectedKeys.ToList().ForEach( f => itemsSelected.Add( f.ToString().AsInteger() ) ); if ( itemsSelected.Any() ) { var rockContext = new RockContext(); var personAliasService = new PersonAliasService( rockContext ); var followingService = new FollowingService( rockContext ); var paQry = personAliasService.Queryable() .Where( p => itemsSelected.Contains( p.PersonId ) ) .Select( p => p.Id ); int personAliasEntityTypeId = EntityTypeCache.Read( "Rock.Model.PersonAlias" ).Id; foreach ( var following in followingService.Queryable() .Where( f => f.EntityTypeId == personAliasEntityTypeId && paQry.Contains( f.EntityId ) && f.PersonAliasId == CurrentPersonAlias.Id ) ) { followingService.Delete( following ); } rockContext.SaveChanges(); } BindGrid(); }
/// <summary> /// Gets the suggestions. /// </summary> /// <param name="followingSuggestionType">Type of the following suggestion.</param> /// <param name="followerPersonIds">The follower person ids.</param> /// <returns></returns> public override List<PersonEntitySuggestion> GetSuggestions( FollowingSuggestionType followingSuggestionType, List<int> followerPersonIds ) { var suggestions = new List<PersonEntitySuggestion>(); var personAliasEntityType = EntityTypeCache.Read( typeof( Rock.Model.PersonAlias ) ); bool isAutoFollow = GetAttributeValue( followingSuggestionType, "AutoFollow" ).AsBoolean(); // Get the grouptype guid Guid? groupTypeGuid = GetAttributeValue( followingSuggestionType, "GroupType" ).AsGuidOrNull(); if ( groupTypeGuid.HasValue ) { using ( var rockContext = new RockContext() ) { var groupMemberService = new GroupMemberService( rockContext ); var personAliasService = new PersonAliasService( rockContext ); // Get all the groupmember records for any follower and the selected group type var followers = groupMemberService.Queryable().AsNoTracking() .Where( m => m.GroupMemberStatus == GroupMemberStatus.Active && m.Group != null && m.Group.IsActive && m.Group.GroupType.Guid.Equals( groupTypeGuid.Value ) && followerPersonIds.Contains( m.PersonId ) ); // If a specific group or security role was specifed, limit groupmembers to only those of the selected group Guid? groupGuid = GetAttributeValue( followingSuggestionType, "Group" ).AsGuidOrNull(); if ( !groupGuid.HasValue ) { groupGuid = GetAttributeValue( followingSuggestionType, "SecurityRole" ).AsGuidOrNull(); } if ( groupGuid.HasValue ) { followers = followers.Where( m => m.Group.Guid.Equals( groupGuid.Value ) ); } // If a specific role for the follower was specified, limit groupmembers to only those with the selected role Guid? followerRoleGuid = GetAttributeValue( followingSuggestionType, "FollowerGroupType" ).AsGuidOrNull(); if ( followerRoleGuid.HasValue ) { followers = followers.Where( m => m.GroupRole.Guid.Equals( followerRoleGuid.Value ) ); } // Run the query to get all the groups that follower is a member of with selected filters var followerPersonGroup = followers .Select( f => new { f.PersonId, f.GroupId } ) .ToList(); // Get a unique list of any of the groups that followers belong to var followedGroupIds = followerPersonGroup .Select( f => f.GroupId ) .Distinct() .ToList(); // Start building query to get the people to follow from any group that contains a follower var followed = groupMemberService .Queryable().AsNoTracking() .Where( m => followedGroupIds.Contains( m.GroupId ) ); // If a specific role for the people being followed was specified, limit the query to only those with the selected role Guid? followedRoleGuid = GetAttributeValue( followingSuggestionType, "FollowedGroupType" ).AsGuidOrNull(); if ( followedRoleGuid.HasValue ) { followed = followed.Where( m => m.GroupRole.Guid.Equals( followedRoleGuid.Value ) ); } // Get all the people in any of the groups that contain a follower var followedPersonGroup = followed .Select( f => new { f.PersonId, f.GroupId } ) .ToList(); // Get distinct list of people var followedPersonIds = followedPersonGroup .Select( f => f.PersonId ) .Distinct() .ToList(); // Build a dictionary of the personid->personaliasid var personAliasIds = new Dictionary<int, int>(); personAliasService.Queryable().AsNoTracking() .Where( a => followedPersonIds.Contains( a.PersonId ) && a.PersonId == a.AliasPersonId ) .ToList() .ForEach( a => personAliasIds.AddOrIgnore( a.PersonId, a.Id ) ); // Loop through each follower/group combination foreach ( var followedGroup in followerPersonGroup ) { // Loop through the other people in that group foreach ( int followedPersonId in followedPersonGroup .Where( f => f.GroupId == followedGroup.GroupId && f.PersonId != followedGroup.PersonId ) .Select( f => f.PersonId ) ) { // If the person has a valid personalias id if ( personAliasIds.ContainsKey( followedPersonId ) ) { if ( !isAutoFollow ) { // add them to the list of suggestions suggestions.Add( new PersonEntitySuggestion( followedGroup.PersonId, personAliasIds[followedPersonId] ) ); } else { // auto-add the follow var followingService = new FollowingService( rockContext ); int followerPersonAliasId = personAliasIds[followedGroup.PersonId]; int followeePersonAliasId = personAliasIds[followedPersonId]; // if person is not already following the person bool isFollowing = followingService.Queryable().Where( f => f.EntityTypeId == personAliasEntityType.Id && f.EntityId == followeePersonAliasId && f.PersonAliasId == followerPersonAliasId ).Any(); if ( !isFollowing ) { var following = new Following(); following.EntityTypeId = personAliasEntityType.Id; following.EntityId = personAliasIds[followedPersonId]; following.PersonAliasId = personAliasIds[followedGroup.PersonId]; followingService.Add( following ); rockContext.SaveChanges(); } } } } } } } return suggestions; }
private void SetFollowing() { var personAliasEntityType = EntityTypeCache.Read( "Rock.Model.PersonAlias" ); if ( Person != null && CurrentPersonId.HasValue && CurrentPersonAlias != null && personAliasEntityType != null ) { using ( var rockContext = new RockContext() ) { var personAliasService = new PersonAliasService( rockContext ); var followingService = new FollowingService( rockContext ); var paQry = personAliasService.Queryable() .Where( p => p.PersonId == Person.Id ) .Select( p => p.Id ); if ( followingService.Queryable() .Where( f => f.EntityTypeId == personAliasEntityType.Id && paQry.Contains( f.EntityId ) && f.PersonAlias.PersonId == CurrentPersonId ) .Any() ) { pnlFollow.AddCssClass( "following" ); } else { pnlFollow.RemoveCssClass( "following" ); } } string script = string.Format( @" $('.following-status').click(function () {{ var $followingDiv = $(this); if ($followingDiv.hasClass('following')) {{ $.ajax({{ type: 'DELETE', url: Rock.settings.get('baseUrl') + 'api/followings/{0}/{1}/{2}', success: function(data, status, xhr){{ $followingDiv.removeClass('following'); }}, }}); }} else {{ var following = {{ EntityTypeId:{0}, EntityId:{1}, PersonAliasId:{3} }}; $.ajax({{ type: 'POST', contentType: 'application/json', data: JSON.stringify(following), url: Rock.settings.get('baseUrl') + 'api/followings', statusCode: {{ 201: function () {{ $followingDiv.addClass('following'); }} }} }}); }} }}); ", personAliasEntityType.Id, Person.PrimaryAliasId, CurrentPersonId.Value, CurrentPersonAlias.Id ); ScriptManager.RegisterStartupScript( lImage, lImage.GetType(), "following", script, true ); } }
/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> public void Execute( IJobExecutionContext context ) { var exceptionMsgs = new List<string>(); JobDataMap dataMap = context.JobDetail.JobDataMap; Guid? groupGuid = dataMap.GetString( "EligibleFollowers" ).AsGuidOrNull(); Guid? systemEmailGuid = dataMap.GetString( "EmailTemplate" ).AsGuidOrNull(); int followingSuggestionsEmailsSent = 0; int followingSuggestionsSuggestionsTotal = 0; if ( groupGuid.HasValue && systemEmailGuid.HasValue ) { using ( var rockContext = new RockContext() ) { var followingService = new FollowingService( rockContext ); // The people who are eligible to get following suggestions based on the group type setting for this job var eligiblePersonIds = new GroupMemberService( rockContext ) .Queryable().AsNoTracking() .Where( m => m.Group != null && m.Group.Guid.Equals( groupGuid.Value ) && m.GroupMemberStatus == GroupMemberStatus.Active && m.Person != null && m.Person.Email != null && m.Person.Email != "" ) .Select( m => m.PersonId ) .Distinct(); // check to see if there are any event types that require notification var followerPersonIds = new List<int>(); if ( new FollowingEventTypeService( rockContext ) .Queryable().AsNoTracking() .Any( e => e.IsNoticeRequired ) ) { // if so, include all eligible people followerPersonIds = eligiblePersonIds.ToList(); } else { // if not, filter the list of eligible people down to only those that actually have subscribed to one or more following events followerPersonIds = new FollowingEventSubscriptionService( rockContext ) .Queryable().AsNoTracking() .Where( f => eligiblePersonIds.Contains( f.PersonAlias.PersonId ) ) .Select( f => f.PersonAlias.PersonId ) .Distinct() .ToList(); } if ( followerPersonIds.Any() ) { // Get the primary person alias id for each of the followers var primaryAliasIds = new Dictionary<int, int>(); new PersonAliasService( rockContext ) .Queryable().AsNoTracking() .Where( a => followerPersonIds.Contains( a.PersonId ) && a.PersonId == a.AliasPersonId ) .ToList() .ForEach( a => primaryAliasIds.AddOrIgnore( a.PersonId, a.Id ) ); // Get current date/time. var timestamp = RockDateTime.Now; var suggestionTypes = new FollowingSuggestionTypeService( rockContext ) .Queryable().AsNoTracking() .Where( s => s.IsActive ) .OrderBy( s => s.Name ) .ToList(); var components = new Dictionary<int, SuggestionComponent>(); var suggestedEntities = new Dictionary<int, Dictionary<int, IEntity>>(); foreach ( var suggestionType in suggestionTypes ) { try { // Get the suggestion type component var suggestionComponent = suggestionType.GetSuggestionComponent(); if ( suggestionComponent != null ) { components.Add( suggestionType.Id, suggestionComponent ); // Get the entitytype for this suggestion type var suggestionEntityType = EntityTypeCache.Read( suggestionComponent.FollowedType ); if ( suggestionEntityType != null ) { var entityIds = new List<int>(); // Call the components method to return all of it's suggestions var personEntitySuggestions = suggestionComponent.GetSuggestions( suggestionType, followerPersonIds ); // If any suggestions were returned by the component if ( personEntitySuggestions.Any() ) { int entityTypeId = suggestionEntityType.Id; string reasonNote = suggestionType.ReasonNote; // Get the existing followings for any of the followers var existingFollowings = new Dictionary<int, List<int>>(); foreach( var following in followingService.Queryable( "PersonAlias" ).AsNoTracking() .Where( f => f.EntityTypeId == entityTypeId && followerPersonIds.Contains( f.PersonAlias.PersonId ) ) ) { existingFollowings.AddOrIgnore( following.PersonAlias.PersonId, new List<int>() ); existingFollowings[ following.PersonAlias.PersonId].Add( following.EntityId ); } // Loop through each follower foreach ( var followerPersonId in personEntitySuggestions .Select( s => s.PersonId ) .Distinct() ) { using ( var suggestionContext = new RockContext() ) { var followingSuggestedService = new FollowingSuggestedService( suggestionContext ); // Read all the existing suggestions for this type and the returned followers var existingSuggestions = followingSuggestedService .Queryable( "PersonAlias" ) .Where( s => s.SuggestionTypeId == suggestionType.Id && s.PersonAlias.PersonId == followerPersonId ) .ToList(); // Look through the returned suggestions foreach ( var followedEntityId in personEntitySuggestions .Where( s => s.PersonId == followerPersonId ) .Select( s => s.EntityId ) ) { // Make sure person isn't already following this entity if ( !existingFollowings.ContainsKey( followerPersonId ) || !existingFollowings[followerPersonId].Contains( followedEntityId ) ) { // If this person had a primary alias id if ( primaryAliasIds.ContainsKey( followerPersonId ) ) { entityIds.Add( followedEntityId ); // Look for existing suggestion for this person and entity var suggestion = existingSuggestions .Where( s => s.EntityId == followedEntityId ) .OrderByDescending( s => s.StatusChangedDateTime ) .FirstOrDefault(); // If not found, add one if ( suggestion == null ) { suggestion = new FollowingSuggested(); suggestion.EntityTypeId = entityTypeId; suggestion.EntityId = followedEntityId; suggestion.PersonAliasId = primaryAliasIds[followerPersonId]; suggestion.SuggestionTypeId = suggestionType.Id; suggestion.Status = FollowingSuggestedStatus.PendingNotification; suggestion.StatusChangedDateTime = timestamp; followingSuggestedService.Add( suggestion ); } else { // If found, and it has not been ignored, and it's time to promote again, update the promote date if ( suggestion.Status != FollowingSuggestedStatus.Ignored && ( !suggestionType.ReminderDays.HasValue || !suggestion.LastPromotedDateTime.HasValue || suggestion.LastPromotedDateTime.Value.AddDays( suggestionType.ReminderDays.Value ) <= timestamp ) ) { if ( suggestion.Status != FollowingSuggestedStatus.PendingNotification ) { suggestion.StatusChangedDateTime = timestamp; suggestion.Status = FollowingSuggestedStatus.PendingNotification; } } } } } } // Save the suggestions for this type suggestionContext.SaveChanges(); } } } // If any entities are being suggested for this type, query database for them and save to dictionary if ( entityIds.Any() ) { if ( suggestionEntityType.AssemblyName != null ) { // get the actual type of what is being followed Type entityType = suggestionEntityType.GetEntityType(); if ( entityType != null ) { // Get generic queryable method and query all the entities that are being followed Type[] modelType = { entityType }; Type genericServiceType = typeof( Rock.Data.Service<> ); Type modelServiceType = genericServiceType.MakeGenericType( modelType ); Rock.Data.IService serviceInstance = Activator.CreateInstance( modelServiceType, new object[] { rockContext } ) as IService; MethodInfo qryMethod = serviceInstance.GetType().GetMethod( "Queryable", new Type[] { } ); var entityQry = qryMethod.Invoke( serviceInstance, new object[] { } ) as IQueryable<IEntity>; var entityList = entityQry.AsNoTracking().Where( q => entityIds.Contains( q.Id ) ).ToList(); if ( entityList != null && entityList.Any() ) { var entities = new Dictionary<int, IEntity>(); entityList.ForEach( e => entities.Add( e.Id, e ) ); suggestedEntities.Add( suggestionType.Id, entities ); } } } } } } } catch ( Exception ex ) { exceptionMsgs.Add( string.Format( "An exception occurred calculating suggestions for the '{0}' suggestion type:{1} {2}", suggestionType.Name, Environment.NewLine, ex.Messages().AsDelimited( Environment.NewLine + " " ) ) ); ExceptionLogService.LogException( ex, System.Web.HttpContext.Current ); } } var allSuggestions = new FollowingSuggestedService( rockContext ) .Queryable( "PersonAlias" ) .Where( s => s.Status == FollowingSuggestedStatus.PendingNotification ) .ToList(); var suggestionPersonIds = allSuggestions .Where( s => followerPersonIds.Contains( s.PersonAlias.PersonId ) ) .Select( s => s.PersonAlias.PersonId ) .Distinct() .ToList(); var appRoot = Rock.Web.Cache.GlobalAttributesCache.Read( rockContext ).GetValue( "PublicApplicationRoot" ); foreach ( var person in new PersonService( rockContext ) .Queryable().AsNoTracking() .Where( p => suggestionPersonIds.Contains( p.Id ) ) .ToList() ) { try { var personSuggestionNotices = new List<FollowingSuggestionNotices>(); foreach ( var suggestionType in suggestionTypes ) { var component = components.ContainsKey( suggestionType.Id ) ? components[suggestionType.Id] : null; if ( component != null && suggestedEntities.ContainsKey( suggestionType.Id ) ) { var entities = new List<IEntity>(); foreach ( var suggestion in allSuggestions .Where( s => s.PersonAlias.PersonId == person.Id && s.SuggestionTypeId == suggestionType.Id ) .ToList() ) { if ( suggestedEntities[suggestionType.Id].ContainsKey( suggestion.EntityId ) ) { entities.Add( suggestedEntities[suggestionType.Id][suggestion.EntityId] ); suggestion.LastPromotedDateTime = timestamp; suggestion.Status = FollowingSuggestedStatus.Suggested; } } var notices = new List<string>(); foreach ( var entity in component.SortEntities( entities ) ) { notices.Add( component.FormatEntityNotification( suggestionType, entity ) ); } if ( notices.Any() ) { personSuggestionNotices.Add( new FollowingSuggestionNotices( suggestionType, notices ) ); } } } if ( personSuggestionNotices.Any() ) { // Send the notice var recipients = new List<RecipientData>(); var mergeFields = new Dictionary<string, object>(); mergeFields.Add( "Person", person ); mergeFields.Add( "Suggestions", personSuggestionNotices.OrderBy( s => s.SuggestionType.Order ).ToList() ); recipients.Add( new RecipientData( person.Email, mergeFields ) ); Email.Send( systemEmailGuid.Value, recipients, appRoot ); followingSuggestionsEmailsSent += recipients.Count(); followingSuggestionsSuggestionsTotal += personSuggestionNotices.Count(); } rockContext.SaveChanges(); } catch ( Exception ex ) { exceptionMsgs.Add( string.Format( "An exception occurred sending suggestions to '{0}':{1} {2}", person.FullName, Environment.NewLine, ex.Messages().AsDelimited( Environment.NewLine + " " ) ) ); ExceptionLogService.LogException( ex, System.Web.HttpContext.Current ); } } } } } context.Result = string.Format( "A total of {0} following suggestions sent to {1} people", followingSuggestionsSuggestionsTotal, followingSuggestionsEmailsSent ); if ( exceptionMsgs.Any() ) { throw new Exception( "One or more exceptions occurred calculating suggestions..." + Environment.NewLine + exceptionMsgs.AsDelimited( Environment.NewLine ) ); } }
/// <summary> /// Handles the Click event of the btnComplete control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> protected void btnComplete_Click( object sender, EventArgs e ) { if ( Page.IsValid ) { var rockContext = new RockContext(); var personService = new PersonService( rockContext ); var ids = Individuals.Select( i => i.PersonId ).ToList(); var personEntityType = EntityTypeCache.Read( "Rock.Model.Person" ); if ( personEntityType != null ) { int personEntityTypeId = personEntityType.Id; var people = personService.Queryable().Where( p => ids.Contains( p.Id ) ).ToList(); #region Individual Details Updates int? newTitleId = ddlTitle.SelectedValueAsInt(); int? newSuffixId = ddlSuffix.SelectedValueAsInt(); int? newConnectionStatusId = ddlStatus.SelectedValueAsInt(); int? newRecordStatusId = ddlRecordStatus.SelectedValueAsInt(); int? newInactiveReasonId = ddlInactiveReason.SelectedValueAsInt(); string newInactiveReasonNote = tbInactiveReasonNote.Text; Gender? newGender = ddlGender.SelectedValue.ConvertToEnumOrNull<Gender>(); int? newMaritalStatusId = ddlMaritalStatus.SelectedValueAsInt(); DateTime? newGraduationDate = null; if ( ypGraduation.SelectedYear.HasValue ) { newGraduationDate = new DateTime( ypGraduation.SelectedYear.Value, _gradeTransitionDate.Month, _gradeTransitionDate.Day ); } int? newCampusId = cpCampus.SelectedCampusId; bool? newEmailActive = null; if ( !string.IsNullOrWhiteSpace( ddlIsEmailActive.SelectedValue ) ) { newEmailActive = ddlIsEmailActive.SelectedValue == "Active"; } EmailPreference? newEmailPreference = ddlEmailPreference.SelectedValue.ConvertToEnumOrNull<EmailPreference>(); string newEmailNote = tbEmailNote.Text; bool? newFollow = null; if ( !string.IsNullOrWhiteSpace( ddlFollow.SelectedValue ) ) { newFollow = ddlFollow.SelectedValue == "Add"; } int? newReviewReason = ddlReviewReason.SelectedValueAsInt(); string newSystemNote = tbSystemNote.Text; string newReviewReasonNote = tbReviewReasonNote.Text; var allChanges = new Dictionary<int, List<string>>(); foreach ( var person in people ) { var changes = new List<string>(); allChanges.Add( person.Id, changes ); if ( newTitleId.HasValue ) { History.EvaluateChange( changes, "Title", DefinedValueCache.GetName( person.TitleValueId ), DefinedValueCache.GetName( newTitleId ) ); person.TitleValueId = newTitleId; } if ( newSuffixId.HasValue ) { History.EvaluateChange( changes, "Suffix", DefinedValueCache.GetName( person.SuffixValueId ), DefinedValueCache.GetName( newSuffixId ) ); person.SuffixValueId = newSuffixId; } if ( newConnectionStatusId.HasValue ) { History.EvaluateChange( changes, "Connection Status", DefinedValueCache.GetName( person.ConnectionStatusValueId ), DefinedValueCache.GetName( newConnectionStatusId ) ); person.ConnectionStatusValueId = newConnectionStatusId; } if ( newRecordStatusId.HasValue ) { History.EvaluateChange( changes, "Record Status", DefinedValueCache.GetName( person.RecordStatusValueId ), DefinedValueCache.GetName( newRecordStatusId ) ); person.RecordStatusValueId = newRecordStatusId; } if ( newInactiveReasonId.HasValue ) { History.EvaluateChange( changes, "Inactive Reason", DefinedValueCache.GetName( person.RecordStatusReasonValueId ), DefinedValueCache.GetName( newInactiveReasonId ) ); person.RecordStatusReasonValueId = newInactiveReasonId; } if ( !string.IsNullOrWhiteSpace( newInactiveReasonNote ) ) { History.EvaluateChange( changes, "Inactive Reason Note", person.InactiveReasonNote, newInactiveReasonNote ); person.InactiveReasonNote = newInactiveReasonNote; } if ( newGender.HasValue ) { History.EvaluateChange( changes, "Gender", person.Gender, newGender.Value ); person.Gender = newGender.Value; } if ( newMaritalStatusId.HasValue ) { History.EvaluateChange( changes, "Marital Status", DefinedValueCache.GetName( person.MaritalStatusValueId ), DefinedValueCache.GetName( newMaritalStatusId ) ); person.MaritalStatusValueId = newMaritalStatusId; } if ( newGraduationDate.HasValue ) { History.EvaluateChange( changes, "Graduation Date", person.GraduationDate, newGraduationDate ); person.GraduationDate = newGraduationDate; } if ( newEmailActive.HasValue ) { History.EvaluateChange( changes, "Email Is Active", person.IsEmailActive ?? true, newEmailActive.Value ); person.IsEmailActive = newEmailActive; } if ( newEmailPreference.HasValue ) { History.EvaluateChange( changes, "Email Preference", person.EmailPreference, newEmailPreference ); person.EmailPreference = newEmailPreference.Value; } if ( !string.IsNullOrWhiteSpace( newEmailNote ) ) { History.EvaluateChange( changes, "Email Note", person.EmailNote, newEmailNote ); person.EmailNote = newEmailNote; } if ( !string.IsNullOrWhiteSpace( newSystemNote ) ) { History.EvaluateChange( changes, "System Note", person.SystemNote, newSystemNote ); person.SystemNote = newSystemNote; } if ( newReviewReason.HasValue ) { History.EvaluateChange( changes, "Review Reason", DefinedValueCache.GetName( person.ReviewReasonValueId ), DefinedValueCache.GetName( newReviewReason ) ); person.ReviewReasonValueId = newReviewReason; } if ( !string.IsNullOrWhiteSpace( newReviewReasonNote ) ) { History.EvaluateChange( changes, "Review Reason Note", person.ReviewReasonNote, newReviewReasonNote ); person.ReviewReasonNote = newReviewReasonNote; } } // Update following if ( newFollow.HasValue && CurrentPersonAlias != null ) { var followingService = new FollowingService( rockContext ); if ( newFollow.Value ) { var alreadyFollingIds = followingService.Queryable() .Where( f => f.EntityTypeId == personEntityTypeId && f.PersonAlias.Id == CurrentPersonAlias.Id ) .Select( f => f.EntityId ) .Distinct() .ToList(); foreach ( int id in ids.Where( id => !alreadyFollingIds.Contains( id ) ) ) { var following = new Following { EntityTypeId = personEntityTypeId, EntityId = id, PersonAliasId = CurrentPersonAlias.Id }; followingService.Add( following ); } } else { foreach ( var following in followingService.Queryable() .Where( f => f.EntityTypeId == personEntityTypeId && ids.Contains( f.EntityId ) && f.PersonAlias.Id == CurrentPersonAlias.Id ) ) { followingService.Delete( following ); } } } rockContext.SaveChanges(); #endregion #region Attributes var selectedCategories = new List<CategoryCache>(); foreach ( string categoryGuid in GetAttributeValue( "AttributeCategories" ).SplitDelimitedValues() ) { var category = CategoryCache.Read( categoryGuid.AsGuid(), rockContext ); if ( category != null ) { selectedCategories.Add( category ); } } var attributes = new List<AttributeCache>(); var attributeValues = new Dictionary<int, string>(); int categoryIndex = 0; foreach ( var category in selectedCategories.OrderBy( c => c.Name ) ) { PanelWidget pw = null; string controlId = "pwAttributes_" + category.Id.ToString(); if ( categoryIndex % 2 == 0 ) { pw = phAttributesCol1.FindControl( controlId ) as PanelWidget; } else { pw = phAttributesCol2.FindControl( controlId) as PanelWidget; } categoryIndex++; if ( pw != null ) { var orderedAttributeList = new AttributeService( rockContext ).GetByCategoryId( category.Id ) .OrderBy( a => a.Order ).ThenBy( a => a.Name ); foreach ( var attribute in orderedAttributeList ) { if ( attribute.IsAuthorized( Authorization.EDIT, CurrentPerson ) ) { var attributeCache = AttributeCache.Read( attribute.Id ); Control attributeControl = pw.FindControl( string.Format( "attribute_field_{0}", attribute.Id ) ); if ( attributeControl != null ) { string newValue = attributeCache.FieldType.Field.GetEditValue( attributeControl, attributeCache.QualifierValues ); if (!string.IsNullOrWhiteSpace(newValue)) { attributes.Add( attributeCache); attributeValues.Add( attributeCache.Id, newValue ); } } } } } } if (attributes.Any()) { foreach ( var person in people ) { person.LoadAttributes(); foreach ( var attribute in attributes ) { string originalValue = person.GetAttributeValue( attribute.Key ); string newValue = attributeValues[attribute.Id]; if ( ( originalValue ?? string.Empty ).Trim() != ( newValue ?? string.Empty ).Trim() ) { Rock.Attribute.Helper.SaveAttributeValue( person, attribute, newValue, rockContext ); string formattedOriginalValue = string.Empty; if ( !string.IsNullOrWhiteSpace( originalValue ) ) { formattedOriginalValue = attribute.FieldType.Field.FormatValue( null, originalValue, attribute.QualifierValues, false ); } string formattedNewValue = string.Empty; if ( !string.IsNullOrWhiteSpace( newValue ) ) { formattedNewValue = attribute.FieldType.Field.FormatValue( null, newValue, attribute.QualifierValues, false ); } History.EvaluateChange( allChanges[person.Id], attribute.Name, formattedOriginalValue, formattedNewValue ); } } } } // Create the history records foreach ( var changes in allChanges ) { if ( changes.Value.Any() ) { HistoryService.AddChanges( rockContext, typeof( Person ), Rock.SystemGuid.Category.HISTORY_PERSON_DEMOGRAPHIC_CHANGES.AsGuid(), changes.Key, changes.Value ); } } rockContext.SaveChanges(); #endregion #region Add Note if ( !string.IsNullOrWhiteSpace( tbNote.Text ) && CurrentPerson != null ) { string text = tbNote.Text; bool isAlert = cbIsAlert.Checked; bool isPrivate = cbIsPrivate.Checked; var noteTypeService = new NoteTypeService( rockContext ); var noteService = new NoteService( rockContext ); string noteTypeName = GetAttributeValue( "NoteType" ); var noteType = noteTypeService.Get( personEntityTypeId, noteTypeName ); if ( noteType != null ) { var notes = new List<Note>(); foreach ( int id in ids ) { var note = new Note(); note.IsSystem = false; note.EntityId = id; note.Caption = isPrivate ? "You - Personal Note" : string.Empty; note.Text = tbNote.Text; note.IsAlert = cbIsAlert.Checked; note.NoteType = noteType; notes.Add( note ); noteService.Add( note ); } rockContext.WrapTransaction( () => { rockContext.SaveChanges(); foreach( var note in notes) { note.AllowPerson( Authorization.EDIT, CurrentPerson, rockContext ); if ( isPrivate) { note.MakePrivate( Authorization.VIEW, CurrentPerson, rockContext ); } } } ); } } #endregion } string message = string.Format("{0} {1} succesfully updated!", ids.Count().ToString("N0"), (ids.Count() > 1 ? "people were" : "person was") ); ShowResult( message ); } }
/// <summary> /// Gets the data. /// </summary> private int GetCount() { var personAliasEntityType = EntityTypeCache.Read( "Rock.Model.PersonAlias" ); if ( personAliasEntityType != null && CurrentPersonAlias != null ) { using ( var rockContext = new RockContext() ) { // PersonAlias query for joining the followed entity id to var personAliasQry = new PersonAliasService( rockContext ) .Queryable().AsNoTracking(); // Get all the people that the current person currently follows var followedPersonIds = new FollowingService( rockContext ) .Queryable().AsNoTracking() .Where( f => f.EntityTypeId == personAliasEntityType.Id && f.PersonAliasId == CurrentPersonAlias.Id ) .Join( personAliasQry, s => s.EntityId, p => p.Id, ( s, p ) => p.PersonId ) .Distinct(); // Get all the person suggestions for the current person that they are not already following return new FollowingSuggestedService( rockContext ) .Queryable( "SuggestionType" ).AsNoTracking() .Where( s => s.SuggestionType != null && s.EntityTypeId == personAliasEntityType.Id && s.PersonAliasId == CurrentPersonAlias.Id && s.Status != FollowingSuggestedStatus.Ignored ) .Join( personAliasQry, s => s.EntityId, p => p.Id, ( s, p ) => new { s, p } ) .Where( j => !followedPersonIds.Contains( j.p.PersonId ) ) .Count(); } } return 0; }
protected void LoadContent() { var mergeFields = new Dictionary<string, object>(); mergeFields.Add( "CurrentPerson", CurrentPerson ); var globalAttributeFields = Rock.Web.Cache.GlobalAttributesCache.GetMergeFields( CurrentPerson ); globalAttributeFields.ToList().ForEach( d => mergeFields.Add( d.Key, d.Value ) ); var entityType = EntityTypeCache.Read(GetAttributeValue("EntityType").AsGuid()); if ( entityType != null ) { RockContext rockContext = new RockContext(); int entityTypeId = EntityTypeCache.GetId<Group>().Value; int personId = this.CurrentPersonId.Value; var followingService = new FollowingService( rockContext ); IQueryable<IEntity> qryFollowedItems = followingService.GetFollowedItems( entityTypeId, personId ); mergeFields.Add( "FollowingItems", qryFollowedItems ); mergeFields.Add( "EntityType", entityType.FriendlyName ); mergeFields.Add( "LinkUrl", GetAttributeValue( "LinkUrl" ) ); string template = GetAttributeValue( "LavaTemplate" ); lContent.Text = template.ResolveMergeFields( mergeFields ); // show debug info if ( GetAttributeValue( "EnableDebug" ).AsBoolean() && IsUserAuthorized( Authorization.EDIT ) ) { lDebug.Visible = true; lDebug.Text = mergeFields.lavaDebugInfo(); } } else { lContent.Text = string.Format( "<div class='alert alert-warning'>Please configure an entity in the block settings." ); } }
/// <summary> /// Handles the Click event of the lbUnfollow control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> void lbFollow_Click( object sender, EventArgs e ) { // Get the suggestion ids that were selected var itemsSelected = new List<int>(); gSuggestions.SelectedKeys.ToList().ForEach( f => itemsSelected.Add( f.ToString().AsInteger() ) ); // Get the personAlias entity type var personAliasEntityType = EntityTypeCache.Read( typeof( Rock.Model.PersonAlias )); // If we have a valid current person and items were selected if ( personAliasEntityType != null && CurrentPersonAliasId.HasValue && itemsSelected.Any() ) { using ( var rockContext = new RockContext() ) { // Get all the person alias id's that were selected var followingSuggestedService = new FollowingSuggestedService( rockContext ); var selectedPersonAliasIds = followingSuggestedService .Queryable() .Where( f => itemsSelected.Contains( f.Id ) ) .Select( f => f.EntityId ) .Distinct() .ToList(); // Find any of the selected person alias ids that current person is already following var followingService = new FollowingService( rockContext ); var alreadyFollowing = followingService .Queryable() .Where( f => f.EntityTypeId == personAliasEntityType.Id && f.PersonAliasId == CurrentPersonAliasId.Value && selectedPersonAliasIds.Contains( f.EntityId ) ) .Select( f => f.EntityId ) .Distinct() .ToList(); // For each selected person alias id that the current person is not already following foreach ( var personAliasId in selectedPersonAliasIds.Where( p => !alreadyFollowing.Contains( p ) ) ) { // Add a following record var following = new Following(); following.EntityTypeId = personAliasEntityType.Id; following.EntityId = personAliasId; following.PersonAliasId = CurrentPersonAliasId.Value; followingService.Add( following ); } rockContext.SaveChanges(); } } BindGrid(); }
/// <summary> /// Binds the grid. /// </summary> private void BindGrid() { var personAliasEntityType = EntityTypeCache.Read( "Rock.Model.PersonAlias" ); if ( personAliasEntityType != null && CurrentPersonAlias != null ) { var rockContext = new RockContext(); // PersonAlias query for joining the followed entity id to var personAliasQry = new PersonAliasService( rockContext ).Queryable(); // Get all the people that the current person currently follows var followedPersonIds = new FollowingService( rockContext ).Queryable() .Where( f => f.EntityTypeId == personAliasEntityType.Id && f.PersonAliasId == CurrentPersonAlias.Id ) .Join( personAliasQry, s => s.EntityId, p => p.Id, ( s, p ) => p.PersonId ) .Distinct(); // Get all the person suggestions for the current person that they are not already following var qry = new FollowingSuggestedService( rockContext ) .Queryable("SuggestionType") .Where( s => s.SuggestionType != null && s.EntityTypeId == personAliasEntityType.Id && s.PersonAliasId == CurrentPersonAlias.Id ) .Join( personAliasQry, s => s.EntityId, p => p.Id, ( s, p ) => new { s, p } ) .Where( j => !followedPersonIds.Contains( j.p.PersonId ) ) .Select( j => new { j.s.Id, j.s.LastPromotedDateTime, j.s.StatusChangedDateTime, j.s.SuggestionType.ReasonNote, j.s.Status, Person = j.p.Person, LastName = j.p.Person.LastName, NickName = j.p.Person.NickName } ); // Sort the result SortProperty sortProperty = gSuggestions.SortProperty; if ( sortProperty == null ) { sortProperty = new SortProperty( new GridViewSortEventArgs( "LastName,NickName", SortDirection.Ascending ) ); } // Bind grid to the query gSuggestions.DataSource = qry.Sort( sortProperty ) .Select( s => new { s.Id, s.LastPromotedDateTime, s.StatusChangedDateTime, s.ReasonNote, s.Status, StatusLabel = s.Status == FollowingSuggestedStatus.Ignored ? "<span class='label label-warning'>Ignored</span>" : "<span class='label label-success'>Suggested</span>", s.Person, s.LastName, s.NickName } ) .ToList(); gSuggestions.DataBind(); } }