示例#1
0
        /// <summary>
        /// Sets the system communication.
        /// </summary>
        /// <returns>JobPreviewInfo.</returns>
        private SystemCommunicationPreviewInfo SetSystemCommunication()
        {
            var previewInfo = new SystemCommunicationPreviewInfo();

            var systemCommunicationGuid = GetAttributeValue(AttributeKey.SystemCommunication).AsGuid();

            if (!systemCommunicationGuid.IsEmpty())
            {
                previewInfo.ParameterSettingType = SystemCommunicationPreviewInfo.ParameterSettingTypeEnum.BlockSetting;
                ViewState[ViewStateKey.SystemCommunicationGuid] = systemCommunicationGuid;
            }
            else
            {
                previewInfo.ParameterSettingType = SystemCommunicationPreviewInfo.ParameterSettingTypeEnum.QueryStringParameter;
                var systemCommunicationId = PageParameter(PageParameterKey.SystemCommunicationId).AsInteger();
                if (systemCommunicationId > 0)
                {
                    var systemCommunicationService = new SystemCommunicationService(new RockContext());
                    var systemCommunication        = systemCommunicationService.Get(systemCommunicationId);
                    if (systemCommunication != null)
                    {
                        systemCommunicationGuid = systemCommunication.Guid;
                        ViewState[ViewStateKey.SystemCommunicationGuid] = systemCommunicationGuid;
                    }
                }
            }
            HasSystemCommunication = ViewState[ViewStateKey.SystemCommunicationGuid].ToStringSafe().Length > 0;
            return(previewInfo);
        }
示例#2
0
        /// <summary>
        /// Gets the <see cref="SystemCommunication"/> for a <see cref="GroupType"/>.
        /// </summary>
        /// <param name="groupType">The <see cref="GroupType"/>.</param>
        /// <param name="systemCommunicationService">The <see cref="SystemCommunicationService"/>.</param>
        /// <returns>A <see cref="SystemCommunication"/> if one is set on the <see cref="GroupType"/>, otherwise null.</returns>
        private SystemCommunication GetGroupTypeRsvpReminder(GroupType groupType, SystemCommunicationService systemCommunicationService)
        {
            SystemCommunication groupTypeReminder = null;

            if (groupType.RSVPReminderSystemCommunicationId.HasValue)
            {
                groupTypeReminder = systemCommunicationService.Get(groupType.RSVPReminderSystemCommunicationId.Value);
            }
            return(groupTypeReminder);
        }
