/// <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 var emailService = new SystemCommunicationService(rockContext); SystemCommunication 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); } }