/// <summary>
        /// Displays the confirmation.
        /// </summary>
        /// <param name="personId">The person identifier.</param>
        private void DisplayConfirmation(int personId)
        {
            PersonService personService = new PersonService(new RockContext());
            Person        person        = personService.Get(personId);

            if (person != null)
            {
                Rock.Model.UserLogin user = CreateUser(person, false);

                string url = LinkedPageUrl("ConfirmationPage");
                if (string.IsNullOrWhiteSpace(url))
                {
                    url = ResolveRockUrl("~/ConfirmAccount");
                }

                var mergeObjects = GlobalAttributesCache.GetMergeFields(CurrentPerson);
                mergeObjects.Add("ConfirmAccountUrl", RootPath + url.TrimStart(new char[] { '/' }));
                mergeObjects.Add("Person", person);
                mergeObjects.Add("User", user);

                var recipients = new List <RecipientData>();
                recipients.Add(new RecipientData(person.Email, mergeObjects));

                Email.Send(GetAttributeValue("ConfirmAccountTemplate").AsGuid(), recipients, ResolveRockUrl("~/"), ResolveRockUrl("~~/"));

                ShowPanel(4);
            }
            else
            {
                ShowErrorMessage("Invalid Person");
            }
        }
Beispiel #2
0
        /// <summary>
        /// Sends the notification.
        /// </summary>
        /// <param name="message">The message to send.</param>
        private void SendNotification(string message)
        {
            try
            {
                // setup merge codes for email
                var mergeObjects = GlobalAttributesCache.GetMergeFields(null);

                mergeObjects.Add("ExceptionDetails", message);

                // get email addresses to send to
                var globalAttributesCache = GlobalAttributesCache.Read();

                string emailAddressesList = globalAttributesCache.GetValue("EmailExceptionsList");

                if (!string.IsNullOrWhiteSpace(emailAddressesList))
                {
                    string[] emailAddresses = emailAddressesList.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                    var recipients = new List <RecipientData>();
                    foreach (string emailAddress in emailAddresses)
                    {
                        recipients.Add(new RecipientData(emailAddress, mergeObjects));
                    }

                    if (recipients.Any())
                    {
                        bool sendNotification = true;

                        Email.Send(Rock.SystemGuid.SystemEmail.CONFIG_EXCEPTION_NOTIFICATION.AsGuid(), recipients);
                    }
                }
            }
            catch { }
        }
Beispiel #3
0
        /// <summary>
        /// Shows the lava help.
        /// </summary>
        private void ShowLavaHelp()
        {
            var           rockContext       = new RockContext();
            List <object> mergeObjectsList  = GetMergeObjectList(rockContext, 1);
            var           globalMergeFields = GlobalAttributesCache.GetMergeFields(this.CurrentPerson);

            globalMergeFields.Add("CurrentPerson", this.CurrentPerson);

            MergeTemplate     mergeTemplate     = new MergeTemplateService(rockContext).Get(mtPicker.SelectedValue.AsInteger());
            MergeTemplateType mergeTemplateType = null;

            if (mergeTemplate != null)
            {
                mergeTemplateType = this.GetMergeTemplateType(rockContext, mergeTemplate);
            }

            if (mergeTemplateType != null)
            {
                // have the mergeTemplateType generate the help text
                lShowMergeFields.Text = mergeTemplateType.GetLavaDebugInfo(mergeObjectsList, globalMergeFields);
            }
            else
            {
                lShowMergeFields.Text = MergeTemplateType.GetDefaultLavaDebugInfo(mergeObjectsList, globalMergeFields);
            }
        }
Beispiel #4
0
        private void ShowForm()
        {
            var mergeObjects = GlobalAttributesCache.GetMergeFields(CurrentPerson);

            mergeObjects.Add("CurrentPerson", CurrentPerson);

            lEmailForm.Text = GetAttributeValue("HTMLForm").ResolveMergeFields(mergeObjects);
        }
        /// <summary>
        /// Displays the success.
        /// </summary>
        /// <param name="user">The user.</param>
        private void DisplaySuccess(Rock.Model.UserLogin user)
        {
            FormsAuthentication.SignOut();
            Rock.Security.Authorization.SetAuthCookie(tbUserName.Text, false, false);

            if (user != null && user.PersonId.HasValue)
            {
                PersonService personService = new PersonService(new RockContext());
                Person        person        = personService.Get(user.PersonId.Value);

                if (person != null)
                {
                    try
                    {
                        string url = LinkedPageUrl("ConfirmationPage");
                        if (string.IsNullOrWhiteSpace(url))
                        {
                            url = ResolveRockUrl("~/ConfirmAccount");
                        }

                        var mergeObjects = GlobalAttributesCache.GetMergeFields(CurrentPerson);
                        mergeObjects.Add("ConfirmAccountUrl", RootPath + url.TrimStart(new char[] { '/' }));
                        mergeObjects.Add("Person", person);
                        mergeObjects.Add("User", user);

                        var recipients = new List <RecipientData>();
                        recipients.Add(new RecipientData(person.Email, mergeObjects));

                        Email.Send(GetAttributeValue("AccountCreatedTemplate").AsGuid(), recipients, ResolveRockUrl("~/"), ResolveRockUrl("~~/"));
                    }
                    catch (SystemException ex)
                    {
                        ExceptionLogService.LogException(ex, Context, RockPage.PageId, RockPage.Site.Id, CurrentPersonAlias);
                    }

                    string returnUrl = Request.QueryString["returnurl"];
                    btnContinue.Visible = !string.IsNullOrWhiteSpace(returnUrl);

                    lSuccessCaption.Text = GetAttributeValue("SuccessCaption");
                    if (lSuccessCaption.Text.Contains("{0}"))
                    {
                        lSuccessCaption.Text = string.Format(lSuccessCaption.Text, person.FirstName);
                    }

                    ShowPanel(5);
                }
                else
                {
                    ShowErrorMessage("Invalid Person");
                }
            }
            else
            {
                ShowErrorMessage("Invalid User");
            }
        }