示例#3
0
        private SystemCommunication GetSystemCommunication()
        {
            var systemCommunicationGuid = ViewState[ViewStateKey.SystemCommunicationGuid].ToStringSafe().AsGuid();

            if (systemCommunicationGuid != Guid.Empty)
            {
                var communicationService = new SystemCommunicationService(new RockContext());
                return(communicationService.Get(systemCommunicationGuid));
            }

            return(null);
        }
        /// <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();
            SystemCommunicationService emailTemplateService = new SystemCommunicationService(rockContext);
            SystemCommunication        emailTemplate        = emailTemplateService.Get(e.RowKeyId);

            if (emailTemplate != null)
            {
                emailTemplateService.Delete(emailTemplate);
                rockContext.SaveChanges();
            }

            BindGrid();
        }
        /// <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
                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.");
                }

                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 <RockEmailMessageRecipient>();
                    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 RockEmailMessageRecipient(leader.Person, mergeFields));
                    }


                    var errorMessages = new List <string>();
                    var emailMessage  = new RockEmailMessage(systemEmail.Guid);
                    emailMessage.SetRecipients(recipients);
                    var sendSuccess = 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 (sendSuccess == false)
                    {
                        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 && m.GroupId == group.Id && notifiedPersonIds.Contains(m.PersonId)))
                    {
                        pendingGroupMember.IsNotified = true;
                        pendingMembersCount++;
                    }

                    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 in GroupLeaderPendingNotificationJob: ");
                    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 this instance.
        /// </summary>
        /// <param name="message"></param>
        public override void Execute(Message message)
        {
            using (var rockContext = new RockContext())
            {
                // Load the alert and alert type
                var financialTransactionAlertService = new FinancialTransactionAlertService(rockContext);
                var alert = financialTransactionAlertService.Queryable()
                            .AsNoTracking()
                            .Include(a => a.FinancialTransactionAlertType)
                            .FirstOrDefault(a => a.Id == message.FinancialTransactionAlertId);

                var alertType = alert?.FinancialTransactionAlertType;

                // If the alert or alert type are no longer in the database, then there is nothing that can be done
                if (alertType == null)
                {
                    return;
                }

                // Get the person that this alert was generated for. Several of the items below use this
                var personAliasService = new PersonAliasService(rockContext);
                var person             = personAliasService.Queryable()
                                         .AsNoTracking()
                                         .Where(pa => pa.Id == alert.PersonAliasId)
                                         .Select(pa => pa.Person)
                                         .FirstOrDefault();

                // Generate the merge objects for the lava templates used in the items below
                var isoDate           = alert.AlertDateTime.ToISO8601DateString();
                var alertsPageId      = PageCache.Get(SystemGuid.Page.GIVING_ALERTS).Id;
                var relativeAlertLink = $"page/{alertsPageId}?StartDate={isoDate}&EndDate={isoDate}&AlertTypeId={alertType.Id}";

                var mergeObjects = new Dictionary <string, object> {
                    { nameof(FinancialTransactionAlert), alert },
                    { nameof(FinancialTransactionAlertType), alertType },
                    { nameof(Person), person },
                    { "RelativeAlertLink", relativeAlertLink }
                };

                // Launch workflow if configured
                if (alertType.WorkflowTypeId.HasValue)
                {
                    var workflowAttributeValues = new Dictionary <string, string>();
                    workflowAttributeValues.Add(nameof(FinancialTransactionAlert), alert.Guid.ToString());
                    workflowAttributeValues.Add(nameof(FinancialTransactionAlertType), alertType.Guid.ToString());
                    workflowAttributeValues.Add(nameof(Person), person.Guid.ToString());
                    alert.LaunchWorkflow(alertType.WorkflowTypeId, string.Empty, workflowAttributeValues, null);
                }

                // Add the person to a connection opportunity if configured
                if (alertType.ConnectionOpportunityId.HasValue)
                {
                    var connectionOpportunityService = new ConnectionOpportunityService(rockContext);
                    var statuses = connectionOpportunityService.Queryable()
                                   .AsNoTracking()
                                   .Where(co =>
                                          co.Id == alertType.ConnectionOpportunityId)
                                   .SelectMany(co => co.ConnectionType.ConnectionStatuses)
                                   .Where(cs => cs.IsActive)
                                   .ToList()
                                   .OrderBy(cs => cs.Order);

                    var status = statuses.FirstOrDefault(cs => cs.IsDefault) ?? statuses.FirstOrDefault();

                    if (status != null)
                    {
                        var connectionRequestService = new ConnectionRequestService(rockContext);
                        var request = new ConnectionRequest
                        {
                            ConnectionOpportunityId = alertType.ConnectionOpportunityId.Value,
                            PersonAliasId           = alert.PersonAliasId,
                            ConnectionStatusId      = status.Id
                        };

                        if (alert.TransactionId.HasValue)
                        {
                            request.LoadAttributes();
                            request.SetAttributeValue("FinancialTransactionId", alert.TransactionId.Value.ToString());
                        }

                        connectionRequestService.Add(request);
                    }
                }

                // Send a bus event if configured
                if (alertType.SendBusEvent)
                {
                    new TransactionWasAlertedMessage
                    {
                        FinancialTransactionAlertId = alert.Id
                    }.Publish();
                }

                // Send a communication if configured
                if (alertType.SystemCommunicationId.HasValue)
                {
                    var systemCommunicationService = new SystemCommunicationService(rockContext);
                    var systemCommunication        = systemCommunicationService.Get(alertType.SystemCommunicationId.Value);

                    if (person != null && systemCommunication != null)
                    {
                        CommunicationHelper.SendMessage(person, ( int )person.CommunicationPreference, systemCommunication, mergeObjects);
                    }
                }

                // Send a communication to account followers if an Account Participant System Communication and Account is specified
                // for this alert type
                if (alertType.AccountParticipantSystemCommunicationId.HasValue && alertType.FinancialAccountId.HasValue)
                {
                    var systemCommunicationService            = new SystemCommunicationService(rockContext);
                    var financialAccountService               = new FinancialAccountService(rockContext);
                    var accountParticipantSystemCommunication = systemCommunicationService.Get(alertType.AccountParticipantSystemCommunicationId.Value);
                    if (accountParticipantSystemCommunication != null)
                    {
                        var accountFollowers = financialAccountService
                                               .GetAccountParticipants(alertType.FinancialAccountId.Value, RelatedEntityPurposeKey.FinancialAccountGivingAlert)
                                               .Select(a => a.Person);

                        foreach (var accountFollower in accountFollowers)
                        {
                            CommunicationHelper.SendMessage(accountFollower, ( int )accountFollower.CommunicationPreference, accountParticipantSystemCommunication, mergeObjects);
                        }
                    }
                }

                // Send a notification to a group if configured
                if (alertType.AlertSummaryNotificationGroupId.HasValue)
                {
                    var systemEmailGuid            = SystemGuid.SystemCommunication.FINANCIAL_TRANSACTION_ALERT_NOTIFICATION_SUMMARY.AsGuid();
                    var systemCommunicationService = new SystemCommunicationService(rockContext);
                    var systemCommunication        = systemCommunicationService.Get(systemEmailGuid);

                    CommunicationHelper.SendMessage(alertType.AlertSummaryNotificationGroupId.Value, systemCommunication, mergeObjects);
                }

                rockContext.SaveChanges();
            }
        }
