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