/// <summary>
/// Called by the <see cref="IScheduler" /> when a <see cref="ITrigger" />
/// fires that is associated with the <see cref="IJob" />.
/// </summary>
/// <param name="context">The execution context.</param>
/// <remarks>
/// The implementation may wish to set a result object on the
/// JobExecutionContext before this method exits. The result itself
/// is meaningless to Quartz, but may be informative to
/// <see cref="IJobListener" />s or
/// <see cref="ITriggerListener" />s that are watching the job's
/// execution.
/// </remarks>
public virtual void Execute( IJobExecutionContext context )
{
JobDataMap dataMap = context.JobDetail.JobDataMap;
int resendDays = dataMap.GetString( "ResendInviteAfterNumberDays" ).AsIntegerOrNull() ?? 5;
int maxInvites = dataMap.GetString( "MaxInvites" ).AsIntegerOrNull() ?? 2;
int checkDays = dataMap.GetString( "CheckForSignatureDays" ).AsIntegerOrNull() ?? 30;
string folderPath = System.Web.Hosting.HostingEnvironment.MapPath( "~/App_Data/Cache/SignNow" );
var errorMessages = new List<string>();
int signatureRequestsSent = 0;
int documentsUpdated = 0;
// Send documents
using ( var rockContext = new RockContext() )
{
var maxInviteDate = RockDateTime.Today.AddDays( 0 - resendDays );
var maxCheckDays = RockDateTime.Today.AddDays( 0 - checkDays );
var docTypeService = new SignatureDocumentTemplateService( rockContext );
var docService = new SignatureDocumentService( rockContext );
// Check for status updates
foreach ( var document in new SignatureDocumentService( rockContext ).Queryable()
.Where( d =>
(
d.Status == SignatureDocumentStatus.Sent ||
( d.Status == SignatureDocumentStatus.Signed && !d.BinaryFileId.HasValue )
) &&
d.LastInviteDate.HasValue &&
d.LastInviteDate.Value > maxCheckDays )
.ToList() )
{
var updateErrorMessages = new List<string>();
var status = document.Status;
int? binaryFileId = document.BinaryFileId;
if ( docTypeService.UpdateDocumentStatus( document, folderPath, out updateErrorMessages ) )
{
if ( status != document.Status || !binaryFileId.Equals( document.BinaryFileId ) )
{
rockContext.SaveChanges();
documentsUpdated++;
}
}
else
{
errorMessages.AddRange( updateErrorMessages );
}
}
// Send any needed signature requests
var docsSent = new Dictionary<int, List<int>>();
foreach ( var gm in new GroupMemberService( rockContext ).Queryable()
.Where( m =>
m.GroupMemberStatus == GroupMemberStatus.Active &&
m.Group.IsActive &&
m.Person.Email != null &&
m.Person.Email != "" &&
m.Group.RequiredSignatureDocumentTemplate != null &&
!m.Group.RequiredSignatureDocumentTemplate.Documents.Any( d =>
d.AppliesToPersonAlias.PersonId == m.PersonId &&
d.Status == SignatureDocumentStatus.Signed
)
)
.Select( m => new
{
GroupName = m.Group.Name,
Person = m.Person,
DocumentType = m.Group.RequiredSignatureDocumentTemplate
} )
.ToList() )
{
if ( docsSent.ContainsKey( gm.Person.Id ) )
{
if ( docsSent[gm.Person.Id].Contains( gm.DocumentType.Id ) )
{
continue;
}
else
{
docsSent[gm.Person.Id].Add( gm.DocumentType.Id );
}
}
else
{
docsSent.Add( gm.Person.Id, new List<int> { gm.DocumentType.Id } );
}
var document = docService.Queryable()
.Where( d =>
d.SignatureDocumentTemplateId == gm.DocumentType.Id &&
d.AppliesToPersonAlias.PersonId == gm.Person.Id &&
d.AssignedToPersonAlias.PersonId == gm.Person.Id &&
d.Status != SignatureDocumentStatus.Signed
)
.OrderByDescending( d => d.CreatedDateTime )
.FirstOrDefault();
if ( document == null || ( document.InviteCount < maxInvites && document.LastInviteDate < maxInviteDate ) )
{
string documentName = string.Format( "{0}_{1}", gm.GroupName.RemoveSpecialCharacters(), gm.Person.FullName.RemoveSpecialCharacters() );
var sendErrorMessages = new List<string>();
if ( document != null )
{
docTypeService.SendDocument( document, gm.Person.Email, out sendErrorMessages );
}
else
{
docTypeService.SendDocument( gm.DocumentType, gm.Person, gm.Person, documentName, gm.Person.Email, out sendErrorMessages );
}
if ( !errorMessages.Any() )
{
rockContext.SaveChanges();
signatureRequestsSent++;
}
else
{
errorMessages.AddRange( sendErrorMessages );
}
}
}
}
if ( errorMessages.Any() )
{
throw new Exception( "One or more exceptions occurred processing signature documents..." + Environment.NewLine + errorMessages.AsDelimited( Environment.NewLine ) );
}
context.Result = string.Format( "{0} signature requests sent; {1} existing document's status updated", signatureRequestsSent, documentsUpdated );
}