示例#7
0
        /// <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();

            var emailService = new SystemCommunicationService(rockContext);

            SystemCommunication 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 <RockEmailMessageRecipient>();

            var personList = personQry.AsNoTracking().ToList();

            foreach (var person in personList)
            {
                var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null);
                mergeFields.Add("Person", person);

                recipients.Add(new RockEmailMessageRecipient(person, 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>
        /// 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 a comma.";

            SystemCommunicationService emailTemplateService = new SystemCommunicationService(new RockContext());
            SystemCommunication        emailTemplate        = emailTemplateService.Get(emailTemplateId);

            bool showMessagePreview = false;

            var pushCommunication = new CommunicationDetails();

            if (emailTemplate != null)
            {
                pdAuditDetails.Visible = true;
                pdAuditDetails.SetEntity(emailTemplate, ResolveRockUrl("~"));

                lActionTitle.Text       = ActionTitle.Edit(SystemCommunication.FriendlyTypeName).FormatAsHtmlTitle();
                hfEmailTemplateId.Value = emailTemplate.Id.ToString();

                cbIsActive.Checked = emailTemplate.IsActive.GetValueOrDefault();
                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;
                ceEmailTemplate.Text = emailTemplate.Body;

                pushCommunication = new CommunicationDetails
                {
                    PushData = emailTemplate.PushData,
                    PushImageBinaryFileId = emailTemplate.PushImageBinaryFileId,
                    PushMessage           = emailTemplate.PushMessage,
                    PushTitle             = emailTemplate.PushTitle,
                    PushOpenMessage       = emailTemplate.PushOpenMessage,
                    PushOpenAction        = emailTemplate.PushOpenAction
                };

                nbTemplateHelp.InnerHtml = CommunicationTemplateHelper.GetTemplateHelp(false);

                kvlMergeFields.Value = emailTemplate.LavaFields.Select(a => string.Format("{0}^{1}", a.Key, a.Value)).ToList().AsDelimited("|");

                hfShowAdditionalFields.Value = (!string.IsNullOrEmpty(emailTemplate.Cc) || !string.IsNullOrEmpty(emailTemplate.Bcc)).ToTrueFalse().ToLower();

                cbCssInliningEnabled.Checked = emailTemplate.CssInliningEnabled;

                showMessagePreview = true;
            }
            else
            {
                pdAuditDetails.Visible  = false;
                lActionTitle.Text       = ActionTitle.Add(SystemCommunication.FriendlyTypeName).FormatAsHtmlTitle();
                hfEmailTemplateId.Value = 0.ToString();

                cbIsActive.Checked = true;
                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;
                ceEmailTemplate.Text = string.Empty;
            }

            var pushNotificationControl = phPushNotification.Controls[0] as PushNotification;

            if (pushNotificationControl != null)
            {
                pushNotificationControl.SetFromCommunication(pushCommunication);
            }

            SetEmailMessagePreviewModeEnabled(showMessagePreview);

            LoadDropDowns();

            // SMS Fields
            mfpSMSMessage.MergeFields.Clear();
            mfpSMSMessage.MergeFields.Add("GlobalAttribute");
            mfpSMSMessage.MergeFields.Add("Rock.Model.Person");

            if (emailTemplate != null)
            {
                dvpSMSFrom.SetValue(emailTemplate.SMSFromDefinedValueId);
                tbSMSTextMessage.Text = emailTemplate.SMSMessage;
            }
        }
        /// <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();

            SystemCommunicationService emailTemplateService = new SystemCommunicationService(rockContext);
            SystemCommunication        emailTemplate;

            int emailTemplateId = int.Parse(hfEmailTemplateId.Value);

            if (emailTemplateId == 0)
            {
                emailTemplate = new SystemCommunication();
                emailTemplateService.Add(emailTemplate);
            }
            else
            {
                emailTemplate = emailTemplateService.Get(emailTemplateId);
            }

            emailTemplate.IsActive           = cbIsActive.Checked;
            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               = ceEmailTemplate.Text;
            emailTemplate.LavaFields         = kvlMergeFields.Value.AsDictionaryOrNull();
            emailTemplate.CssInliningEnabled = cbCssInliningEnabled.Checked;

            emailTemplate.SMSFromDefinedValueId = dvpSMSFrom.SelectedValue.AsIntegerOrNull();
            emailTemplate.SMSMessage            = tbSMSTextMessage.Text;

            var pushCommunication       = new CommunicationDetails();
            var pushNotificationControl = phPushNotification.Controls[0] as PushNotification;

            if (pushNotificationControl != null)
            {
                pushNotificationControl.UpdateCommunication(pushCommunication);
            }

            emailTemplate.PushData = pushCommunication.PushData;
            emailTemplate.PushImageBinaryFileId = pushCommunication.PushImageBinaryFileId;
            emailTemplate.PushMessage           = pushCommunication.PushMessage;
            emailTemplate.PushOpenAction        = pushCommunication.PushOpenAction;
            emailTemplate.PushOpenMessage       = pushCommunication.PushOpenMessage;
            emailTemplate.PushTitle             = pushCommunication.PushTitle;

            if (!emailTemplate.IsValid)
            {
                // If CodeEditor is hidden, we need to manually add the Required error message or it will not be shown.
                if (string.IsNullOrWhiteSpace(ceEmailTemplate.Text) && !ceEmailTemplate.Visible)
                {
                    var customValidator = new CustomValidator();

                    customValidator.ValidationGroup   = ceEmailTemplate.ValidationGroup;
                    customValidator.ControlToValidate = ceEmailTemplate.ID;
                    customValidator.ErrorMessage      = "Email Message Body is required.";
                    customValidator.IsValid           = false;

                    Page.Validators.Add(customValidator);
                }

                // Controls will render the error messages
                return;
            }

            rockContext.SaveChanges();

            NavigateToParentPage();
        }
        /// <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);
            }
        }