Beispiel #6
0
        /// <summary>
        /// Handles the Click event of the btnSend 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 btnSend_Click(object sender, EventArgs e)
        {
            var url = LinkedPageUrl("ConfirmationPage");

            if (string.IsNullOrWhiteSpace(url))
            {
                url = ResolveRockUrl("~/ConfirmAccount");
            }

            var mergeObjects = GlobalAttributesCache.GetMergeFields(CurrentPerson);

            mergeObjects.Add("ConfirmAccountUrl", RootPath + url.TrimStart(new char[] { '/' }));
            var results = new List <IDictionary <string, object> >();

            var rockContext      = new RockContext();
            var personService    = new PersonService(rockContext);
            var userLoginService = new UserLoginService(rockContext);

            foreach (Person person in personService.GetByEmail(tbEmail.Text)
                     .Where(p => p.Users.Any()))
            {
                var users = new List <UserLogin>();
                foreach (UserLogin user in userLoginService.GetByPersonId(person.Id))
                {
                    if (user.EntityType != null)
                    {
                        var component = AuthenticationContainer.GetComponent(user.EntityType.Name);
                        if (!component.RequiresRemoteAuthentication)
                        {
                            users.Add(user);
                        }
                    }
                }

                var resultsDictionary = new Dictionary <string, object>();
                resultsDictionary.Add("Person", person);
                resultsDictionary.Add("Users", users);
                results.Add(resultsDictionary);
            }

            if (results.Count > 0)
            {
                mergeObjects.Add("Results", results.ToArray());
                var recipients = new List <RecipientData>();
                recipients.Add(new RecipientData(tbEmail.Text, mergeObjects));

                Email.Send(GetAttributeValue("EmailTemplate").AsGuid(), recipients, ResolveRockUrlIncludeRoot("~/"), ResolveRockUrlIncludeRoot("~~/"));

                pnlEntry.Visible   = false;
                pnlSuccess.Visible = true;
            }
            else
            {
                pnlWarning.Visible = true;
            }
        }
        /// <summary>
        /// Displays the sent login.
        /// </summary>
        /// <param name="direction">The direction.</param>
        private void DisplaySentLogin(Direction direction)
        {
            var           rockContext   = new RockContext();
            PersonService personService = new PersonService(rockContext);
            Person        person        = personService.Get(hfSendPersonId.Value.AsInteger());

            if (person != null)
            {
                string url = LinkedPageUrl("ConfirmationPage");
                if (string.IsNullOrWhiteSpace(url))
                {
                    url = ResolveRockUrl("~/ConfirmAccount");
                }

                var mergeObjects = GlobalAttributesCache.GetMergeFields(CurrentPerson);
                mergeObjects.Add("ConfirmAccountUrl", RootPath + url.TrimStart(new char[] { '/' }));
                var results = new List <IDictionary <string, object> >();

                var users            = new List <UserLogin>();
                var userLoginService = new UserLoginService(rockContext);
                foreach (UserLogin user in userLoginService.GetByPersonId(person.Id))
                {
                    if (user.EntityType != null)
                    {
                        var component = AuthenticationContainer.GetComponent(user.EntityType.Name);
                        if (component.ServiceType == AuthenticationServiceType.Internal)
                        {
                            users.Add(user);
                        }
                    }
                }

                var resultsDictionary = new Dictionary <string, object>();
                resultsDictionary.Add("Person", person);
                resultsDictionary.Add("Users", users);
                results.Add(resultsDictionary);

                mergeObjects.Add("Results", results.ToArray());

                var recipients = new List <RecipientData>();
                recipients.Add(new RecipientData(person.Email, mergeObjects));

                Email.Send(GetAttributeValue("ForgotUsernameTemplate").AsGuid(), recipients, ResolveRockUrl("~/"), ResolveRockUrl("~~/"));
            }
            else
            {
                ShowErrorMessage("Invalid Person");
            }

            ShowPanel(3);
        }
        /// <summary>
        /// Raises the <see cref="E:System.Web.UI.Control.Init" /> event.
        /// </summary>
        /// <param name="e">An <see cref="T:System.EventArgs" /> object that contains the event data.</param>
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            var mergeObjects = GlobalAttributesCache.GetMergeFields(CurrentPerson);

            LoadDropdowns(mergeObjects);

            var key = PageParameter("Person");

            if (!string.IsNullOrWhiteSpace(key))
            {
                var service = new PersonService(new RockContext());
                _person = service.GetByUrlEncodedKey(key);
            }

            if (_person == null && CurrentPerson != null)
            {
                _person = CurrentPerson;
            }

            if (_person != null)
            {
                nbMessage.NotificationBoxType = NotificationBoxType.Success;
                nbMessage.Text = GetAttributeValue("SuccessText").ResolveMergeFields(mergeObjects);
            }
            else
            {
                nbMessage.NotificationBoxType = NotificationBoxType.Danger;
                nbMessage.Text    = "Unfortunately, we're unable to update your email preference, as we're not sure who you are.";
                nbMessage.Visible = true;
                btnSubmit.Visible = false;
            }

            string script = string.Format(@"
    $(""input[id^='{0}'"").click(function () {{
        if ($(this).val() == '3') {{
            $('#{1}').slideDown('fast');
        }} else {{
            $('#{1}').slideUp('fast');
        }}
    }});    
", rblEmailPreference.ClientID, divNotInvolved.ClientID);

            ScriptManager.RegisterStartupScript(rblEmailPreference, rblEmailPreference.GetType(), "toggle-preference" + this.BlockId.ToString(), script, true);
        }
Beispiel #9
0
        /// <summary>
        /// Sends the specified recipient merge values.
        /// </summary>
        /// <param name="recipients">The recipients.</param>
        public void Send(Dictionary <string, Dictionary <string, object> > recipients)
        {
            var configValues = GlobalAttributesCache.GetMergeFields(null);

            List <string> cc  = SplitRecipient(Cc);
            List <string> bcc = SplitRecipient(Bcc);

            foreach (KeyValuePair <string, Dictionary <string, object> > recipient in recipients)
            {
                List <string> to = SplitRecipient(To);
                to.Add(recipient.Key);

                var mergeObjects = recipient.Value;

                // Combine the global merge values with the recipient specific merge values
                configValues.ToList().ForEach(g => mergeObjects.Add(g.Key, g.Value));

                // Resolve any merge codes in the subject and body
                string subject = Subject.ResolveMergeFields(mergeObjects);
                string body    = Body.ResolveMergeFields(mergeObjects);

                Email.Send(From, to, cc, bcc, subject, body);
            }
        }
Beispiel #10
0
        /// <summary>
        /// Sends the confirmation.
        /// </summary>
        /// <param name="userLogin">The user login.</param>
        private void SendConfirmation(UserLogin userLogin)
        {
            string url = LinkedPageUrl("ConfirmationPage");

            if (string.IsNullOrWhiteSpace(url))
            {
                url = ResolveRockUrl("~/ConfirmAccount");
            }

            var mergeObjects = GlobalAttributesCache.GetMergeFields(CurrentPerson);

            mergeObjects.Add("ConfirmAccountUrl", RootPath + url.TrimStart(new char[] { '/' }));

            var personDictionary = userLogin.Person.ToLiquid() as Dictionary <string, object>;

            mergeObjects.Add("Person", personDictionary);
            mergeObjects.Add("User", userLogin);

            var recipients = new List <RecipientData>();

            recipients.Add(new RecipientData(userLogin.Person.Email, mergeObjects));

            Email.Send(GetAttributeValue("ConfirmAccountTemplate").AsGuid(), recipients, ResolveRockUrl("~/"), ResolveRockUrl("~~/"), false);
        }
        /// <summary>
        /// Sends the notification.
        /// </summary>
        /// <param name="ex">The ex.</param>
        private void SendNotification(Exception ex)
        {
            int?        pageId      = (Context.Items["Rock:PageId"] ?? "").ToString().AsIntegerOrNull();;
            int?        siteId      = (Context.Items["Rock:SiteId"] ?? "").ToString().AsIntegerOrNull();;
            PersonAlias personAlias = null;
            Person      person      = null;

            try
            {
                var user = UserLoginService.GetCurrentUser();
                if (user != null && user.Person != null)
                {
                    person      = user.Person;
                    personAlias = user.Person.PrimaryAlias;
                }
            }
            catch { }

            try
            {
                ExceptionLogService.LogException(ex, Context, pageId, siteId, personAlias);
            }
            catch { }

            try
            {
                string siteName = "Rock";
                if (siteId.HasValue)
                {
                    var site = SiteCache.Read(siteId.Value);
                    if (site != null)
                    {
                        siteName = site.Name;
                    }
                }

                // setup merge codes for email
                var mergeObjects = GlobalAttributesCache.GetMergeFields(null);
                mergeObjects.Add("ExceptionDetails", string.Format("An error occurred{0} on the {1} site on page: <br>{2}<p>{3}</p>",
                                                                   person != null ? " for " + person.FullName : "", siteName, Context.Request.Url.OriginalString, FormatException(ex, "")));
                mergeObjects.Add("Person", person);

                // get email addresses to send to
                var    globalAttributesCache = GlobalAttributesCache.Read();
                string emailAddressesList    = globalAttributesCache.GetValue("EmailExceptionsList");

                if (!string.IsNullOrWhiteSpace(emailAddressesList))
                {
                    string[] emailAddresses = emailAddressesList.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                    var recipients = new List <RecipientData>();
                    foreach (string emailAddress in emailAddresses)
                    {
                        recipients.Add(new RecipientData(emailAddress, mergeObjects));
                    }

                    if (recipients.Any())
                    {
                        bool sendNotification = true;

                        string filterSettings = globalAttributesCache.GetValue("EmailExceptionsFilter");
                        var    serverVarList  = Context.Request.ServerVariables;

                        if (!string.IsNullOrWhiteSpace(filterSettings) && serverVarList.Count > 0)
                        {
                            string[] nameValues = filterSettings.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
                            foreach (string nameValue in nameValues)
                            {
                                string[] nameAndValue = nameValue.Split(new char[] { '^' }, StringSplitOptions.RemoveEmptyEntries);
                                {
                                    if (nameAndValue.Length == 2)
                                    {
                                        var serverValue = serverVarList[nameAndValue[0]];
                                        if (serverValue != null && serverValue.ToUpper().Contains(nameAndValue[1].ToUpper().Trim()))
                                        {
                                            sendNotification = false;
                                            break;
                                        }
                                    }
                                }
                            }
                        }

                        if (sendNotification)
                        {
                            Email.Send(Rock.SystemGuid.SystemEmail.CONFIG_EXCEPTION_NOTIFICATION.AsGuid(), recipients, string.Empty, string.Empty, false);
                        }
                    }
                }
            }
            catch { }
        }
Beispiel #12
0
        /// <summary>
        /// Handles the Click event of the btnMerge 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 btnMerge_Click(object sender, EventArgs e)
        {
            // NOTE: This is a full postback (not a partial like most other blocks)

            var rockContext = new RockContext();

            List <object> mergeObjectsList = GetMergeObjectList(rockContext);

            MergeTemplate mergeTemplate = new MergeTemplateService(rockContext).Get(mtPicker.SelectedValue.AsInteger());

            if (mergeTemplate == null)
            {
                nbWarningMessage.Text = "Unable to get merge template";
                nbWarningMessage.NotificationBoxType = NotificationBoxType.Danger;
                nbWarningMessage.Visible             = true;
                return;
            }

            MergeTemplateType mergeTemplateType = this.GetMergeTemplateType(rockContext, mergeTemplate);

            if (mergeTemplateType == null)
            {
                nbWarningMessage.Text = "Unable to get merge template type";
                nbWarningMessage.NotificationBoxType = NotificationBoxType.Danger;
                nbWarningMessage.Visible             = true;
                return;
            }

            var globalMergeFields = GlobalAttributesCache.GetMergeFields(this.CurrentPerson);

            globalMergeFields.Add("CurrentPerson", this.CurrentPerson);
            BinaryFile outputBinaryFileDoc = null;

            try
            {
                outputBinaryFileDoc = mergeTemplateType.CreateDocument(mergeTemplate, mergeObjectsList, globalMergeFields);

                if (mergeTemplateType.Exceptions != null && mergeTemplateType.Exceptions.Any())
                {
                    if (mergeTemplateType.Exceptions.Count == 1)
                    {
                        this.LogException(mergeTemplateType.Exceptions[0]);
                    }
                    else if (mergeTemplateType.Exceptions.Count > 50)
                    {
                        this.LogException(new AggregateException(string.Format("Exceptions merging template {0}. See InnerExceptions for top 50.", mergeTemplate.Name), mergeTemplateType.Exceptions.Take(50).ToList()));
                    }
                    else
                    {
                        this.LogException(new AggregateException(string.Format("Exceptions merging template {0}. See InnerExceptions", mergeTemplate.Name), mergeTemplateType.Exceptions.ToList()));
                    }
                }

                var uri = new UriBuilder(outputBinaryFileDoc.Url);
                var qry = System.Web.HttpUtility.ParseQueryString(uri.Query);
                qry["attachment"] = true.ToTrueFalse();
                uri.Query         = qry.ToString();
                Response.Redirect(uri.ToString(), false);
                Context.ApplicationInstance.CompleteRequest();
            }
            catch (Exception ex)
            {
                this.LogException(ex);
                if (ex is System.FormatException)
                {
                    nbMergeError.Text = "Error loading the merge template. Please verify that the merge template file is valid.";
                }
                else
                {
                    nbMergeError.Text = "An error occurred while merging";
                }

                nbMergeError.Details = ex.Message;
                nbMergeError.Visible = true;
            }
        }
        /// <summary>
        /// Binds the grid.
        /// </summary>
        private void BindGrid()
        {
            var contributionType = DefinedValueCache.Read(Rock.SystemGuid.DefinedValue.TRANSACTION_TYPE_CONTRIBUTION.AsGuid());

            if (contributionType != null)
            {
                var rockContext = new RockContext();
                var transactionDetailService = new FinancialTransactionDetailService(rockContext);
                var qry = transactionDetailService.Queryable().AsNoTracking()
                          .Where(a =>
                                 a.Transaction.TransactionTypeValueId == contributionType.Id &&
                                 a.Transaction.TransactionDateTime.HasValue);

                var targetPerson = this.ContextEntity <Person>();
                if (targetPerson != null)
                {
                    qry = qry.Where(t => t.Transaction.AuthorizedPersonAlias.Person.GivingId == targetPerson.GivingId);
                }

                List <SummaryRecord> summaryList;

                using (new Rock.Data.QueryHintScope(rockContext, QueryHintType.RECOMPILE))
                {
                    summaryList = qry
                                  .GroupBy(a => new { a.Transaction.TransactionDateTime.Value.Year, a.AccountId })
                                  .Select(t => new SummaryRecord
                    {
                        Year        = t.Key.Year,
                        AccountId   = t.Key.AccountId,
                        TotalAmount = t.Sum(d => d.Amount)
                    }).OrderByDescending(a => a.Year)
                                  .ToList();
                }

                var mergeObjects      = GlobalAttributesCache.GetMergeFields(this.CurrentPerson);
                var financialAccounts = new FinancialAccountService(rockContext).Queryable().Select(a => new { a.Id, a.Name }).ToDictionary(k => k.Id, v => v.Name);

                var yearsMergeObjects = new List <Dictionary <string, object> >();
                foreach (var item in summaryList.GroupBy(a => a.Year))
                {
                    var year         = item.Key;
                    var accountsList = new List <object>();
                    foreach (var a in item)
                    {
                        var accountDictionary = new Dictionary <string, object>();
                        accountDictionary.Add("Account", financialAccounts.ContainsKey(a.AccountId) ? financialAccounts[a.AccountId] : string.Empty);
                        accountDictionary.Add("TotalAmount", a.TotalAmount);
                        accountsList.Add(accountDictionary);
                    }

                    var yearDictionary = new Dictionary <string, object>();
                    yearDictionary.Add("Year", year);
                    yearDictionary.Add("SummaryRows", accountsList);

                    yearsMergeObjects.Add(yearDictionary);
                }

                mergeObjects.Add("Rows", yearsMergeObjects);

                lLavaOutput.Text = string.Empty;
                if (GetAttributeValue("EnableDebug").AsBooleanOrNull().GetValueOrDefault(false))
                {
                    lLavaOutput.Text = mergeObjects.lavaDebugInfo(rockContext);
                }

                string template = GetAttributeValue("LavaTemplate");

                lLavaOutput.Text += template.ResolveMergeFields(mergeObjects).ResolveClientIds(upnlContent.ClientID);
            }
        }
Beispiel #14
0
        /// <summary>
        /// Executes the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        public virtual void Execute(IJobExecutionContext context)
        {
            JobDataMap dataMap   = context.JobDetail.JobDataMap;
            var        groupType = GroupTypeCache.Read(dataMap.GetString("GroupType").AsGuid());

            if (groupType.TakesAttendance && groupType.SendAttendanceReminder)
            {
                // Get the occurrence dates that apply
                var dates = new List <DateTime>();
                dates.Add(RockDateTime.Today);
                try
                {
                    string[] reminderDays = dataMap.GetString("SendReminders").Split(',');
                    foreach (string reminderDay in reminderDays)
                    {
                        if (reminderDay.Trim() != string.Empty)
                        {
                            var reminderDate = RockDateTime.Today.AddDays(0 - Convert.ToInt32(reminderDay));
                            if (!dates.Contains(reminderDate))
                            {
                                dates.Add(reminderDate);
                            }
                        }
                    }
                }
                catch { }

                var rockContext        = new RockContext();
                var groupService       = new GroupService(rockContext);
                var groupMemberService = new GroupMemberService(rockContext);
                var scheduleService    = new ScheduleService(rockContext);
                var attendanceService  = new AttendanceService(rockContext);

                var startDate = dates.Min();
                var endDate   = dates.Max().AddDays(1);

                // Find all 'occurrences' for the groups that occur on the affected dates
                var occurrences = new Dictionary <int, List <DateTime> >();
                foreach (var group in groupService
                         .Queryable("Schedule").AsNoTracking()
                         .Where(g =>
                                g.GroupTypeId == groupType.Id &&
                                g.IsActive &&
                                g.Schedule != null &&
                                g.Members.Any(m =>
                                              m.GroupMemberStatus == GroupMemberStatus.Active &&
                                              m.GroupRole.IsLeader &&
                                              m.Person.Email != null &&
                                              m.Person.Email != "")))
                {
                    // Add the group
                    occurrences.Add(group.Id, new List <DateTime>());

                    // Check for a iCal schedule
                    DDay.iCal.Event calEvent = group.Schedule.GetCalenderEvent();
                    if (calEvent != null)
                    {
                        // If schedule has an iCal schedule, get occurrences between first and last dates
                        foreach (var occurrence in calEvent.GetOccurrences(startDate, endDate))
                        {
                            var startTime = occurrence.Period.StartTime.Value;
                            if (dates.Contains(startTime.Date))
                            {
                                occurrences[group.Id].Add(startTime);
                            }
                        }
                    }
                    else
                    {
                        // if schedule does not have an iCal, then check for weekly schedule and calculate occurrences starting with first attendance or current week
                        if (group.Schedule.WeeklyDayOfWeek.HasValue)
                        {
                            foreach (var date in dates)
                            {
                                if (date.DayOfWeek == group.Schedule.WeeklyDayOfWeek.Value)
                                {
                                    var startTime = date;
                                    if (group.Schedule.WeeklyTimeOfDay.HasValue)
                                    {
                                        startTime = startTime.Add(group.Schedule.WeeklyTimeOfDay.Value);
                                    }
                                    occurrences[group.Id].Add(startTime);
                                }
                            }
                        }
                    }
                }

                // Remove any occurrences during group type exclusion date ranges
                foreach (var exclusion in groupType.GroupScheduleExclusions)
                {
                    if (exclusion.Start.HasValue && exclusion.End.HasValue)
                    {
                        foreach (var keyVal in occurrences)
                        {
                            foreach (var occurrenceDate in keyVal.Value.ToList())
                            {
                                if (occurrenceDate >= exclusion.Start.Value &&
                                    occurrenceDate < exclusion.End.Value.AddDays(1))
                                {
                                    keyVal.Value.Remove(occurrenceDate);
                                }
                            }
                        }
                    }
                }

                // Remove any 'occurrenes' that already have attendance data entered
                foreach (var occurrence in attendanceService
                         .Queryable().AsNoTracking()
                         .Where(a =>
                                a.Group != null &&
                                a.ScheduleId.HasValue &&
                                a.Group.GroupTypeId == groupType.Id &&
                                a.Group.IsActive &&
                                a.StartDateTime > startDate &&
                                a.StartDateTime < endDate)
                         .Select(a => new
                {
                    GroupId = a.GroupId.Value,
                    a.StartDateTime
                })
                         .Distinct()
                         .ToList())
                {
                    if (occurrences.ContainsKey(occurrence.GroupId))
                    {
                        occurrences[occurrence.GroupId].RemoveAll(d => d == occurrence.StartDateTime);
                    }
                }

                // Get the groups that have occurrences
                var groupIds = occurrences.Where(o => o.Value.Any()).Select(o => o.Key).ToList();

                // Get the leaders of those groups
                var leaders = groupMemberService
                              .Queryable("Group,Person").AsNoTracking()
                              .Where(m =>
                                     groupIds.Contains(m.GroupId) &&
                                     m.GroupMemberStatus == GroupMemberStatus.Active &&
                                     m.GroupRole.IsLeader &&
                                     m.Person.Email != null &&
                                     m.Person.Email != "")
                              .ToList();

                // Loop through the leaders
                foreach (var leader in leaders)
                {
                    foreach (var group in occurrences.Where(o => o.Key == leader.GroupId))
                    {
                        var mergeObjects = GlobalAttributesCache.GetMergeFields(leader.Person);
                        mergeObjects.Add("Person", leader.Person);
                        mergeObjects.Add("Group", leader.Group);
                        mergeObjects.Add("Occurrence", group.Value.Max());

                        var recipients = new List <RecipientData>();
                        recipients.Add(new RecipientData(leader.Person.Email, mergeObjects));

                        Email.Send(dataMap.GetString("SystemEmail").AsGuid(), recipients);
                    }
                }
            }
        }
Beispiel #15
0
        /// <summary>
        /// Sends the specified communication.
        /// </summary>
        /// <param name="communication">The communication.</param>
        /// <exception cref="System.NotImplementedException"></exception>
        public override void Send(Rock.Model.Communication communication)
        {
            var rockContext = new RockContext();

            // Requery the Communication
            communication = new CommunicationService(rockContext).Get(communication.Id);

            if (communication != null &&
                communication.Status == Model.CommunicationStatus.Approved &&
                communication.HasPendingRecipients(rockContext) &&
                (!communication.FutureSendDateTime.HasValue || communication.FutureSendDateTime.Value.CompareTo(RockDateTime.Now) <= 0))
            {
                string fromPhone   = string.Empty;
                string fromValue   = communication.GetMediumDataValue("FromValue");
                int    fromValueId = int.MinValue;
                if (int.TryParse(fromValue, out fromValueId))
                {
                    fromPhone = DefinedValueCache.Read(fromValueId, rockContext).Value;
                }

                if (!string.IsNullOrWhiteSpace(fromPhone))
                {
                    string accountSid = GetAttributeValue("SID");
                    string authToken  = GetAttributeValue("Token");
                    var    twilio     = new TwilioRestClient(accountSid, authToken);

                    var historyService   = new HistoryService(rockContext);
                    var recipientService = new CommunicationRecipientService(rockContext);

                    var personEntityTypeId        = EntityTypeCache.Read("Rock.Model.Person").Id;
                    var communicationEntityTypeId = EntityTypeCache.Read("Rock.Model.Communication").Id;
                    var communicationCategoryId   = CategoryCache.Read(Rock.SystemGuid.Category.HISTORY_PERSON_COMMUNICATIONS.AsGuid(), rockContext).Id;

                    var globalConfigValues = GlobalAttributesCache.GetMergeFields(null);

                    bool recipientFound = true;
                    while (recipientFound)
                    {
                        var recipient = Rock.Model.Communication.GetNextPending(communication.Id, rockContext);
                        if (recipient != null)
                        {
                            try
                            {
                                var phoneNumber = recipient.PersonAlias.Person.PhoneNumbers
                                                  .Where(p => p.IsMessagingEnabled)
                                                  .FirstOrDefault();

                                if (phoneNumber != null)
                                {
                                    // Create merge field dictionary
                                    var    mergeObjects = recipient.CommunicationMergeValues(globalConfigValues);
                                    string message      = communication.GetMediumDataValue("Message");

                                    // convert any special microsoft word characters to normal chars so they don't look funny (for example "Hey “double-quotes” from ‘single quote’")
                                    message = message.ReplaceWordChars();
                                    message = message.ResolveMergeFields(mergeObjects);

                                    string twilioNumber = phoneNumber.Number;
                                    if (!string.IsNullOrWhiteSpace(phoneNumber.CountryCode))
                                    {
                                        twilioNumber = "+" + phoneNumber.CountryCode + phoneNumber.Number;
                                    }

                                    var    globalAttributes = Rock.Web.Cache.GlobalAttributesCache.Read();
                                    string callbackUrl      = globalAttributes.GetValue("PublicApplicationRoot") + "Webhooks/Twilio.ashx";

                                    var response = twilio.SendMessage(fromPhone, twilioNumber, message, callbackUrl);

                                    recipient.Status = CommunicationRecipientStatus.Delivered;
                                    recipient.TransportEntityTypeName = this.GetType().FullName;
                                    recipient.UniqueMessageId         = response.Sid;

                                    try
                                    {
                                        historyService.Add(new History
                                        {
                                            CreatedByPersonAliasId = communication.SenderPersonAliasId,
                                            EntityTypeId           = personEntityTypeId,
                                            CategoryId             = communicationCategoryId,
                                            EntityId            = recipient.PersonAlias.PersonId,
                                            Summary             = "Sent SMS message.",
                                            Caption             = message.Truncate(200),
                                            RelatedEntityTypeId = communicationEntityTypeId,
                                            RelatedEntityId     = communication.Id
                                        });
                                    }
                                    catch (Exception ex)
                                    {
                                        ExceptionLogService.LogException(ex, null);
                                    }
                                }
                                else
                                {
                                    recipient.Status     = CommunicationRecipientStatus.Failed;
                                    recipient.StatusNote = "No Phone Number with Messaging Enabled";
                                }
                            }
                            catch (Exception ex)
                            {
                                recipient.Status     = CommunicationRecipientStatus.Failed;
                                recipient.StatusNote = "Twilio Exception: " + ex.Message;
                            }

                            rockContext.SaveChanges();
                        }
                        else
                        {
                            recipientFound = false;
                        }
                    }
                }
            }
        }
Beispiel #16
0
        private void SendEmail()
        {
            // ensure this is not from a bot
            string[] bots          = GlobalAttributesCache.Value("EmailExceptionsFilter").Split('|');
            string   test          = GlobalAttributesCache.Value("EmailExceptionsFilter");
            var      serverVarList = Context.Request.ServerVariables;
            bool     isBot         = false;

            foreach (var bot in bots)
            {
                string[] botParms = bot.Split('^');
                if (botParms.Length == 2)
                {
                    var serverValue = serverVarList[botParms[0]];
                    if (serverValue != null && serverValue.ToUpper().Contains(botParms[1].ToUpper().Trim()))
                    {
                        isBot = true;
                    }
                }
            }

            if (!isBot)
            {
                // create merge objects
                var mergeFields = GlobalAttributesCache.GetMergeFields(CurrentPerson);
                mergeFields.Add("CurrentPerson", CurrentPerson);

                // create merge object for fields
                Regex rgxRockControls = new Regex(@"^ctl\d*\$.*");

                var formFields = new Dictionary <string, object>();
                for (int i = 0; i < Request.Form.Count; i++)
                {
                    string formFieldKey = Request.Form.GetKey(i);
                    if (formFieldKey != null &&
                        formFieldKey.Substring(0, 1) != "_" &&
                        formFieldKey != "searchField_hSearchFilter" &&
                        formFieldKey != "send" &&
                        !rgxRockControls.IsMatch(formFieldKey))
                    {
                        formFields.Add(formFieldKey, Request.Form[formFieldKey]);
                    }
                }

                mergeFields.Add("FormFields", formFields);

                // get attachments
                List <Attachment> attachments = new List <Attachment>();

                for (int i = 0; i < Request.Files.Count; i++)
                {
                    HttpPostedFile attachmentFile = Request.Files[i];

                    string fileName = System.IO.Path.GetFileName(attachmentFile.FileName);

                    Attachment attachment = new Attachment(attachmentFile.InputStream, fileName);

                    attachments.Add(attachment);
                }

                mergeFields.Add("AttachmentCount", attachments.Count);

                // send email
                List <string> recipients = GetAttributeValue("RecipientEmail").Split(',').ToList();
                string        message    = GetAttributeValue("MessageBody").ResolveMergeFields(mergeFields);
                string        fromEmail  = GetAttributeValue("FromEmail");
                string        fromName   = GetAttributeValue("FromName");
                string        subject    = GetAttributeValue("Subject");

                Email.Send(fromEmail, fromName, subject, recipients, message, ResolveRockUrl("~/"), ResolveRockUrl("~~/"), attachments, GetAttributeValue("SaveCommunicationHistory").AsBoolean());

                // set response
                if (!string.IsNullOrWhiteSpace(GetAttributeValue("ResponsePage")))
                {
                    NavigateToLinkedPage("ResponsePage");
                }

                // display response message
                lResponse.Visible  = true;
                lEmailForm.Visible = false;
                lResponse.Text     = GetAttributeValue("ResponseMessage").ResolveMergeFields(mergeFields);

                // show debug info
                if (GetAttributeValue("EnableDebug").AsBoolean() && IsUserAuthorized(Authorization.EDIT))
                {
                    lDebug.Visible = true;
                    lDebug.Text    = mergeFields.lavaDebugInfo();
                }
            }
            else
            {
                lResponse.Visible  = true;
                lEmailForm.Visible = false;
                lResponse.Text     = "You appear to be a computer. Check the global attribute 'Email Exceptions Filter' if you are getting this in error.";
            }
        }
Beispiel #17
0
        /// <summary>
        /// Handles the Click event of the lbPrintAttendanceRoster 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 lbPrintAttendanceRoster_Click(object sender, EventArgs e)
        {
            // NOTE: lbPrintAttendanceRoster is a full postback since we are returning a download of the roster

            nbPrintRosterWarning.Visible = false;
            var rockContext = new RockContext();

            Dictionary <int, object> mergeObjectsDictionary = new Dictionary <int, object>();

            if (_attendees != null)
            {
                var personIdList = _attendees.Select(a => a.PersonId).ToList();
                var personList   = new PersonService(rockContext).GetByIds(personIdList);
                foreach (var person in personList.OrderBy(a => a.LastName).ThenBy(a => a.NickName))
                {
                    mergeObjectsDictionary.AddOrIgnore(person.Id, person);
                }
            }

            var globalMergeFields = GlobalAttributesCache.GetMergeFields(this.CurrentPerson);

            globalMergeFields.Add("CurrentPerson", this.CurrentPerson);
            globalMergeFields.Add("Group", this._group);

            var mergeTemplate = new MergeTemplateService(rockContext).Get(this.GetAttributeValue("AttendanceRosterTemplate").AsGuid());

            if (mergeTemplate == null)
            {
                this.LogException(new Exception("No Merge Template specified in block settings"));
                nbPrintRosterWarning.Visible = true;
                nbPrintRosterWarning.Text    = "Unable to print Attendance Roster";
                return;
            }

            MergeTemplateType mergeTemplateType = mergeTemplate.GetMergeTemplateType();

            if (mergeTemplateType == null)
            {
                this.LogException(new Exception("Unable to determine Merge Template Type"));
                nbPrintRosterWarning.Visible = true;
                nbPrintRosterWarning.Text    = "Error printing Attendance Roster";
                return;
            }

            BinaryFile outputBinaryFileDoc = null;

            var mergeObjectList = mergeObjectsDictionary.Select(a => a.Value).ToList();

            outputBinaryFileDoc = mergeTemplateType.CreateDocument(mergeTemplate, mergeObjectList, globalMergeFields);

            // set the name of the output doc
            outputBinaryFileDoc          = new BinaryFileService(rockContext).Get(outputBinaryFileDoc.Id);
            outputBinaryFileDoc.FileName = _group.Name + " Attendance Roster" + Path.GetExtension(outputBinaryFileDoc.FileName ?? "") ?? ".docx";;
            rockContext.SaveChanges();

            if (mergeTemplateType.Exceptions != null && mergeTemplateType.Exceptions.Any())
            {
                if (mergeTemplateType.Exceptions.Count == 1)
                {
                    this.LogException(mergeTemplateType.Exceptions[0]);
                }
                else if (mergeTemplateType.Exceptions.Count > 50)
                {
                    this.LogException(new AggregateException(string.Format("Exceptions merging template {0}. See InnerExceptions for top 50.", mergeTemplate.Name), mergeTemplateType.Exceptions.Take(50).ToList()));
                }
                else
                {
                    this.LogException(new AggregateException(string.Format("Exceptions merging template {0}. See InnerExceptions", mergeTemplate.Name), mergeTemplateType.Exceptions.ToList()));
                }
            }

            var uri = new UriBuilder(outputBinaryFileDoc.Url);
            var qry = System.Web.HttpUtility.ParseQueryString(uri.Query);

            qry["attachment"] = true.ToTrueFalse();
            uri.Query         = qry.ToString();
            Response.Redirect(uri.ToString(), false);
            Context.ApplicationInstance.CompleteRequest();
        }
Beispiel #18
0
        /// <summary>
        /// Binds the grid.
        /// </summary>
        private void BindGrid()
        {
            var rockContext              = new RockContext();
            var transactionIdsQry        = new FinancialTransactionService(rockContext).Queryable();
            var transactionDetailService = new FinancialTransactionDetailService(rockContext);
            var qry = transactionDetailService.Queryable().AsNoTracking()
                      .Where(a => a.Transaction.TransactionDateTime.HasValue);

            var targetPerson = this.ContextEntity <Person>();

            if (targetPerson != null)
            {
                qry = qry.Where(t => t.Transaction.AuthorizedPersonAlias.Person.GivingId == targetPerson.GivingId);
            }

            var yearlyAccountDetails = qry.Select(t => new
            {
                Year        = t.Transaction.TransactionDateTime.Value.Year,
                AccountId   = t.Account.Id,
                AccountName = t.Account.Name,
                Amount      = t.Amount
            })
                                       .ToList();

            var summaryList = yearlyAccountDetails
                              .GroupBy(a => a.Year)
                              .Select(t => new
            {
                Year     = t.Key,
                Accounts = t.GroupBy(b => b.AccountId).Select(c => new
                {
                    AccountName = c.Max(d => d.AccountName),
                    TotalAmount = c.Sum(d => d.Amount)
                }).OrderBy(e => e.AccountName)
            }).OrderByDescending(a => a.Year)
                              .ToList();

            var mergeObjects = GlobalAttributesCache.GetMergeFields(this.CurrentPerson);

            var yearsMergeObjects = new List <Dictionary <string, object> >();

            foreach (var item in summaryList)
            {
                var accountsList = new List <object>();
                foreach (var a in item.Accounts)
                {
                    var accountDictionary = new Dictionary <string, object>();
                    accountDictionary.Add("Account", a.AccountName);
                    accountDictionary.Add("TotalAmount", a.TotalAmount);
                    accountsList.Add(accountDictionary);
                }

                var yearDictionary = new Dictionary <string, object>();
                yearDictionary.Add("Year", item.Year);
                yearDictionary.Add("SummaryRows", accountsList);

                yearsMergeObjects.Add(yearDictionary);
            }

            mergeObjects.Add("Rows", yearsMergeObjects);

            lLavaOutput.Text = string.Empty;
            if (GetAttributeValue("EnableDebug").AsBooleanOrNull().GetValueOrDefault(false))
            {
                lLavaOutput.Text = mergeObjects.lavaDebugInfo(rockContext);
            }

            string template = GetAttributeValue("LavaTemplate");

            lLavaOutput.Text += template.ResolveMergeFields(mergeObjects).ResolveClientIds(upnlContent.ClientID);
        }
Beispiel #19
0
        /// <summary>
        /// Sends the specified communication.
        /// </summary>
        /// <param name="communication">The communication.</param>
        /// <param name="CurrentPersonId">The current person id.</param>
        /// <exception cref="System.NotImplementedException"></exception>
        public override void Send(Rock.Model.Communication communication, int?CurrentPersonId)
        {
            if (communication != null &&
                communication.Status == Model.CommunicationStatus.Approved &&
                communication.Recipients.Where(r => r.Status == Model.CommunicationRecipientStatus.Pending).Any() &&
                (!communication.FutureSendDateTime.HasValue || communication.FutureSendDateTime.Value.CompareTo(DateTime.Now) > 0))
            {
                string fromPhone   = string.Empty;
                string fromValue   = communication.GetChannelDataValue("FromValue");
                int    fromValueId = int.MinValue;
                if (int.TryParse(fromValue, out fromValueId))
                {
                    fromPhone = DefinedValueCache.Read(fromValueId).Description;
                }

                if (!string.IsNullOrWhiteSpace(fromPhone))
                {
                    string accountSid = GetAttributeValue("SID");
                    string authToken  = GetAttributeValue("Token");
                    var    twilio     = new TwilioRestClient(accountSid, authToken);

                    var recipientService = new CommunicationRecipientService();

                    var globalConfigValues = GlobalAttributesCache.GetMergeFields(null);

                    bool recipientFound = true;
                    while (recipientFound)
                    {
                        RockTransactionScope.WrapTransaction(() =>
                        {
                            var recipient = recipientService.Get(communication.Id, CommunicationRecipientStatus.Pending).FirstOrDefault();
                            if (recipient != null)
                            {
                                string phoneNumber = recipient.Person.PhoneNumbers
                                                     .Where(p => p.IsMessagingEnabled)
                                                     .Select(p => p.Number)
                                                     .FirstOrDefault();

                                if (string.IsNullOrWhiteSpace(phoneNumber))
                                {
                                    recipient.Status     = CommunicationRecipientStatus.Failed;
                                    recipient.StatusNote = "No Phone Number with Messaging Enabled";
                                }
                                else
                                {
                                    // Create merge field dictionary
                                    var mergeObjects = MergeValues(globalConfigValues, recipient);
                                    string subject   = communication.Subject.ResolveMergeFields(mergeObjects);

                                    try
                                    {
                                        twilio.SendMessage(fromPhone, phoneNumber, subject);
                                        recipient.Status = CommunicationRecipientStatus.Success;
                                    }
                                    catch (Exception ex)
                                    {
                                        recipient.Status     = CommunicationRecipientStatus.Failed;
                                        recipient.StatusNote = "Twilio Exception: " + ex.Message;
                                    }
                                }
                                recipientService.Save(recipient, CurrentPersonId);
                            }
                            else
                            {
                                recipientFound = false;
                            }
                        });
                    }
                }
            }
        }
Beispiel #20
0
        /// <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)
        {
            if (string.IsNullOrWhiteSpace(txtFirstName.Text) ||
                string.IsNullOrWhiteSpace(txtLastName.Text) ||
                string.IsNullOrWhiteSpace(txtEmail.Text))
            {
                ShowError("Missing Information", "Please enter a value for First Name, Last Name, and Email");
            }
            else
            {
                var rockContext = new RockContext();
                var person      = GetPerson(rockContext);
                if (person != null)
                {
                    Guid?groupGuid = GetAttributeValue("Group").AsGuidOrNull();

                    if (groupGuid.HasValue)
                    {
                        var groupService       = new GroupService(rockContext);
                        var groupMemberService = new GroupMemberService(rockContext);

                        var group = groupService.Get(groupGuid.Value);
                        if (group != null && group.GroupType.DefaultGroupRoleId.HasValue)
                        {
                            string linkedPage = GetAttributeValue("ConfirmationPage");
                            if (!string.IsNullOrWhiteSpace(linkedPage))
                            {
                                var member = group.Members.Where(m => m.PersonId == person.Id).FirstOrDefault();

                                // If person has not registered or confirmed their registration
                                if (member == null || member.GroupMemberStatus != GroupMemberStatus.Active)
                                {
                                    Guid confirmationEmailTemplateGuid = Guid.Empty;
                                    if (!Guid.TryParse(GetAttributeValue("ConfirmationEmail"), out confirmationEmailTemplateGuid))
                                    {
                                        confirmationEmailTemplateGuid = Guid.Empty;
                                    }

                                    if (member == null)
                                    {
                                        member             = new GroupMember();
                                        member.GroupId     = group.Id;
                                        member.PersonId    = person.Id;
                                        member.GroupRoleId = group.GroupType.DefaultGroupRoleId.Value;

                                        // If a confirmation email is configured, set status to Pending otherwise set it to active
                                        member.GroupMemberStatus = confirmationEmailTemplateGuid != Guid.Empty ? GroupMemberStatus.Pending : GroupMemberStatus.Active;

                                        groupMemberService.Add(member);
                                        rockContext.SaveChanges();

                                        member = groupMemberService.Get(member.Id);
                                    }

                                    // Send the confirmation
                                    if (confirmationEmailTemplateGuid != Guid.Empty)
                                    {
                                        var mergeObjects = GlobalAttributesCache.GetMergeFields(null);
                                        mergeObjects.Add("Member", member);

                                        var pageParams = new Dictionary <string, string>();
                                        pageParams.Add("gm", member.UrlEncodedKey);
                                        var pageReference = new Rock.Web.PageReference(linkedPage, pageParams);
                                        mergeObjects.Add("ConfirmationPage", pageReference.BuildUrl());

                                        var recipients = new List <RecipientData>();
                                        recipients.Add(new RecipientData(person.Email, mergeObjects));
                                        Email.Send(confirmationEmailTemplateGuid, recipients, ResolveRockUrl("~/"), ResolveRockUrl("~~/"));
                                    }

                                    ShowSuccess(GetAttributeValue("SuccessMessage"));
                                }
                                else
                                {
                                    var pageParams = new Dictionary <string, string>();
                                    pageParams.Add("gm", member.UrlEncodedKey);
                                    var pageReference = new Rock.Web.PageReference(linkedPage, pageParams);
                                    Response.Redirect(pageReference.BuildUrl(), false);
                                }
                            }
                            else
                            {
                                ShowError("Configuration Error", "Invalid Confirmation Page setting");
                            }
                        }
                        else
                        {
                            ShowError("Configuration Error", "The configured group does not exist, or it's group type does not have a default role configured.");
                        }
                    }
                    else
                    {
                        ShowError("Configuration Error", "Invalid Group setting");
                    }
                }
            }
        }
        /// <summary>
        /// Handles the Click event of the btnSend 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 btnSend_Click(object sender, EventArgs e)
        {
            var url = LinkedPageUrl("ConfirmationPage");

            if (string.IsNullOrWhiteSpace(url))
            {
                url = ResolveRockUrl("~/ConfirmAccount");
            }

            var mergeObjects = GlobalAttributesCache.GetMergeFields(CurrentPerson);

            mergeObjects.Add("ConfirmAccountUrl", RootPath + url.TrimStart(new char[] { '/' }));
            var results = new List <IDictionary <string, object> >();

            var rockContext      = new RockContext();
            var personService    = new PersonService(rockContext);
            var userLoginService = new UserLoginService(rockContext);

            bool          hasAccountWithPasswordResetAbility = false;
            List <string> accountTypes = new List <string>();

            foreach (Person person in personService.GetByEmail(tbEmail.Text)
                     .Where(p => p.Users.Any()))
            {
                var users = new List <UserLogin>();
                foreach (UserLogin user in userLoginService.GetByPersonId(person.Id))
                {
                    if (user.EntityType != null)
                    {
                        var component = AuthenticationContainer.GetComponent(user.EntityType.Name);
                        if (!component.RequiresRemoteAuthentication)
                        {
                            users.Add(user);
                            hasAccountWithPasswordResetAbility = true;
                        }

                        accountTypes.Add(user.EntityType.FriendlyName);
                    }
                }

                var resultsDictionary = new Dictionary <string, object>();
                resultsDictionary.Add("Person", person);
                resultsDictionary.Add("Users", users);
                results.Add(resultsDictionary);
            }

            if (results.Count > 0 && hasAccountWithPasswordResetAbility)
            {
                mergeObjects.Add("Results", results.ToArray());
                var recipients = new List <RecipientData>();
                recipients.Add(new RecipientData(tbEmail.Text, mergeObjects));

                Email.Send(GetAttributeValue("EmailTemplate").AsGuid(), recipients, ResolveRockUrlIncludeRoot("~/"), ResolveRockUrlIncludeRoot("~~/"), false);

                pnlEntry.Visible   = false;
                pnlSuccess.Visible = true;
            }
            else if (results.Count > 0)
            {
                // the person has user accounts but none of them are allowed to have their passwords reset (Facebook/Google/etc)

                lWarning.Text = string.Format(@"<p>We were able to find the following accounts for this email, but 
                                                none of them are able to be reset from this website.</p> <p>Accounts:<br /> {0}</p>
                                                <p>To create a new account with a username and password please see our <a href='{1}'>New Account</a>
                                                page.</p>"
                                              , string.Join(",", accountTypes)
                                              , ResolveRockUrl("~/NewAccount"));
                pnlWarning.Visible = true;
            }
            else
            {
                pnlWarning.Visible = true;
            }
        }