/// <summary>
/// Executes the specified context.
/// </summary>
/// <param name="context">The context.</param>
public void Execute( IJobExecutionContext context )
{
var rockContext = new RockContext();
var groupRequirementService = new GroupRequirementService( rockContext );
var groupMemberRequirementService = new GroupMemberRequirementService( rockContext );
var groupMemberService = new GroupMemberService( rockContext );
// we only need to consider group requirements that are based on a DataView or SQL
var groupRequirementQry = groupRequirementService.Queryable()
.Where( a => a.GroupRequirementType.RequirementCheckType != RequirementCheckType.Manual )
.AsNoTracking();
var calculationExceptions = new List<Exception>();
foreach ( var groupRequirement in groupRequirementQry.Include( i => i.GroupRequirementType ).AsNoTracking().ToList() )
{
try
{
var groupMemberQry = groupMemberService.Queryable().Where( a => a.GroupId == groupRequirement.GroupId ).AsNoTracking();
var personQry = groupMemberQry.Select( a => a.Person );
var currentDateTime = RockDateTime.Now;
var expireDaysCount = groupRequirement.GroupRequirementType.ExpireInDays.Value;
var qryGroupMemberRequirementsAlreadyOK = groupMemberRequirementService.Queryable().Where( a => a.GroupRequirementId == groupRequirement.Id );
if ( groupRequirement.GroupRequirementType.CanExpire && groupRequirement.GroupRequirementType.ExpireInDays.HasValue )
{
// Expirable: don't recalculate members that already met the requirement within the expiredays
qryGroupMemberRequirementsAlreadyOK = qryGroupMemberRequirementsAlreadyOK.Where( a => a.RequirementMetDateTime.HasValue && SqlFunctions.DateDiff( "day", a.RequirementMetDateTime, currentDateTime ) < expireDaysCount );
}
else
{
// No Expiration: don't recalculate members that already met the requirement
qryGroupMemberRequirementsAlreadyOK = qryGroupMemberRequirementsAlreadyOK.Where( a => a.RequirementMetDateTime.HasValue );
}
personQry = personQry.Where( a => !qryGroupMemberRequirementsAlreadyOK.Any( r => r.GroupMember.PersonId == a.Id ) );
var results = groupRequirement.PersonQueryableMeetsGroupRequirement( rockContext, personQry, groupRequirement.GroupRoleId ).ToList();
foreach ( var result in results )
{
// use a fresh rockContext per Update so that ChangeTracker doesn't get bogged down
var rockContextUpdate = new RockContext();
groupRequirement.UpdateGroupMemberRequirementResult( rockContextUpdate, result.PersonId, result.MeetsGroupRequirement );
rockContextUpdate.SaveChanges();
}
}
catch ( Exception ex )
{
calculationExceptions.Add( new Exception( string.Format( "Exception when calculating group requirement: ", groupRequirement ), ex ) );
}
}
if ( calculationExceptions.Any() )
{
throw new AggregateException( "One or more group requirement calculations failed ", calculationExceptions );
}
}