示例#11
0
        /// <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));

                RockContext rockContext = new RockContext();

                SystemCommunicationService systemCommunicationService = new SystemCommunicationService(rockContext);

                if (pnlRegistration.Visible && registrationTemplateIds.Count > 0)
                {
                    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);

                    // 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))
                        {
                            issuedRefund = issueRefund(payment.Transaction, "Registration", registration.FirstName + " " + registration.LastName);
                        }
                        j++;

                        // Send an email if applicable
                        if (issuedRefund && !string.IsNullOrWhiteSpace(registration.ConfirmationEmail) && ddlSystemCommunication.SelectedValueAsInt().HasValue&& ddlSystemCommunication.SelectedValueAsInt() > 0)
                        {
                            var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage);
                            mergeFields.Add("Registration", registration);

                            SystemCommunication systemCommunication = systemCommunicationService.Get(ddlSystemCommunication.SelectedValueAsInt().Value);

                            var emailMessage = new RockEmailMessage(systemCommunication);
                            emailMessage.AdditionalMergeFields = mergeFields;

                            emailMessage.AddRecipient(RockEmailMessageRecipient.CreateAnonymous(registration.ConfirmationEmail, mergeFields));
                            emailMessage.CreateCommunicationRecord = true;
                            emailMessage.Send();
                        }
                    }
                }

                if (pnlTransactionCodes.Visible && tbTransactionCodes.Text.Length > 0)
                {
                    var codes = tbTransactionCodes.Text.SplitDelimitedValues();
                    FinancialTransactionService financialTransactionService = new FinancialTransactionService(rockContext);
                    var transactions = financialTransactionService.Queryable().Where(ft => codes.Contains(ft.TransactionCode));
                    int j            = 0;
                    foreach (var transaction in transactions)
                    {
                        OnProgress("Processing transaction refund " + j + " of " + transactions.Count());
                        var issuedRefund = issueRefund(transaction, "Transaction", transaction.AuthorizedPersonAlias != null ? transaction.AuthorizedPersonAlias.Person.FullName : "Unknown");

                        // Send an email if applicable
                        if (issuedRefund && transaction.AuthorizedPersonAlias != null && !string.IsNullOrWhiteSpace(transaction.AuthorizedPersonAlias.Person.Email) && ddlSystemCommunication.SelectedValueAsInt().HasValue&& ddlSystemCommunication.SelectedValueAsInt() > 0)
                        {
                            var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage);
                            mergeFields.Add("Transaction", transaction);

                            SystemCommunication systemCommunication = systemCommunicationService.Get(ddlSystemCommunication.SelectedValueAsInt().Value);

                            var emailMessage = new RockEmailMessage(systemCommunication);
                            emailMessage.AdditionalMergeFields = mergeFields;
                            emailMessage.FromEmail             = ebEmail.Text;
                            emailMessage.AddRecipient(new RockEmailMessageRecipient(transaction.AuthorizedPersonAlias.Person, 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();
        }
示例#12
0
        /// <summary>
        /// Sends the expired credit card notices.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        /// <exception cref="Exception">Expiring credit card email is missing.</exception>
        private SendExpiredCreditCardNoticesResult SendExpiredCreditCardNotices(IJobExecutionContext context)
        {
            var dataMap     = context.JobDetail.JobDataMap;
            var rockContext = new RockContext();

            // Get the details for the email that we'll be sending out.
            Guid?systemEmailGuid = dataMap.GetString(AttributeKey.ExpiringCreditCardEmail).AsGuidOrNull();
            SystemCommunication systemCommunication = null;

            if (systemEmailGuid.HasValue)
            {
                var systemCommunicationService = new SystemCommunicationService(rockContext);
                systemCommunication = systemCommunicationService.Get(systemEmailGuid.Value);
            }

            if (systemCommunication == 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(AttributeKey.Workflow).AsGuidOrNull();
            WorkflowTypeCache workflowType    = null;
            WorkflowService   workflowService = new WorkflowService(rockContext);

            if (workflowGuid != null)
            {
                workflowType = WorkflowTypeCache.Get(workflowGuid.Value);
            }

            var financialScheduledTransactionQuery = new FinancialScheduledTransactionService(rockContext).Queryable()
                                                     .Where(t => t.IsActive && t.FinancialPaymentDetail.ExpirationMonthEncrypted != null && (t.EndDate == null || t.EndDate > DateTime.Now))
                                                     .AsNoTracking();

            List <ScheduledTransactionInfo> scheduledTransactionInfoList = financialScheduledTransactionQuery.Select(a => new ScheduledTransactionInfo
            {
                Id = a.Id,
                FinancialPaymentDetail    = a.FinancialPaymentDetail,
                AuthorizedPersonAliasGuid = a.AuthorizedPersonAlias.Guid,
                Person = a.AuthorizedPersonAlias.Person
            }).ToList();

            // Get the current month and year
            DateTime now          = DateTime.Now;
            int      currentMonth = now.Month;
            int      currentYYYY  = now.Year;

            // get the common merge fields once, so we don't have to keep calling it for every person, then create a new mergeFields for each person, starting with a copy of the common merge fields
            var commonMergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null);

            var result = new SendExpiredCreditCardNoticesResult
            {
                ExaminedCount = scheduledTransactionInfoList.Count()
            };

            foreach (ScheduledTransactionInfo scheduledTransactionInfo in scheduledTransactionInfoList.OrderByDescending(a => a.Id))
            {
                int?expirationMonth = scheduledTransactionInfo.FinancialPaymentDetail.ExpirationMonth;
                int?expirationYYYY  = scheduledTransactionInfo.FinancialPaymentDetail.ExpirationYear;
                if (!expirationMonth.HasValue || !expirationMonth.HasValue)
                {
                    continue;
                }

                int warningYear  = expirationYYYY.Value;
                int warningMonth = expirationMonth.Value - 1;
                if (warningMonth == 0)
                {
                    warningYear -= 1;
                    warningMonth = 12;
                }

                if ((warningYear == currentYYYY) && (warningMonth == currentMonth))
                {
                    string maskedCardNumber = string.Empty;

                    if (!string.IsNullOrEmpty(scheduledTransactionInfo.FinancialPaymentDetail.AccountNumberMasked) && scheduledTransactionInfo.FinancialPaymentDetail.AccountNumberMasked.Length >= 4)
                    {
                        maskedCardNumber = scheduledTransactionInfo.FinancialPaymentDetail.AccountNumberMasked.Substring(scheduledTransactionInfo.FinancialPaymentDetail.AccountNumberMasked.Length - 4);
                    }

                    string expirationDateMMYYFormatted = scheduledTransactionInfo.FinancialPaymentDetail?.ExpirationDate;

                    var recipients = new List <RockEmailMessageRecipient>();

                    var person = scheduledTransactionInfo.Person;

                    if (!person.IsEmailActive || person.Email.IsNullOrWhiteSpace() || person.EmailPreference == EmailPreference.DoNotEmail)
                    {
                        continue;
                    }

                    // make a mergeFields for this person, starting with copy of the commonFieldFields
                    var mergeFields = new Dictionary <string, object>(commonMergeFields);
                    mergeFields.Add("Person", person);
                    mergeFields.Add("Card", maskedCardNumber);
                    mergeFields.Add("Expiring", expirationDateMMYYFormatted);

                    recipients.Add(new RockEmailMessageRecipient(person, mergeFields));

                    var emailMessage = new RockEmailMessage(systemCommunication);
                    emailMessage.SetRecipients(recipients);
                    emailMessage.Send(out List <string> emailErrors);

                    if (emailErrors.Any())
                    {
                        var errorLines = new StringBuilder();
                        errorLines.AppendLine(string.Empty);
                        foreach (string error in emailErrors)
                        {
                            errorLines.AppendLine(error);
                        }

                        // Provide better identifying context in case the errors are too vague.
                        var exception = new Exception($"Unable to send email (Person ID = {person.Id}).{errorLines}");

                        result.EmailSendExceptions.Add(exception);
                    }
                    else
                    {
                        result.NoticesSentCount++;
                    }

                    // Start workflow for this person
                    if (workflowType != null)
                    {
                        Dictionary <string, string> attributes = new Dictionary <string, string>();
                        attributes.Add("Person", scheduledTransactionInfo.AuthorizedPersonAliasGuid.ToString());
                        attributes.Add("Card", maskedCardNumber);
                        attributes.Add("Expiring", expirationDateMMYYFormatted);
                        attributes.Add("FinancialScheduledTransactionId", scheduledTransactionInfo.Id.ToString());

                        StartWorkflow(workflowService, workflowType, attributes, $"{person.FullName} (scheduled transaction Id: {scheduledTransactionInfo.Id})");
                    }
                }
            }

            return(result);
        }