/// <summary>
        /// Executes the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        public virtual void Execute(IJobExecutionContext context)
        {
            JobDataMap    dataMap         = context.JobDetail.JobDataMap;
            int           alertPeriod     = dataMap.GetInt("AlertPeriod");
            Guid?         systemEmailGuid = dataMap.GetString("AlertEmail").AsGuidOrNull();
            List <string> recipientEmails = dataMap.GetString("AlertRecipients").SplitDelimitedValues().ToList();

            if (systemEmailGuid.HasValue && recipientEmails.Any())
            {
                var rockContext = new RockContext();

                int expirationDays = GetJobAttributeValue("ExpirationPeriod", 3, rockContext);
                var cutoffTime     = RockDateTime.Now.AddMinutes(0 - alertPeriod);

                var communications = new CommunicationService(rockContext)
                                     .GetQueued(expirationDays, alertPeriod, false, false)
                                     .Where(c => !c.ReviewedDateTime.HasValue || c.ReviewedDateTime.Value.CompareTo(cutoffTime) < 0) // Make sure communication wasn't just recently approved
                                     .OrderBy(c => c.Id)
                                     .ToList();

                if (communications.Any())
                {
                    var mergeFields = Lava.LavaHelper.GetCommonMergeFields(null);
                    mergeFields.Add("Communications", communications);

                    var emailMessage = new RockEmailMessage(systemEmailGuid.Value);
                    foreach (var email in recipientEmails)
                    {
                        emailMessage.AddRecipient(new RecipientData(email, mergeFields));
                    }
                    emailMessage.Send();
                }
            }
        }
        /// <summary>
        /// Executes the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        public virtual void Execute(IJobExecutionContext context)
        {
            JobDataMap    dataMap         = context.JobDetail.JobDataMap;
            int           alertPeriod     = dataMap.GetInt("AlertPeriod");
            Guid?         systemEmailGuid = dataMap.GetString("AlertEmail").AsGuidOrNull();
            List <string> recipientEmails = dataMap.GetString("AlertRecipients").SplitDelimitedValues().ToList();

            if (systemEmailGuid.HasValue && recipientEmails.Any())
            {
                var rockContext = new RockContext();

                int expirationDays = GetJobAttributeValue("ExpirationPeriod", 3, rockContext);
                var beginWindow    = RockDateTime.Now.AddDays(0 - expirationDays);
                var cutoffTime     = RockDateTime.Now.AddMinutes(0 - alertPeriod);

                var communications = new CommunicationService(rockContext)
                                     .GetQueued(expirationDays, alertPeriod, false, false)
                                     .NotRecentlyApproved(cutoffTime)
                                     .IfScheduledAreInWindow(beginWindow, cutoffTime)
                                     .OrderBy(c => c.Id)
                                     .ToList();

                if (communications.Any())
                {
                    var mergeFields = Lava.LavaHelper.GetCommonMergeFields(null);
                    mergeFields.Add("Communications", communications);

                    var emailMessage = new RockEmailMessage(systemEmailGuid.Value);
                    foreach (var email in recipientEmails)
                    {
                        emailMessage.AddRecipient(RockEmailMessageRecipient.CreateAnonymous(email, mergeFields));
                    }

                    var errors = new List <string>();
                    emailMessage.Send(out errors);

                    context.Result = string.Format("Notified about {0} queued communications. {1} errors encountered.", communications.Count, errors.Count);
                    if (errors.Any())
                    {
                        StringBuilder sb = new StringBuilder();
                        sb.AppendLine();
                        sb.Append("Errors: ");
                        errors.ForEach(e => { sb.AppendLine(); sb.Append(e); });
                        string errorMessage = sb.ToString();
                        context.Result += errorMessage;
                        throw new Exception(errorMessage);
                    }
                }
            }
        }