/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> public void Execute( IJobExecutionContext context ) { var rockContext = new RockContext(); JobDataMap dataMap = context.JobDetail.JobDataMap; Guid? systemEmailGuid = dataMap.GetString( "NotificationEmailTemplate" ).AsGuidOrNull(); if ( systemEmailGuid.HasValue ) { var selectedGroupTypes = new List<Guid>(); if ( !string.IsNullOrWhiteSpace( dataMap.GetString( "GroupTypes" ) ) ) { selectedGroupTypes = dataMap.GetString( "GroupTypes" ).Split( ',' ).Select( Guid.Parse ).ToList(); } var excludedGroupRoleIds = new List<int>(); if ( !string.IsNullOrWhiteSpace( dataMap.GetString( "ExcludedGroupRoleIds" ) ) ) { excludedGroupRoleIds = dataMap.GetString( "ExcludedGroupRoleIds" ).Split( ',' ).Select( int.Parse ).ToList(); } var notificationOption = dataMap.GetString( "NotifyParentLeaders" ).ConvertToEnum<NotificationOption>( NotificationOption.None ); var accountAbilityGroupGuid = dataMap.GetString( "AccountabilityGroup" ).AsGuid(); // get groups matching of the types provided GroupService groupService = new GroupService( rockContext ); var groups = groupService.Queryable().AsNoTracking() .Where( g => selectedGroupTypes.Contains( g.GroupType.Guid ) && g.IsActive == true && g.GroupRequirements.Any() ); foreach ( var group in groups ) { // check for members that don't meet requirements var groupMembersWithIssues = groupService.GroupMembersNotMeetingRequirements( group.Id, true ); if ( groupMembersWithIssues.Count > 0 ) { // add issues to issue list GroupsMissingRequirements groupMissingRequirements = new GroupsMissingRequirements(); groupMissingRequirements.Id = group.Id; groupMissingRequirements.Name = group.Name; if ( group.GroupType != null ) { groupMissingRequirements.GroupTypeId = group.GroupTypeId; groupMissingRequirements.GroupTypeName = group.GroupType.Name; } groupMissingRequirements.AncestorPathName = groupService.GroupAncestorPathName( group.Id ); // get list of the group leaders groupMissingRequirements.Leaders = group.Members .Where( m => m.GroupRole.IsLeader == true && !excludedGroupRoleIds.Contains( m.GroupRoleId ) ) .Select( m => new GroupMemberResult { Id = m.Id, PersonId = m.PersonId, FullName = m.Person.FullName } ) .ToList(); List<GroupMembersMissingRequirements> groupMembers = new List<GroupMembersMissingRequirements>(); foreach ( var groupMemberIssue in groupMembersWithIssues ) { GroupMembersMissingRequirements groupMember = new GroupMembersMissingRequirements(); groupMember.FullName = groupMemberIssue.Key.Person.FullName; groupMember.Id = groupMemberIssue.Key.Id; groupMember.PersonId = groupMemberIssue.Key.PersonId; groupMember.GroupMemberRole = groupMemberIssue.Key.GroupRole.Name; List<MissingRequirement> missingRequirements = new List<MissingRequirement>(); foreach ( var issue in groupMemberIssue.Value ) { MissingRequirement missingRequirement = new MissingRequirement(); missingRequirement.Id = issue.Key.GroupRequirement.GroupRequirementType.Id; missingRequirement.Name = issue.Key.GroupRequirement.GroupRequirementType.Name; missingRequirement.Status = issue.Key.MeetsGroupRequirement; missingRequirement.OccurrenceDate = issue.Value; switch ( issue.Key.MeetsGroupRequirement ) { case MeetsGroupRequirement.Meets: missingRequirement.Message = issue.Key.GroupRequirement.GroupRequirementType.PositiveLabel; break; case MeetsGroupRequirement.MeetsWithWarning: missingRequirement.Message = issue.Key.GroupRequirement.GroupRequirementType.WarningLabel; break; case MeetsGroupRequirement.NotMet: missingRequirement.Message = issue.Key.GroupRequirement.GroupRequirementType.NegativeLabel; break; } missingRequirements.Add( missingRequirement ); } groupMember.MissingRequirements = missingRequirements; groupMembers.Add( groupMember ); } groupMissingRequirements.GroupMembersMissingRequirements = groupMembers; _groupsMissingRequriements.Add( groupMissingRequirements ); // add leaders as people to notify foreach ( var leader in group.Members.Where( m => m.GroupRole.IsLeader == true && !excludedGroupRoleIds.Contains( m.GroupRoleId ) ) ) { NotificationItem notification = new NotificationItem(); notification.GroupId = group.Id; notification.Person = leader.Person; _notificationList.Add( notification ); } // notify parents if ( notificationOption != NotificationOption.None ) { var parentLeaders = new GroupMemberService( rockContext ).Queryable( "Person" ).AsNoTracking() .Where( m => m.GroupRole.IsLeader && !excludedGroupRoleIds.Contains( m.GroupRoleId ) ); if ( notificationOption == NotificationOption.DirectParent ) { // just the parent group parentLeaders = parentLeaders.Where( m => m.GroupId == group.ParentGroupId ); } else { // all parents in the heirarchy var parentIds = groupService.GetAllAncestorIds( group.Id ); parentLeaders = parentLeaders.Where( m => parentIds.Contains( m.GroupId ) ); } foreach ( var parentLeader in parentLeaders.ToList() ) { NotificationItem parentNotification = new NotificationItem(); parentNotification.Person = parentLeader.Person; parentNotification.GroupId = group.Id; _notificationList.Add( parentNotification ); } } } } // send out notificatons var appRoot = Rock.Web.Cache.GlobalAttributesCache.Read( rockContext ).GetValue( "PublicApplicationRoot" ); var recipients = new List<RecipientData>(); var notificationRecipients = _notificationList.GroupBy( p => p.Person.Id ).ToList(); foreach ( var recipientId in notificationRecipients ) { var recipient = _notificationList.Where( n => n.Person.Id == recipientId.Key ).Select( n => n.Person ).FirstOrDefault(); var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields( null ); mergeFields.Add( "Person", recipient ); var notificationGroupIds = _notificationList .Where( n => n.Person.Id == recipient.Id ) .Select( n => n.GroupId ) .ToList(); var missingRequirements = _groupsMissingRequriements.Where( g => notificationGroupIds.Contains( g.Id ) ).ToList(); mergeFields.Add( "GroupsMissingRequirements", missingRequirements ); recipients.Add( new RecipientData( recipient.Email, mergeFields ) ); Email.Send( systemEmailGuid.Value, recipients, appRoot ); recipients.Clear(); } // add accountability group members if ( !accountAbilityGroupGuid.IsEmpty() ) { var accountabilityGroupMembers = new GroupMemberService( rockContext ).Queryable().AsNoTracking() .Where( m => m.Group.Guid == accountAbilityGroupGuid ) .Select( m => m.Person ); foreach ( var person in accountabilityGroupMembers ) { var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields( null ); mergeFields.Add( "Person", person ); mergeFields.Add( "GroupsMissingRequirements", _groupsMissingRequriements ); recipients.Add( new RecipientData( person.Email, mergeFields ) ); } } Email.Send( systemEmailGuid.Value, recipients, appRoot ); context.Result = string.Format( "{0} requirement notification {1} sent", recipients.Count, "email".PluralizeIf( recipients.Count() != 1 ) ); } else { context.Result = "Warning: No NotificationEmailTemplate found"; } }
private void ListGroups() { RockContext rockContext = new RockContext(); var qry = new GroupMemberService( rockContext ) .Queryable( "Group" ); var parentGroupGuid = GetAttributeValue( "ParentGroup" ).AsGuidOrNull(); if ( parentGroupGuid!=null ) { var availableGroupIds = ( List<int> ) GetCacheItem( "GroupListPersonalizedLava:" + parentGroupGuid.ToString() ); if ( availableGroupIds == null ) { var parentGroup = new GroupService( rockContext ).Get( parentGroupGuid ?? new Guid() ); if ( parentGroup != null ) { availableGroupIds = GetChildGroups( parentGroup ).Select( g => g.Id ).ToList(); } else { availableGroupIds = new List<int>(); } var cacheLength = GetAttributeValue( "CacheDuration" ).AsInteger(); AddCacheItem( "GroupListPersonalizedLava:" + parentGroupGuid.ToString(), availableGroupIds, cacheLength ); } qry = qry.Where( m => availableGroupIds.Contains( m.GroupId ) ); } qry = qry.Where( m => m.PersonId == CurrentPersonId && m.GroupMemberStatus == GroupMemberStatus.Active && m.Group.IsActive == true ); List<Guid> includeGroupTypeGuids = GetAttributeValue( "IncludeGroupTypes" ).SplitDelimitedValues().Select( a => Guid.Parse( a ) ).ToList(); if ( includeGroupTypeGuids.Count > 0 ) { qry = qry.Where( t => includeGroupTypeGuids.Contains( t.Group.GroupType.Guid ) ); } List<Guid> excludeGroupTypeGuids = GetAttributeValue( "ExcludeGroupTypes" ).SplitDelimitedValues().Select( a => Guid.Parse( a ) ).ToList(); if ( excludeGroupTypeGuids.Count > 0 ) { qry = qry.Where( t => !excludeGroupTypeGuids.Contains( t.Group.GroupType.Guid ) ); } var groups = new List<GroupInvolvementSummary>(); foreach ( var groupMember in qry.ToList() ) { if ( groupMember.Group.IsAuthorized( Authorization.VIEW, CurrentPerson ) ) { groups.Add( new GroupInvolvementSummary { Group = groupMember.Group, Role = groupMember.GroupRole.Name, IsLeader = groupMember.GroupRole.IsLeader, GroupType = groupMember.Group.GroupType.Name } ); } } var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields( this.RockPage, this.CurrentPerson ); mergeFields.Add( "Groups", groups ); Dictionary<string, object> linkedPages = new Dictionary<string, object>(); linkedPages.Add( "DetailPage", LinkedPageRoute( "DetailPage" ) ); mergeFields.Add( "LinkedPages", linkedPages ); string template = GetAttributeValue( "LavaTemplate" ); // show debug info bool enableDebug = GetAttributeValue( "EnableDebug" ).AsBoolean(); if ( enableDebug && IsUserAuthorized( Authorization.EDIT ) ) { lDebug.Visible = true; lDebug.Text = mergeFields.lavaDebugInfo(); } lContent.Text = template.ResolveMergeFields( mergeFields ); }
/// <summary> /// Job that will sync groups. /// /// Called by the <see cref="IScheduler" /> when a /// <see cref="ITrigger" /> fires that is associated with /// the <see cref="IJob" />. /// </summary> public virtual void Execute( IJobExecutionContext context ) { JobDataMap dataMap = context.JobDetail.JobDataMap; try { int notificationsSent = 0; int pendingMembersCount = 0; // get groups set to sync RockContext rockContext = new RockContext(); Guid? groupTypeGuid = dataMap.GetString( "GroupType" ).AsGuidOrNull(); Guid? systemEmailGuid = dataMap.GetString( "NotificationEmail" ).AsGuidOrNull(); Guid? groupRoleFilterGuid = dataMap.GetString( "GroupRoleFilter" ).AsGuidOrNull(); int? pendingAge = dataMap.GetString( "PendingAge" ).AsIntegerOrNull(); bool includePreviouslyNotificed = dataMap.GetString( "IncludePreviouslyNotified" ).AsBoolean(); // get system email SystemEmailService emailService = new SystemEmailService( rockContext ); SystemEmail systemEmail = null; if ( systemEmailGuid.HasValue ) { systemEmail = emailService.Get( systemEmailGuid.Value ); } if ( systemEmail == null ) { // no email specified, so nothing to do return; } // get group members if ( groupTypeGuid.HasValue && groupTypeGuid != Guid.Empty ) { var qry = new GroupMemberService( rockContext ).Queryable( "Person, Group, Group.Members.GroupRole" ) .Where( m => m.Group.GroupType.Guid == groupTypeGuid.Value && m.GroupMemberStatus == GroupMemberStatus.Pending ); if ( !includePreviouslyNotificed ) { qry = qry.Where( m => m.IsNotified == false ); } if ( groupRoleFilterGuid.HasValue ) { qry = qry.Where( m => m.GroupRole.Guid == groupRoleFilterGuid.Value ); } if ( pendingAge.HasValue ) { var ageDate = RockDateTime.Now.AddDays( pendingAge.Value * -1 ); qry = qry.Where( m => m.ModifiedDateTime > ageDate ); } var pendingGroupMembers = qry.ToList(); var groups = pendingGroupMembers.GroupBy( m => m.Group ); foreach ( var groupKey in groups ) { var group = groupKey.Key; // get list of pending people var qryPendingIndividuals = group.Members.Where( m => m.GroupMemberStatus == GroupMemberStatus.Pending ); if ( !includePreviouslyNotificed ) { qryPendingIndividuals = qryPendingIndividuals.Where( m => m.IsNotified == false ); } if ( groupRoleFilterGuid.HasValue ) { qryPendingIndividuals = qryPendingIndividuals.Where( m => m.GroupRole.Guid == groupRoleFilterGuid.Value ); } var pendingIndividuals = qryPendingIndividuals.Select( m => m.Person ).ToList(); // get list of leaders var groupLeaders = group.Members.Where( m => m.GroupRole.IsLeader == true ); var appRoot = Rock.Web.Cache.GlobalAttributesCache.Read( rockContext ).GetValue( "PublicApplicationRoot" ); var recipients = new List<RecipientData>(); foreach ( var leader in groupLeaders ) { // create merge object var mergeFields = new Dictionary<string, object>(); mergeFields.Add( "PendingIndividuals", pendingIndividuals ); mergeFields.Add( "Group", group ); mergeFields.Add( "ParentGroup", group.ParentGroup ); mergeFields.Add( "Person", leader.Person ); recipients.Add( new RecipientData( leader.Person.Email, mergeFields ) ); } if ( pendingIndividuals.Count() > 0 ) { Email.Send( systemEmail.Guid, recipients, appRoot ); pendingMembersCount += pendingIndividuals.Count(); notificationsSent += recipients.Count(); } // mark pending members as notified as we go in case the job fails var notifiedPersonIds = pendingIndividuals.Select( p => p.Id ); foreach ( var pendingGroupMember in pendingGroupMembers.Where( m => m.IsNotified == false && notifiedPersonIds.Contains( m.PersonId ) ) ) { pendingGroupMember.IsNotified = true; } rockContext.SaveChanges(); } } context.Result = string.Format( "Sent {0} emails to leaders for {1} pending individuals", notificationsSent, pendingMembersCount ); } catch ( System.Exception ex ) { HttpContext context2 = HttpContext.Current; ExceptionLogService.LogException( ex, context2 ); throw; } }
/// <summary> /// Executes the specified workflow. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="action">The action.</param> /// <param name="entity">The entity.</param> /// <param name="errorMessages">The error messages.</param> /// <returns></returns> public override bool Execute( RockContext rockContext, WorkflowAction action, Object entity, out List<string> errorMessages ) { errorMessages = new List<string>(); Guid? groupGuid = null; Person person = null; string attributeValue = string.Empty; Guid groupRoleGuid = Guid.Empty; string attributeKey = string.Empty; // get the group attribute Guid groupAttributeGuid = GetAttributeValue(action, "Group").AsGuid(); if ( !groupAttributeGuid.IsEmpty() ) { groupGuid = action.GetWorklowAttributeValue(groupAttributeGuid).AsGuidOrNull(); if ( !groupGuid.HasValue ) { errorMessages.Add("The group could not be found!"); } } // get person alias guid Guid personAliasGuid = Guid.Empty; string personAttribute = GetAttributeValue( action, "Person" ); Guid guid = personAttribute.AsGuid(); if (!guid.IsEmpty()) { var attribute = AttributeCache.Read( guid, rockContext ); if ( attribute != null ) { string value = action.GetWorklowAttributeValue(guid); personAliasGuid = value.AsGuid(); } if ( personAliasGuid != Guid.Empty ) { person = new PersonAliasService(rockContext).Queryable().AsNoTracking() .Where(p => p.Guid.Equals(personAliasGuid)) .Select(p => p.Person) .FirstOrDefault(); } else { errorMessages.Add("The person could not be found in the attribute!"); } } // get group member attribute value attributeValue = GetAttributeValue(action, "AttributeValue"); guid = attributeValue.AsGuid(); if ( guid.IsEmpty() ) { attributeValue = attributeValue.ResolveMergeFields(GetMergeFields(action)); } else { var workflowAttributeValue = action.GetWorklowAttributeValue(guid); if ( workflowAttributeValue != null ) { attributeValue = workflowAttributeValue; } } // get optional role filter groupRoleGuid = GetAttributeValue(action, "GroupRoleFilter").AsGuid(); // get attribute key attributeKey = GetAttributeValue(action, "GroupMemberAttributeKey").Replace(" ", ""); // set attribute if ( groupGuid.HasValue && person != null ) { var qry = new GroupMemberService(rockContext).Queryable() .Where(m => m.Group.Guid == groupGuid && m.PersonId == person.Id); if ( groupRoleGuid != Guid.Empty ) { qry = qry.Where(m => m.GroupRole.Guid == groupRoleGuid); } foreach ( var groupMember in qry.ToList() ) { groupMember.LoadAttributes(rockContext); if ( groupMember.Attributes.ContainsKey(attributeKey) ) { var attribute = groupMember.Attributes[attributeKey]; Rock.Attribute.Helper.SaveAttributeValue(groupMember, attribute, attributeValue, rockContext); } else { action.AddLogEntry(string.Format("The group member attribute {0} does not exist!", attributeKey)); break; } } } errorMessages.ForEach( m => action.AddLogEntry( m, true ) ); return 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> /// Gets the groups of selected type that person is a member of /// </summary> /// <param name="context">The context.</param> /// <param name="input">The input.</param> /// <param name="groupTypeId">The group type identifier.</param> /// <param name="status">The status.</param> /// <returns></returns> public static List<Rock.Model.GroupMember> Groups( DotLiquid.Context context, object input, string groupTypeId, string status = "Active" ) { var person = GetPerson( input ); int? numericalGroupTypeId = groupTypeId.AsIntegerOrNull(); if ( person != null && numericalGroupTypeId.HasValue ) { var groupQuery = new GroupMemberService( GetRockContext( context ) ) .Queryable("Group, GroupRole").AsNoTracking() .Where( m => m.PersonId == person.Id && m.Group.GroupTypeId == numericalGroupTypeId.Value && m.Group.IsActive ); if ( status != "All" ) { GroupMemberStatus queryStatus = GroupMemberStatus.Active; queryStatus = (GroupMemberStatus)Enum.Parse( typeof( GroupMemberStatus ), status, true ); groupQuery = groupQuery.Where( m => m.GroupMemberStatus == queryStatus ); } return groupQuery.ToList(); } return new List<Model.GroupMember>(); }