/// <summary> /// Shows the edit. /// </summary> /// <param name="emailTemplateId">The email template id.</param> protected void ShowEdit(int emailTemplateId) { var globalAttributes = GlobalAttributesCache.Get(); string globalFromName = globalAttributes.GetValue("OrganizationName"); tbFromName.Help = string.Format("If a From Name value is not entered the 'Organization Name' Global Attribute value of '{0}' will be used when this template is sent. <small><span class='tip tip-lava'></span></small>", globalFromName); string globalFrom = globalAttributes.GetValue("OrganizationEmail"); tbFrom.Help = string.Format("If a From Address value is not entered the 'Organization Email' Global Attribute value of '{0}' will be used when this template is sent. <small><span class='tip tip-lava'></span></small>", globalFrom); tbTo.Help = "You can specify multiple email addresses by separating them with commas or semi-colons."; SystemEmailService emailTemplateService = new SystemEmailService(new RockContext()); SystemEmail emailTemplate = emailTemplateService.Get(emailTemplateId); if (emailTemplate != null) { pdAuditDetails.Visible = true; pdAuditDetails.SetEntity(emailTemplate, ResolveRockUrl("~")); lActionTitle.Text = ActionTitle.Edit(SystemEmail.FriendlyTypeName).FormatAsHtmlTitle(); hfEmailTemplateId.Value = emailTemplate.Id.ToString(); cpCategory.SetValue(emailTemplate.CategoryId); tbTitle.Text = emailTemplate.Title; tbFromName.Text = emailTemplate.FromName; tbFrom.Text = emailTemplate.From; tbTo.Text = emailTemplate.To; tbCc.Text = emailTemplate.Cc; tbBcc.Text = emailTemplate.Bcc; tbSubject.Text = emailTemplate.Subject; tbBody.Text = emailTemplate.Body; } else { pdAuditDetails.Visible = false; lActionTitle.Text = ActionTitle.Add(SystemEmail.FriendlyTypeName).FormatAsHtmlTitle(); hfEmailTemplateId.Value = 0.ToString(); cpCategory.SetValue((int?)null); tbTitle.Text = string.Empty; tbFromName.Text = string.Empty; tbFrom.Text = string.Empty; tbTo.Text = string.Empty; tbCc.Text = string.Empty; tbBcc.Text = string.Empty; tbSubject.Text = string.Empty; tbBody.Text = string.Empty; } }
/// <summary> /// Handles the Delete event of the gEmailTemplates 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 gEmailTemplates_Delete( object sender, RowEventArgs e ) { var rockContext = new RockContext(); SystemEmailService emailTemplateService = new SystemEmailService( rockContext ); SystemEmail emailTemplate = emailTemplateService.Get( (int)gEmailTemplates.DataKeys[e.RowIndex]["id"] ); if ( emailTemplate != null ) { emailTemplateService.Delete( emailTemplate ); rockContext.SaveChanges(); } BindGrid(); }
/// <summary> /// Handles the Delete event of the gEmailTemplates 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 gEmailTemplates_Delete(object sender, RowEventArgs e) { var rockContext = new RockContext(); SystemEmailService emailTemplateService = new SystemEmailService(rockContext); SystemEmail emailTemplate = emailTemplateService.Get(e.RowKeyId); if (emailTemplate != null) { emailTemplateService.Delete(emailTemplate); rockContext.SaveChanges(); } BindGrid(); }
/// <summary> /// Sends the welcome email. /// </summary> /// <param name="systemEmailId">The system email identifier.</param> /// <param name="personId">The person identifier.</param> /// <param name="syncGroup">The synchronize group.</param> /// <param name="createLogin">if set to <c>true</c> [create login].</param> /// <param name="requirePasswordReset">if set to <c>true</c> [require password reset].</param> private void SendWelcomeEmail(int systemEmailId, int personId, Group syncGroup, bool createLogin, bool requirePasswordReset) { using (var rockContext = new RockContext()) { SystemEmailService emailService = new SystemEmailService(rockContext); var systemEmail = emailService.Get(systemEmailId); if (systemEmail != null) { string newPassword = string.Empty; var recipients = new List <RecipientData>(); var mergeFields = new Dictionary <string, object>(); mergeFields.Add("Group", syncGroup); // get person var recipient = new PersonService(rockContext).Queryable("Users").Where(p => p.Id == personId).FirstOrDefault(); if (!string.IsNullOrWhiteSpace(recipient.Email)) { if (createLogin && recipient.Users.Count == 0) { newPassword = System.Web.Security.Membership.GeneratePassword(9, 1); // create user string username = Rock.Security.Authentication.Database.GenerateUsername(recipient.NickName, recipient.LastName); UserLogin login = UserLoginService.Create( rockContext, recipient, Rock.Model.AuthenticationServiceType.Internal, EntityTypeCache.Read(Rock.SystemGuid.EntityType.AUTHENTICATION_DATABASE.AsGuid()).Id, username, newPassword, true, requirePasswordReset); } mergeFields.Add("Person", recipient); mergeFields.Add("NewPassword", newPassword); mergeFields.Add("CreateLogin", createLogin); recipients.Add(new RecipientData(recipient.Email, mergeFields)); var appRoot = Rock.Web.Cache.GlobalAttributesCache.Read(rockContext).GetValue("ExternalApplicationRoot"); Email.Send(systemEmail.Guid, recipients, appRoot); } } } }
/// <summary> /// Shows the edit. /// </summary> /// <param name="emailTemplateId">The email template id.</param> protected void ShowEdit(int emailTemplateId) { var globalAttributes = GlobalAttributesCache.Read(); string globalFromName = globalAttributes.GetValue("OrganizationName"); tbFromName.Help = string.Format("If a From Name value is not entered the 'Organization Name' Global Attribute value of '{0}' will be used when this template is sent.", globalFromName); string globalFrom = globalAttributes.GetValue("OrganizationEmail"); tbFrom.Help = string.Format("If a From Address value is not entered the 'Organization Email' Global Attribute value of '{0}' will be used when this template is sent.", globalFrom); SystemEmailService emailTemplateService = new SystemEmailService(new RockContext()); SystemEmail emailTemplate = emailTemplateService.Get(emailTemplateId); if (emailTemplate != null) { lActionTitle.Text = ActionTitle.Edit(SystemEmail.FriendlyTypeName).FormatAsHtmlTitle(); hfEmailTemplateId.Value = emailTemplate.Id.ToString(); tbCategory.Text = emailTemplate.Category; tbTitle.Text = emailTemplate.Title; tbFromName.Text = emailTemplate.FromName; tbFrom.Text = emailTemplate.From; tbTo.Text = emailTemplate.To; tbCc.Text = emailTemplate.Cc; tbBcc.Text = emailTemplate.Bcc; tbSubject.Text = emailTemplate.Subject; tbBody.Text = emailTemplate.Body; } else { lActionTitle.Text = ActionTitle.Add(SystemEmail.FriendlyTypeName).FormatAsHtmlTitle(); hfEmailTemplateId.Value = 0.ToString(); tbCategory.Text = string.Empty; tbTitle.Text = string.Empty; tbFromName.Text = string.Empty; tbFrom.Text = string.Empty; tbTo.Text = string.Empty; tbCc.Text = string.Empty; tbBcc.Text = string.Empty; tbSubject.Text = string.Empty; tbBody.Text = string.Empty; } }
/// <summary> /// Handles the Click event of the btnSave 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 btnSave_Click(object sender, EventArgs e) { var rockContext = new RockContext(); SystemEmailService emailTemplateService = new SystemEmailService(rockContext); SystemEmail emailTemplate; int emailTemplateId = int.Parse(hfEmailTemplateId.Value); if (emailTemplateId == 0) { emailTemplate = new SystemEmail(); emailTemplateService.Add(emailTemplate); } else { emailTemplate = emailTemplateService.Get(emailTemplateId); } emailTemplate.CategoryId = cpCategory.SelectedValueAsInt(); emailTemplate.Title = tbTitle.Text; emailTemplate.FromName = tbFromName.Text; emailTemplate.From = tbFrom.Text; emailTemplate.To = tbTo.Text; emailTemplate.Cc = tbCc.Text; emailTemplate.Bcc = tbBcc.Text; emailTemplate.Subject = tbSubject.Text; emailTemplate.Body = tbBody.Text; if (!emailTemplate.IsValid) { // Controls will render the error messages return; } rockContext.SaveChanges(); NavigateToParentPage(); }
/// <summary> /// Sends the exit email. /// </summary> /// <param name="systemEmailId">The system email identifier.</param> /// <param name="recipient">The recipient.</param> /// <param name="syncGroup">The synchronize group.</param> private void SendExitEmail(int systemEmailId, Person recipient, Group syncGroup) { if (!string.IsNullOrWhiteSpace(recipient.Email)) { using (var rockContext = new RockContext()) { SystemEmailService emailService = new SystemEmailService(rockContext); var systemEmail = emailService.Get(systemEmailId); if (systemEmail != null) { var recipients = new List <RecipientData>(); var mergeFields = new Dictionary <string, object>(); mergeFields.Add("Group", syncGroup); mergeFields.Add("Person", recipient); recipients.Add(new RecipientData(recipient.Email, mergeFields)); var appRoot = Rock.Web.Cache.GlobalAttributesCache.Read(rockContext).GetValue("ExternalApplicationRoot"); Email.Send(systemEmail.Guid, recipients, appRoot); } } } }
/// <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; // Get the details for the email that we'll be sending out. Guid?systemEmailGuid = dataMap.GetString("ExpiringCreditCardEmail").AsGuidOrNull(); SystemEmailService emailService = new SystemEmailService(rockContext); SystemEmail systemEmail = null; if (systemEmailGuid.HasValue) { systemEmail = emailService.Get(systemEmailGuid.Value); } if (systemEmail == null) { throw new Exception("Expiring credit card email is missing."); } // Fetch the configured Workflow once if one was set, we'll use it later. Guid?workflowGuid = dataMap.GetString("Workflow").AsGuidOrNull(); WorkflowTypeCache workflowType = null; var workflowService = new WorkflowService(rockContext); if (workflowGuid != null) { workflowType = WorkflowTypeCache.Get(workflowGuid.Value); } var qry = new FinancialScheduledTransactionService(rockContext) .Queryable("ScheduledTransactionDetails,FinancialPaymentDetail.CurrencyTypeValue,FinancialPaymentDetail.CreditCardTypeValue") .Where(t => t.IsActive && t.FinancialPaymentDetail.ExpirationMonthEncrypted != null && (t.EndDate == null || t.EndDate > DateTime.Now)) .AsNoTracking(); // Get the current month and year DateTime now = DateTime.Now; int month = now.Month; int year = now.Year; int counter = 0; var errors = new List <string>(); foreach (var transaction in qry) { int?expirationMonthDecrypted = Encryption.DecryptString(transaction.FinancialPaymentDetail.ExpirationMonthEncrypted).AsIntegerOrNull(); int?expirationYearDecrypted = Encryption.DecryptString(transaction.FinancialPaymentDetail.ExpirationYearEncrypted).AsIntegerOrNull(); if (expirationMonthDecrypted.HasValue && expirationMonthDecrypted.HasValue) { string acctNum = string.Empty; if (!string.IsNullOrEmpty(transaction.FinancialPaymentDetail.AccountNumberMasked) && transaction.FinancialPaymentDetail.AccountNumberMasked.Length >= 4) { acctNum = transaction.FinancialPaymentDetail.AccountNumberMasked.Substring(transaction.FinancialPaymentDetail.AccountNumberMasked.Length - 4); } int warningYear = expirationYearDecrypted.Value; int warningMonth = expirationMonthDecrypted.Value - 1; if (warningMonth == 0) { warningYear -= 1; warningMonth = 12; } string warningDate = warningMonth.ToString() + warningYear.ToString(); string currentMonthString = month.ToString() + year.ToString(); if (warningDate == currentMonthString) { // as per ISO7813 https://en.wikipedia.org/wiki/ISO/IEC_7813 var expirationDate = string.Format("{0:D2}/{1:D2}", expirationMonthDecrypted, expirationYearDecrypted); var recipients = new List <RecipientData>(); var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null); var person = transaction.AuthorizedPersonAlias.Person; if (!person.IsEmailActive || person.Email.IsNullOrWhiteSpace() || person.EmailPreference == EmailPreference.DoNotEmail) { continue; } mergeFields.Add("Person", person); mergeFields.Add("Card", acctNum); mergeFields.Add("Expiring", expirationDate); recipients.Add(new RecipientData(person.Email, mergeFields)); var emailMessage = new RockEmailMessage(systemEmail.Guid); emailMessage.SetRecipients(recipients); var emailErrors = new List <string>(); emailMessage.Send(out emailErrors); errors.AddRange(emailErrors); // Start workflow for this person if (workflowType != null) { Dictionary <string, string> attributes = new Dictionary <string, string>(); attributes.Add("Person", transaction.AuthorizedPersonAlias.Guid.ToString()); attributes.Add("Card", acctNum); attributes.Add("Expiring", expirationDate); StartWorkflow(workflowService, workflowType, attributes, string.Format("{0} (scheduled transaction Id: {1})", person.FullName, transaction.Id)); } counter++; } } } context.Result = string.Format("{0} scheduled credit card transactions were examined with {1} notice(s) sent.", qry.Count(), counter); if (errors.Any()) { StringBuilder sb = new StringBuilder(); sb.AppendLine(); sb.Append(string.Format("{0} Errors: ", errors.Count())); errors.ForEach(e => { sb.AppendLine(); sb.Append(e); }); string errorMessage = sb.ToString(); context.Result += errorMessage; var exception = new Exception(errorMessage); HttpContext context2 = HttpContext.Current; ExceptionLogService.LogException(exception, context2); throw exception; } }
/// <summary> /// Sends the welcome email. /// </summary> /// <param name="systemEmailId">The system email identifier.</param> /// <param name="personId">The person identifier.</param> /// <param name="syncGroup">The synchronize group.</param> /// <param name="createLogin">if set to <c>true</c> [create login].</param> private void SendWelcomeEmail( int systemEmailId, int personId, Group syncGroup, bool createLogin ) { using ( var rockContext = new RockContext() ) { SystemEmailService emailService = new SystemEmailService( rockContext ); var systemEmail = emailService.Get( systemEmailId ); if ( systemEmail != null ) { string newPassword = string.Empty; var recipients = new List<RecipientData>(); var mergeFields = new Dictionary<string, object>(); mergeFields.Add( "Group", syncGroup ); // get person var recipient = new PersonService( rockContext ).Queryable( "Users" ).Where( p => p.Id == personId ).FirstOrDefault(); if ( !string.IsNullOrWhiteSpace( recipient.Email ) ) { if ( createLogin && recipient.Users.Count == 0 ) { newPassword = System.Web.Security.Membership.GeneratePassword( 9, 1 ); // create user string username = Rock.Security.Authentication.Database.GenerateUsername( recipient.NickName, recipient.LastName ); UserLogin login = UserLoginService.Create( rockContext, recipient, Rock.Model.AuthenticationServiceType.Internal, EntityTypeCache.Read( Rock.SystemGuid.EntityType.AUTHENTICATION_DATABASE.AsGuid() ).Id, username, newPassword, true ); } mergeFields.Add( "Person", recipient ); mergeFields.Add( "NewPassword", newPassword ); mergeFields.Add( "CreateLogin", createLogin ); recipients.Add( new RecipientData( recipient.Email, mergeFields ) ); var appRoot = Rock.Web.Cache.GlobalAttributesCache.Read( rockContext ).GetValue( "ExternalApplicationRoot" ); Email.Send( systemEmail.Guid, recipients, appRoot ); } } } }
/// <summary> /// Sends the exit email. /// </summary> /// <param name="systemEmailId">The system email identifier.</param> /// <param name="recipient">The recipient.</param> /// <param name="syncGroup">The synchronize group.</param> private void SendExitEmail( int systemEmailId, Person recipient, Group syncGroup ) { if ( !string.IsNullOrWhiteSpace( recipient.Email ) ) { using ( var rockContext = new RockContext() ) { SystemEmailService emailService = new SystemEmailService( rockContext ); var systemEmail = emailService.Get( systemEmailId ); if ( systemEmail != null ) { var recipients = new List<RecipientData>(); var mergeFields = new Dictionary<string, object>(); mergeFields.Add( "Group", syncGroup ); mergeFields.Add( "Person", recipient ); recipients.Add( new RecipientData( recipient.Email, mergeFields ) ); var appRoot = Rock.Web.Cache.GlobalAttributesCache.Read( rockContext ).GetValue( "ExternalApplicationRoot" ); Email.Send( systemEmail.Guid, recipients, appRoot ); } } } }
/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> public void Execute( IJobExecutionContext context ) { var rockContext = new RockContext(); var personService = new PersonService( rockContext ); JobDataMap dataMap = context.JobDetail.JobDataMap; Guid? systemEmailGuid = dataMap.GetString( "BirthdayEmail" ).AsGuidOrNull(); 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; } var activeStatusGuid = Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_ACTIVE.AsGuid(); // only include alive people that have record status of Active var personQry = personService.Queryable( false, false ).Where( a => a.RecordStatusValue.Guid == activeStatusGuid && a.IsDeceased == false ); var ageRange = ( dataMap.GetString( "AgeRange" ) ?? string.Empty ).Split( ',' ); if ( ageRange.Length == 2 ) { int? minimumAge = ageRange[0].AsIntegerOrNull(); int? maximumAge = ageRange[1].AsIntegerOrNull(); personQry = personQry.WhereAgeRange( minimumAge, maximumAge, true ); } // only include people whose birthday is today (which can be determined from the computed DaysUntilBirthday column) personQry = personQry.Where( a => a.DaysUntilBirthday.HasValue && a.DaysUntilBirthday == 0 ); var connectionStatusGuids = ( dataMap.GetString( "ConnectionStatuses" ) ?? string.Empty ).Split( ',' ).AsGuidList(); if ( connectionStatusGuids.Any() ) { personQry = personQry.Where( a => connectionStatusGuids.Contains( a.ConnectionStatusValue.Guid ) ); } // only include people that have an email address and want an email personQry = personQry.Where( a => ( a.Email != null ) && ( a.Email != "" ) && ( a.EmailPreference == EmailPreference.EmailAllowed ) ); var recipients = new List<RecipientData>(); var personList = personQry.AsNoTracking().ToList(); foreach ( var person in personList ) { var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields( null ); mergeFields.Add( "Person", person ); recipients.Add( new RecipientData( person.Email, mergeFields ) ); } var appRoot = Rock.Web.Cache.GlobalAttributesCache.Read( rockContext ).GetValue( "ExternalApplicationRoot" ); Email.Send( systemEmail.Guid, recipients, appRoot ); context.Result = string.Format( "{0} birthday emails sent", recipients.Count() ); }
/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> public void Execute(IJobExecutionContext context) { var rockContext = new RockContext(); var personService = new PersonService(rockContext); JobDataMap dataMap = context.JobDetail.JobDataMap; Guid? systemEmailGuid = dataMap.GetString("BirthdayEmail").AsGuidOrNull(); 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; } var activeStatusGuid = Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_ACTIVE.AsGuid(); // only include alive people that have record status of Active var personQry = personService.Queryable(false, false).Where(a => a.RecordStatusValue.Guid == activeStatusGuid && a.IsDeceased == false); var ageRange = (dataMap.GetString("AgeRange") ?? string.Empty).Split(','); if (ageRange.Length == 2) { int?minimumAge = ageRange[0].AsIntegerOrNull(); int?maximumAge = ageRange[1].AsIntegerOrNull(); personQry = personQry.WhereAgeRange(minimumAge, maximumAge, true); } // only include people whose birthday is today (which can be determined from the computed DaysUntilBirthday column) personQry = personQry.Where(a => a.DaysUntilBirthday.HasValue && a.DaysUntilBirthday == 0); var connectionStatusGuids = (dataMap.GetString("ConnectionStatuses") ?? string.Empty).Split(',').AsGuidList(); if (connectionStatusGuids.Any()) { personQry = personQry.Where(a => connectionStatusGuids.Contains(a.ConnectionStatusValue.Guid)); } // only include people that have an email address and want an email personQry = personQry.Where(a => (a.Email != null) && (a.Email != string.Empty) && (a.EmailPreference != EmailPreference.DoNotEmail) && (a.IsEmailActive)); var recipients = new List <RecipientData>(); var personList = personQry.AsNoTracking().ToList(); foreach (var person in personList) { var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null); mergeFields.Add("Person", person); recipients.Add(new RecipientData(person.Email, mergeFields)); } var emailMessage = new RockEmailMessage(systemEmail.Guid); emailMessage.SetRecipients(recipients); var errors = new List <string>(); emailMessage.Send(out errors); context.Result = string.Format("{0} birthday emails sent", recipients.Count()); if (errors.Any()) { StringBuilder sb = new StringBuilder(); sb.AppendLine(); sb.Append(string.Format("{0} Errors: ", errors.Count())); errors.ForEach(e => { sb.AppendLine(); sb.Append(e); }); string errorMessage = sb.ToString(); context.Result += errorMessage; var exception = new Exception(errorMessage); HttpContext context2 = HttpContext.Current; ExceptionLogService.LogException(exception, context2); throw exception; } }
/// <summary> /// Handles the Click event of the btnSave 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 btnSave_Click( object sender, EventArgs e ) { var rockContext = new RockContext(); SystemEmailService emailTemplateService = new SystemEmailService( rockContext ); SystemEmail emailTemplate; int emailTemplateId = int.Parse(hfEmailTemplateId.Value); if ( emailTemplateId == 0 ) { emailTemplate = new SystemEmail(); emailTemplateService.Add( emailTemplate ); } else { emailTemplate = emailTemplateService.Get( emailTemplateId ); } emailTemplate.Category = tbCategory.Text; emailTemplate.Title = tbTitle.Text; emailTemplate.FromName = tbFromName.Text; emailTemplate.From = tbFrom.Text; emailTemplate.To = tbTo.Text; emailTemplate.Cc = tbCc.Text; emailTemplate.Bcc = tbBcc.Text; emailTemplate.Subject = tbSubject.Text; emailTemplate.Body = tbBody.Text; if ( !emailTemplate.IsValid ) { // Controls will render the error messages return; } rockContext.SaveChanges(); NavigateToParentPage(); }
/// <summary> /// Shows the edit. /// </summary> /// <param name="emailTemplateId">The email template id.</param> protected void ShowEdit( int emailTemplateId ) { var globalAttributes = GlobalAttributesCache.Read(); string globalFromName = globalAttributes.GetValue( "OrganizationName" ); tbFromName.Help = string.Format( "If a From Name value is not entered the 'Organization Name' Global Attribute value of '{0}' will be used when this template is sent.", globalFromName ); string globalFrom = globalAttributes.GetValue( "OrganizationEmail" ); tbFrom.Help = string.Format( "If a From Address value is not entered the 'Organization Email' Global Attribute value of '{0}' will be used when this template is sent.", globalFrom ); SystemEmailService emailTemplateService = new SystemEmailService( new RockContext() ); SystemEmail emailTemplate = emailTemplateService.Get( emailTemplateId ); if ( emailTemplate != null ) { lActionTitle.Text = ActionTitle.Edit( SystemEmail.FriendlyTypeName ).FormatAsHtmlTitle(); hfEmailTemplateId.Value = emailTemplate.Id.ToString(); tbCategory.Text = emailTemplate.Category; tbTitle.Text = emailTemplate.Title; tbFromName.Text = emailTemplate.FromName; tbFrom.Text = emailTemplate.From; tbTo.Text = emailTemplate.To; tbCc.Text = emailTemplate.Cc; tbBcc.Text = emailTemplate.Bcc; tbSubject.Text = emailTemplate.Subject; tbBody.Text = emailTemplate.Body; } else { lActionTitle.Text = ActionTitle.Add( SystemEmail.FriendlyTypeName ).FormatAsHtmlTitle(); hfEmailTemplateId.Value = 0.ToString(); tbCategory.Text = string.Empty; tbTitle.Text = string.Empty; tbFromName.Text = string.Empty; tbFrom.Text = string.Empty; tbTo.Text = string.Empty; tbCc.Text = string.Empty; tbBcc.Text = string.Empty; tbSubject.Text = string.Empty; tbBody.Text = string.Empty; } }
/// <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; // Get the details for the email that we'll be sending out. Guid? systemEmailGuid = dataMap.GetString( "ExpiringCreditCardEmail" ).AsGuidOrNull(); SystemEmailService emailService = new SystemEmailService( rockContext ); SystemEmail systemEmail = null; if ( systemEmailGuid.HasValue ) { systemEmail = emailService.Get( systemEmailGuid.Value ); } // Fetch the configured Workflow once if one was set, we'll use it later. Guid? workflowGuid = dataMap.GetString( "Workflow" ).AsGuidOrNull(); WorkflowType workflowType = null; var workflowTypeService = new WorkflowTypeService( rockContext ); var workflowService = new WorkflowService( rockContext ); if ( workflowGuid != null ) { workflowType = workflowTypeService.Get( workflowGuid.Value ); } var qry = new FinancialScheduledTransactionService( rockContext ) .Queryable( "ScheduledTransactionDetails,FinancialPaymentDetail.CurrencyTypeValue,FinancialPaymentDetail.CreditCardTypeValue" ) .Where( t => t.IsActive && t.FinancialPaymentDetail.ExpirationMonthEncrypted != null && ( t.EndDate == null || t.EndDate > DateTime.Now ) ) .AsNoTracking(); var appRoot = Rock.Web.Cache.GlobalAttributesCache.Read( rockContext ).GetValue( "PublicApplicationRoot" ); // Get the current month and year DateTime now = DateTime.Now; int month = now.Month; int year = now.Year; int counter = 0; foreach ( var transaction in qry ) { int expirationMonthDecrypted = Int32.Parse( Encryption.DecryptString( transaction.FinancialPaymentDetail.ExpirationMonthEncrypted ) ); int expirationYearDecrypted = Int32.Parse( Encryption.DecryptString( transaction.FinancialPaymentDetail.ExpirationYearEncrypted ) ); string acctNum = transaction.FinancialPaymentDetail.AccountNumberMasked.Substring( transaction.FinancialPaymentDetail.AccountNumberMasked.Length - 4 ); int warningYear = expirationYearDecrypted; int warningMonth = expirationMonthDecrypted - 1; if ( warningMonth == 0 ) { warningYear -= 1; warningMonth = 12; } string warningDate = warningMonth.ToString() + warningYear.ToString(); string currentMonthString = month.ToString() + year.ToString(); if ( warningDate == currentMonthString ) { // as per ISO7813 https://en.wikipedia.org/wiki/ISO/IEC_7813 var expirationDate = string.Format( "{0:D2}/{1:D2}", expirationMonthDecrypted, expirationYearDecrypted ); var recipients = new List<RecipientData>(); var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields( null ); var person = transaction.AuthorizedPersonAlias.Person; mergeFields.Add( "Person", person ); mergeFields.Add( "Card", acctNum ); mergeFields.Add( "Expiring", expirationDate ); recipients.Add( new RecipientData( person.Email, mergeFields ) ); Email.Send( systemEmail.Guid, recipients, appRoot ); // Start workflow for this person if ( workflowType != null ) { Dictionary<string, string> attributes = new Dictionary<string, string>(); attributes.Add( "Person", transaction.AuthorizedPersonAlias.Guid.ToString() ); attributes.Add( "Card", acctNum ); attributes.Add( "Expiring", expirationDate ); StartWorkflow( workflowService, workflowType, attributes, string.Format( "{0} (scheduled transaction Id: {1})", person.FullName, transaction.Id ) ); } counter++; } } context.Result = string.Format( "{0} scheduled credit card transactions were examined with {1} notice(s) sent.", qry.Count(), counter ); }
/// <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> /// Private method called by Execute() to process the job. /// </summary> private void ProcessJob(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; int notificationsSent = 0; int errorsEncountered = 0; int absentMembersCount = 0; int sendFailed = 0; // get groups set to sync RockContext rockContext = new RockContext(); Guid?groupTypeGuid = dataMap.GetString(AttributeKey.GroupType).AsGuidOrNull(); Guid?systemEmailGuid = dataMap.GetString(AttributeKey.NotificationEmail).AsGuidOrNull(); Guid?groupRoleFilterGuid = dataMap.GetString(AttributeKey.GroupRoleFilter).AsGuidOrNull(); int minimumAbsences = dataMap.GetString(AttributeKey.MinimumAbsences).AsInteger(); // get system email SystemEmailService emailService = new SystemEmailService(rockContext); SystemEmail systemEmail = null; if (!systemEmailGuid.HasValue || systemEmailGuid == Guid.Empty) { context.Result = "Job failed. Unable to find System Email"; throw new Exception("No system email found."); } if (minimumAbsences == default(int)) { context.Result = "Job failed. The is no minimum absense count entered."; throw new Exception("No minimum absense count found."); } systemEmail = emailService.Get(systemEmailGuid.Value); // get group members if (!groupTypeGuid.HasValue || groupTypeGuid == Guid.Empty) { context.Result = "Job failed. Unable to find group type"; throw new Exception("No group type found."); } var groupMemberQry = new GroupMemberService(rockContext).Queryable("Group, Group.Members.GroupRole") .Where(m => m.Group.GroupType.Guid == groupTypeGuid.Value); if (groupRoleFilterGuid.HasValue) { groupMemberQry = groupMemberQry.Where(m => m.GroupRole.Guid == groupRoleFilterGuid.Value); } var groupMembers = groupMemberQry.GroupBy(m => m.Group); var errorList = new List <string>(); foreach (var groupGroupMember in groupMembers) { var group = groupGroupMember.Key; var filteredPersons = groupGroupMember.Select(a => a.PersonId); // get list of leaders var groupLeaders = group.Members.Where(m => m.GroupRole.IsLeader == true && m.Person != null && m.Person.Email != null && m.Person.Email != string.Empty); if (!groupLeaders.Any()) { errorList.Add("Unable to send emails to members in group " + group.Name + " because there is no group leader"); continue; } // Get all the occurrences for this group var occurrences = new AttendanceOccurrenceService(rockContext) .Queryable("Attendees.PersonAlias.Person") .Where(a => a.DidNotOccur.HasValue && !a.DidNotOccur.Value && a.GroupId == group.Id) .OrderByDescending(a => a.OccurrenceDate) .Take(minimumAbsences) .ToList(); if (occurrences.Count == minimumAbsences) { var absentPersons = occurrences .SelectMany(a => a.Attendees) .Where(a => a.DidAttend.HasValue && !a.DidAttend.Value && filteredPersons.Contains(a.PersonAlias.PersonId)) .GroupBy(a => a.PersonAlias.Person) .Where(a => a.Count() == minimumAbsences) .Select(a => a.Key) .ToList(); if (absentPersons.Count > 0) { var recipients = new List <RockEmailMessageRecipient>(); foreach (var leader in groupLeaders) { // create merge object var mergeFields = new Dictionary <string, object>(); mergeFields.Add("AbsentMembers", absentPersons); mergeFields.Add("Group", group); mergeFields.Add("Person", leader.Person); recipients.Add(new RockEmailMessageRecipient(leader.Person, mergeFields)); } var errorMessages = new List <string>(); var emailMessage = new RockEmailMessage(systemEmail.Guid); emailMessage.SetRecipients(recipients); var sendSuccess = emailMessage.Send(out errorMessages); if (!sendSuccess) { sendFailed++; } errorsEncountered += errorMessages.Count; errorList.AddRange(errorMessages); // be conservative: only mark as notified if we are sure the email didn't fail if (errorMessages.Any()) { continue; } absentMembersCount += absentPersons.Count; notificationsSent += recipients.Count(); } } } context.Result = string.Format("Sent {0} emails to leaders for {1} absent members. {2} errors encountered. {3} times Send reported a fail.", notificationsSent, absentMembersCount, errorsEncountered, sendFailed); if (errorList.Any()) { StringBuilder sb = new StringBuilder(); sb.AppendLine(); sb.Append("Errors in GroupLeaderAbsenceNotifications: "); errorList.ForEach(e => { sb.AppendLine(); sb.Append(e); }); string errors = sb.ToString(); context.Result += errors; throw new Exception(errors); } }
/// <summary> /// Starts the refund process. /// </summary> private void StartRefunds() { long totalMilliseconds = 0; var importTask = new Task(() => { // wait a little so the browser can render and start listening to events System.Threading.Thread.Sleep(1000); _hubContext.Clients.All.showButtons(this.SignalRNotificationKey, false); Stopwatch stopwatch = Stopwatch.StartNew(); List <int> registrationTemplateIds = rtpRegistrationTemplate.ItemIds.AsIntegerList(); registrationTemplateIds.RemoveAll(i => i.Equals(0)); if (registrationTemplateIds.Count > 0) { RockContext rockContext = new RockContext(); List <int> registrationInstanceIds = new List <int>(); if (ddlRegistrationInstance.SelectedValueAsId().HasValue&& ddlRegistrationInstance.SelectedValueAsId() > 0) { registrationInstanceIds.Add(ddlRegistrationInstance.SelectedValueAsId().Value); } else { RegistrationTemplateService registrationTemplateService = new RegistrationTemplateService(rockContext); var templates = registrationTemplateService.GetByIds(rtpRegistrationTemplate.ItemIds.AsIntegerList()); int registrationCount = templates.SelectMany(t => t.Instances).SelectMany(i => i.Registrations).Count(); registrationInstanceIds.AddRange(templates.SelectMany(t => t.Instances).OrderBy(i => i.Name).Select(i => i.Id)); } RegistrationInstanceService registrationInstanceService = new RegistrationInstanceService(rockContext); SystemEmailService systemEmailService = new SystemEmailService(rockContext); // Load the registration instance and then iterate through all registrations. var registrations = registrationInstanceService.Queryable().Where(ri => registrationInstanceIds.Contains(ri.Id)).SelectMany(ri => ri.Registrations); int j = 1; foreach (Registration registration in registrations) { bool issuedRefund = false; OnProgress("Processing registration refund " + j + " of " + registrations.Count()); foreach (var payment in registration.GetPayments(rockContext)) { decimal refundAmount = payment.Amount + payment.Transaction.Refunds.Sum(r => r.FinancialTransaction.TotalAmount); // If refunds totalling the amount of the payments have not already been issued if (payment.Amount > 0 && refundAmount > 0) { string errorMessage; using (var refundRockContext = new RockContext()) { var financialTransactionService = new FinancialTransactionService(refundRockContext); var refundTransaction = financialTransactionService.ProcessRefund(payment.Transaction, refundAmount, dvpRefundReason.SelectedDefinedValueId, tbRefundSummary.Text, true, string.Empty, out errorMessage); if (refundTransaction != null) { refundRockContext.SaveChanges(); } if (!string.IsNullOrWhiteSpace(errorMessage)) { results["Fail"] += string.Format("Failed refund for registration {0}: {1}", registration.FirstName + " " + registration.LastName, errorMessage) + Environment.NewLine; } else { results["Success"] += string.Format("Successfully issued {0} refund for registration {1} payment {2} ({3}) - Refund Transaction Id: {4}, Amount: {5}", refundAmount < payment.Amount?"Partial":"Full", registration.FirstName + " " + registration.LastName, payment.Transaction.TransactionCode, payment.Transaction.TotalAmount, refundTransaction.TransactionCode, refundTransaction.TotalAmount.FormatAsCurrency()) + Environment.NewLine; issuedRefund = true; } } System.Threading.Thread.Sleep(2500); } else if (payment.Transaction.Refunds.Count > 0) { results["Success"] += string.Format("Refund already issued for registration {0} payment {1} ({2})", registration.FirstName + " " + registration.LastName, payment.Transaction.TransactionCode, payment.Transaction.TotalAmount) + Environment.NewLine; } } j++; // Send an email if applicable if (issuedRefund && !string.IsNullOrWhiteSpace(registration.ConfirmationEmail) && ddlSystemEmail.SelectedValueAsInt().HasValue&& ddlSystemEmail.SelectedValueAsInt() > 0) { var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage); mergeFields.Add("Registration", registration); SystemEmail systemEmail = systemEmailService.Get(ddlSystemEmail.SelectedValueAsInt().Value); var emailMessage = new RockEmailMessage(systemEmail); emailMessage.AdditionalMergeFields = mergeFields; emailMessage.AddRecipient(new RecipientData(registration.ConfirmationEmail, mergeFields)); emailMessage.CreateCommunicationRecord = true; emailMessage.Send(); } } } stopwatch.Stop(); totalMilliseconds = stopwatch.ElapsedMilliseconds; _hubContext.Clients.All.showButtons(this.SignalRNotificationKey, true); }); importTask.ContinueWith((t) => { if (t.IsFaulted) { foreach (var exception in t.Exception.InnerExceptions) { LogException(exception); } OnProgress("ERROR: " + t.Exception.Message); } else { OnProgress(string.Format("{0} Complete: [{1}ms]", "All refunds have been issued.", totalMilliseconds)); } }); importTask.Start(); }
/// <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 && pendingAge.Value > 0) { 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.Where(l => l.Person != null && l.Person.Email != "")) { // 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) { var emailMessage = new RockEmailMessage(systemEmail.Guid); emailMessage.SetRecipients(recipients); emailMessage.Send(); 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> /// 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 errorsEncountered = 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 || systemEmailGuid == Guid.Empty) { context.Result = "Job failed. Unable to find System Email"; throw new Exception("No system email found."); } systemEmail = emailService.Get(systemEmailGuid.Value); // get group members if (!groupTypeGuid.HasValue || groupTypeGuid == Guid.Empty) { context.Result = "Job failed. Unable to find group type"; throw new Exception("No group type found"); } 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 && pendingAge.Value > 0) { 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); var errorList = new List <string>(); 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(); if (!pendingIndividuals.Any()) { continue; } // get list of leaders var groupLeaders = group.Members.Where(m => m.GroupRole.IsLeader == true && m.Person != null && m.Person.Email != null && m.Person.Email != string.Empty); if (!groupLeaders.Any()) { errorList.Add("Unable to send emails to members in group " + group.Name + " because there is no group leader"); continue; } 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)); } var errorMessages = new List <string>(); var emailMessage = new RockEmailMessage(systemEmail.Guid); emailMessage.SetRecipients(recipients); emailMessage.Send(out errorMessages); errorsEncountered += errorMessages.Count; errorList.AddRange(errorMessages); // be conservative: only mark as notified if we are sure the email didn't fail if (errorMessages.Any()) { continue; } 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. {2} errors encountered.", notificationsSent, pendingMembersCount, errorsEncountered); if (errorList.Any()) { StringBuilder sb = new StringBuilder(); sb.AppendLine(); sb.Append("Errors: "); errorList.ForEach(e => { sb.AppendLine(); sb.Append(e); }); string errors = sb.ToString(); context.Result += errors; throw new Exception(errors); } } catch (Exception ex) { HttpContext context2 = HttpContext.Current; ExceptionLogService.LogException(ex, context2); throw; } }
/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> public void Execute(IJobExecutionContext context) { var rockContext = new RockContext(); var personService = new PersonService(rockContext); JobDataMap dataMap = context.JobDetail.JobDataMap; Guid? systemEmailGuid = dataMap.GetString("BirthdayEmail").AsGuidOrNull(); 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; } var activeStatusGuid = Rock.SystemGuid.DefinedValue.PERSON_RECORD_STATUS_ACTIVE.AsGuid(); // only include alive people that have record status of Active var personQry = personService.Queryable(false, false).Where(a => a.RecordStatusValue.Guid == activeStatusGuid && a.IsDeceased == false); var ageRange = (dataMap.GetString("AgeRange") ?? string.Empty).Split(','); if (ageRange.Length == 2) { int?minimumAge = ageRange[0].AsIntegerOrNull(); int?maximumAge = ageRange[1].AsIntegerOrNull(); personQry = personQry.WhereAgeRange(minimumAge, maximumAge, true); } // only include people whose birthday is today (which can be determined from the computed DaysUntilBirthday column) personQry = personQry.Where(a => a.DaysUntilBirthday.HasValue && a.DaysUntilBirthday == 0); var connectionStatusGuids = (dataMap.GetString("ConnectionStatuses") ?? string.Empty).Split(',').AsGuidList(); if (connectionStatusGuids.Any()) { personQry = personQry.Where(a => connectionStatusGuids.Contains(a.ConnectionStatusValue.Guid)); } // only include people that have an email address and want an email personQry = personQry.Where(a => (a.Email != null) && (a.Email != "") && (a.EmailPreference == EmailPreference.EmailAllowed)); var recipients = new List <RecipientData>(); var personList = personQry.AsNoTracking().ToList(); foreach (var person in personList) { var mergeFields = new Dictionary <string, object>(); mergeFields.Add("Person", person); var globalAttributeFields = Rock.Web.Cache.GlobalAttributesCache.GetMergeFields(null); globalAttributeFields.ToList().ForEach(d => mergeFields.Add(d.Key, d.Value)); recipients.Add(new RecipientData(person.Email, mergeFields)); } var appRoot = Rock.Web.Cache.GlobalAttributesCache.Read(rockContext).GetValue("ExternalApplicationRoot"); Email.Send(systemEmail.Guid, recipients, appRoot); }