/// <summary>
        /// Configures the note editor.
        /// </summary>
        /// <param name="personId">The person identifier.</param>
        private void ConfigureNoteEditor()
        {
            var noteTypes = NoteTypeCache.GetByEntity(EntityTypeCache.GetId <Rock.Model.Person>(), string.Empty, string.Empty, true);

            // If block is configured to only allow certain note types, limit notes to those types.
            var configuredNoteTypes = GetAttributeValue(AttributeKey.NoteTypes).SplitDelimitedValues().AsGuidList();

            if (configuredNoteTypes.Any())
            {
                noteTypes = noteTypes.Where(n => configuredNoteTypes.Contains(n.Guid)).ToList();
            }

            NoteOptions noteOptions = new NoteOptions(this.ViewState)
            {
                NoteTypes           = noteTypes.ToArray(),
                AddAlwaysVisible    = true,
                DisplayType         = NoteDisplayType.Full,
                ShowAlertCheckBox   = true,
                ShowPrivateCheckBox = true,
                UsePersonIcon       = true,
                ShowSecurityButton  = false,
                ShowCreateDateInput = false,
            };

            noteEditor.SetNoteOptions(noteOptions);
            noteEditor.NoteTypeId = noteTypes.FirstOrDefault()?.Id;
        }
        /// <summary>
        /// Renders the notes.
        /// </summary>
        private void ShowNotes()
        {
            IEntity contextEntity;

            if (ContextTypesRequired.Count == 1)
            {
                contextEntity = this.ContextEntity(ContextTypesRequired.First().Name);
            }
            else
            {
                contextEntity = this.ContextEntity();
            }

            if (contextEntity != null)
            {
                upNotes.Visible = true;

                string noteTypeName = GetAttributeValue("NoteType");

                using (var rockContext = new RockContext())
                {
                    var noteTypes = NoteTypeCache.GetByEntity(contextEntity.TypeId, string.Empty, string.Empty, true);

                    // If block is configured to only allow certain note types, limit notes to those types.
                    var configuredNoteTypes = GetAttributeValue("NoteTypes").SplitDelimitedValues().AsGuidList();
                    if (configuredNoteTypes.Any())
                    {
                        noteTypes = noteTypes.Where(n => configuredNoteTypes.Contains(n.Guid)).ToList();
                    }

                    NoteOptions noteOptions = new NoteOptions(notesTimeline)
                    {
                        EntityId               = contextEntity.Id,
                        NoteTypes              = noteTypes.ToArray(),
                        NoteLabel              = GetAttributeValue("NoteTerm"),
                        DisplayType            = GetAttributeValue("DisplayType") == "Light" ? NoteDisplayType.Light : NoteDisplayType.Full,
                        ShowAlertCheckBox      = GetAttributeValue("ShowAlertCheckbox").AsBoolean(),
                        ShowPrivateCheckBox    = GetAttributeValue("ShowPrivateCheckbox").AsBoolean(),
                        ShowSecurityButton     = GetAttributeValue("ShowSecurityButton").AsBoolean(),
                        AddAlwaysVisible       = GetAttributeValue("AddAlwaysVisible").AsBoolean(),
                        ShowCreateDateInput    = GetAttributeValue("AllowBackdatedNotes").AsBoolean(),
                        NoteViewLavaTemplate   = GetAttributeValue("NoteViewLavaTemplate"),
                        DisplayNoteTypeHeading = GetAttributeValue("DisplayNoteTypeHeading").AsBoolean(),
                        UsePersonIcon          = GetAttributeValue("UsePersonIcon").AsBoolean(),
                        ExpandReplies          = GetAttributeValue("ExpandReplies").AsBoolean()
                    };

                    notesTimeline.NoteOptions         = noteOptions;
                    notesTimeline.Title               = GetAttributeValue("Heading");
                    notesTimeline.TitleIconCssClass   = GetAttributeValue("HeadingIcon");
                    notesTimeline.AllowAnonymousEntry = GetAttributeValue("Allow Anonymous").AsBoolean();
                    notesTimeline.SortDirection       = GetAttributeValue("DisplayOrder") == "Ascending" ? ListSortDirection.Ascending : ListSortDirection.Descending;
                }
            }
            else
            {
                upNotes.Visible = false;
            }
        }
示例#3
0
        /// <summary>
        /// Loads the note type drop down.
        /// </summary>
        public void LoadNoteTypeDropDown(int?entityTypeId)
        {
            ddlNoteType.Items.Clear();
            ddlNoteType.Items.Add(new ListItem());
            if (entityTypeId.HasValue)
            {
                var entityNoteTypes = NoteTypeCache.GetByEntity(entityTypeId.Value, null, null, true);
                ddlNoteType.Items.AddRange(entityNoteTypes.Select(a => new ListItem(a.Name, a.Id.ToString())).ToArray());
            }

            ddlNoteType.Visible = entityTypeId.HasValue;
        }
示例#4
0
        /// <summary>
        /// Gets the viewable note types.
        /// </summary>
        /// <returns></returns>
        private ICollection <NoteTypeCache> GetViewableNoteTypes()
        {
            var contextEntityType = EntityTypeCache.Get(ContextEntityType);

            if (contextEntityType == null)
            {
                return(new NoteTypeCache[0]);
            }

            return(NoteTypeCache.GetByEntity(contextEntityType.Id, string.Empty, string.Empty, true)
                   .Where(a => !NoteTypes.Any() || NoteTypes.Contains(a.Guid))
                   .Where(a => a.IsAuthorized(Authorization.VIEW, RequestContext.CurrentPerson))
                   .ToList());
        }
        private List <NoteTypeCache> getNoteTypes()
        {
            var noteTypes = NoteTypeCache.GetByEntity(_entityTypeId, string.Empty, string.Empty, true);

            // If block is configured to only allow certain note types, limit notes to those types.
            var configuredPersonNoteTypes      = GetAttributeValue("PersonNoteTypes").SplitDelimitedValues().AsGuidList();
            var configuredGroupMemberNoteTypes = GetAttributeValue("GroupMemberNoteTypes").SplitDelimitedValues().AsGuidList();

            if (configuredPersonNoteTypes.Any() || configuredGroupMemberNoteTypes.Any())
            {
                noteTypes = noteTypes.Where(n => configuredPersonNoteTypes.Contains(n.Guid) || configuredGroupMemberNoteTypes.Contains(n.Guid)).ToList();
            }

            return(noteTypes);
        }
示例#6
0
        /// <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 contextEntity = this.ContextEntity();

            if (contextEntity != null)
            {
                upNotes.Visible = true;

                string noteTypeName = GetAttributeValue("NoteType");

                using (var rockContext = new RockContext())
                {
                    var noteTypes = NoteTypeCache.GetByEntity(contextEntity.TypeId, string.Empty, string.Empty, true);

                    // If block is configured to only allow certain note types, limit notes to those types.
                    var configuredNoteTypes = GetAttributeValue("NoteTypes").SplitDelimitedValues().AsGuidList();
                    if (configuredNoteTypes.Any())
                    {
                        noteTypes = noteTypes.Where(n => configuredNoteTypes.Contains(n.Guid)).ToList();
                    }

                    notesTimeline.EntityId          = contextEntity.Id;
                    notesTimeline.NoteTypes         = noteTypes;
                    notesTimeline.Title             = GetAttributeValue("Heading");
                    notesTimeline.TitleIconCssClass = GetAttributeValue("HeadingIcon");
                    notesTimeline.Term                = GetAttributeValue("NoteTerm");
                    notesTimeline.DisplayType         = GetAttributeValue("DisplayType") == "Light" ? NoteDisplayType.Light : NoteDisplayType.Full;
                    notesTimeline.UsePersonIcon       = GetAttributeValue("UsePersonIcon").AsBoolean();
                    notesTimeline.ShowAlertCheckBox   = GetAttributeValue("ShowAlertCheckbox").AsBoolean();
                    notesTimeline.ShowPrivateCheckBox = GetAttributeValue("ShowPrivateCheckbox").AsBoolean();
                    notesTimeline.ShowSecurityButton  = GetAttributeValue("ShowSecurityButton").AsBoolean();
                    notesTimeline.AllowAnonymousEntry = GetAttributeValue("Allow Anonymous").AsBoolean();
                    notesTimeline.AddAlwaysVisible    = GetAttributeValue("AddAlwaysVisible").AsBoolean();
                    notesTimeline.SortDirection       = GetAttributeValue("DisplayOrder") == "Ascending" ? ListSortDirection.Ascending : ListSortDirection.Descending;
                    notesTimeline.ShowCreateDateInput = GetAttributeValue("AllowBackdatedNotes").AsBoolean();
                }
            }
            else
            {
                upNotes.Visible = false;
            }
        }
示例#7
0
        private bool HydrateObjects()
        {
            LoadWorkflowType();

            // Set the note type if this is first request
            if (!Page.IsPostBack)
            {
                var entityType = EntityTypeCache.Get(typeof(Rock.Model.Workflow));
                var noteTypes  = NoteTypeCache.GetByEntity(entityType.Id, string.Empty, string.Empty);
                ncWorkflowNotes.NoteOptions.SetNoteTypes(noteTypes);
            }

            if (_workflowType == null)
            {
                ShowNotes(false);
                ShowMessage(NotificationBoxType.Danger, "Configuration Error", "Workflow type was not configured or specified correctly.");
                return(false);
            }

            if (!_workflowType.IsAuthorized(Authorization.VIEW, CurrentPerson))
            {
                ShowNotes(false);
                ShowMessage(NotificationBoxType.Warning, "Sorry", "You are not authorized to view this type of workflow.");
                return(false);
            }

            if (!(_workflowType.IsActive ?? true))
            {
                ShowNotes(false);
                ShowMessage(NotificationBoxType.Warning, "Sorry", "This type of workflow is not active.");
                return(false);
            }

            // If operating against an existing workflow, get the workflow and load attributes
            if (!WorkflowId.HasValue)
            {
                WorkflowId = PageParameter("WorkflowId").AsIntegerOrNull();
                if (!WorkflowId.HasValue)
                {
                    Guid guid = PageParameter("WorkflowGuid").AsGuid();
                    if (!guid.IsEmpty())
                    {
                        _workflow = _workflowService.Queryable()
                                    .Where(w => w.Guid.Equals(guid) && w.WorkflowTypeId == _workflowType.Id)
                                    .FirstOrDefault();
                        if (_workflow != null)
                        {
                            WorkflowId = _workflow.Id;
                        }
                    }
                }
            }

            if (WorkflowId.HasValue)
            {
                if (_workflow == null)
                {
                    _workflow = _workflowService.Queryable()
                                .Where(w => w.Id == WorkflowId.Value && w.WorkflowTypeId == _workflowType.Id)
                                .FirstOrDefault();
                }
                if (_workflow != null)
                {
                    hlblWorkflowId.Text = _workflow.WorkflowId;

                    _workflow.LoadAttributes();
                    foreach (var activity in _workflow.Activities)
                    {
                        activity.LoadAttributes();
                    }
                }
            }

            // If an existing workflow was not specified, activate a new instance of workflow and start processing
            if (_workflow == null)
            {
                string workflowName = PageParameter("WorkflowName");
                if (string.IsNullOrWhiteSpace(workflowName))
                {
                    workflowName = "New " + _workflowType.WorkTerm;
                }

                _workflow = Rock.Model.Workflow.Activate(_workflowType, workflowName);
                if (_workflow != null)
                {
                    // If a PersonId or GroupId parameter was included, load the corresponding
                    // object and pass that to the actions for processing
                    object entity   = null;
                    int?   personId = PageParameter("PersonId").AsIntegerOrNull();
                    if (personId.HasValue)
                    {
                        entity = new PersonService(_rockContext).Get(personId.Value);
                    }
                    else
                    {
                        int?groupId = PageParameter("GroupId").AsIntegerOrNull();
                        if (groupId.HasValue)
                        {
                            entity = new GroupService(_rockContext).Get(groupId.Value);
                        }
                    }

                    // Loop through all the query string parameters and try to set any workflow
                    // attributes that might have the same key
                    foreach (var param in RockPage.PageParameters())
                    {
                        if (param.Value != null && param.Value.ToString().IsNotNullOrWhiteSpace())
                        {
                            _workflow.SetAttributeValue(param.Key, param.Value.ToString());
                        }
                    }

                    List <string> errorMessages;
                    if (!_workflowService.Process(_workflow, entity, out errorMessages))
                    {
                        ShowNotes(false);
                        ShowMessage(NotificationBoxType.Danger, "Workflow Processing Error(s):",
                                    "<ul><li>" + errorMessages.AsDelimited("</li><li>") + "</li></ul>");
                        return(false);
                    }
                    if (_workflow.Id != 0)
                    {
                        WorkflowId = _workflow.Id;
                    }
                }
            }

            if (_workflow == null)
            {
                ShowNotes(false);
                ShowMessage(NotificationBoxType.Danger, "Workflow Activation Error", "Workflow could not be activated.");
                return(false);
            }

            var canEdit = UserCanEdit || _workflow.IsAuthorized(Authorization.EDIT, CurrentPerson);

            if (_workflow.IsActive)
            {
                if (ActionTypeId.HasValue)
                {
                    foreach (var activity in _workflow.ActiveActivities)
                    {
                        _action = activity.ActiveActions.Where(a => a.ActionTypeId == ActionTypeId.Value).FirstOrDefault();
                        if (_action != null)
                        {
                            _activity = activity;
                            _activity.LoadAttributes();

                            _actionType  = _action.ActionTypeCache;
                            ActionTypeId = _actionType.Id;
                            return(true);
                        }
                    }
                }

                // Find first active action form
                int personId = CurrentPerson != null ? CurrentPerson.Id : 0;
                int?actionId = PageParameter("ActionId").AsIntegerOrNull();
                foreach (var activity in _workflow.Activities
                         .Where(a =>
                                a.IsActive &&
                                (!actionId.HasValue || a.Actions.Any(ac => ac.Id == actionId.Value)) &&
                                (
                                    (canEdit) ||
                                    (!a.AssignedGroupId.HasValue && !a.AssignedPersonAliasId.HasValue) ||
                                    (a.AssignedPersonAlias != null && a.AssignedPersonAlias.PersonId == personId) ||
                                    (a.AssignedGroup != null && a.AssignedGroup.Members.Any(m => m.PersonId == personId))
                                )
                                )
                         .ToList()
                         .OrderBy(a => a.ActivityTypeCache.Order))
                {
                    if (canEdit || (activity.ActivityTypeCache.IsAuthorized(Authorization.VIEW, CurrentPerson)))
                    {
                        foreach (var action in activity.ActiveActions
                                 .Where(a => (!actionId.HasValue || a.Id == actionId.Value)))
                        {
                            if (action.ActionTypeCache.WorkflowForm != null && action.IsCriteriaValid)
                            {
                                _activity = activity;
                                _activity.LoadAttributes();

                                _action      = action;
                                _actionType  = _action.ActionTypeCache;
                                ActionTypeId = _actionType.Id;
                                return(true);
                            }
                        }
                    }
                }

                lSummary.Text = string.Empty;
            }
            else
            {
                if (GetAttributeValue("ShowSummaryView").AsBoolean() && !string.IsNullOrWhiteSpace(_workflowType.SummaryViewText))
                {
                    var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage, this.CurrentPerson);
                    mergeFields.Add("Action", _action);
                    mergeFields.Add("Activity", _activity);
                    mergeFields.Add("Workflow", _workflow);

                    lSummary.Text    = _workflowType.SummaryViewText.ResolveMergeFields(mergeFields, CurrentPerson);
                    lSummary.Visible = true;
                }
            }

            if (lSummary.Text.IsNullOrWhiteSpace())
            {
                if (_workflowType.NoActionMessage.IsNullOrWhiteSpace())
                {
                    ShowMessage(NotificationBoxType.Warning, string.Empty, "The selected workflow is not in a state that requires you to enter information.");
                }
                else
                {
                    var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(this.RockPage, this.CurrentPerson);
                    mergeFields.Add("Action", _action);
                    mergeFields.Add("Activity", _activity);
                    mergeFields.Add("Workflow", _workflow);
                    ShowMessage(NotificationBoxType.Warning, string.Empty, _workflowType.NoActionMessage.ResolveMergeFields(mergeFields, CurrentPerson));
                }
            }

            ShowNotes(false);
            return(false);
        }
        /// <summary>
        /// Executes the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        public virtual void Execute(IJobExecutionContext context)
        {
            var dataMap                 = context.JobDetail.JobDataMap;
            var JobStartDateTime        = RockDateTime.Now;
            var minimumCareTouches      = dataMap.GetIntegerFromString(AttributeKey.MinimumCareTouches);
            var minimumCareTouchesHours = dataMap.GetIntegerFromString(AttributeKey.MinimumCareTouches);
            var followUpDays            = dataMap.GetIntegerFromString(AttributeKey.FollowUpDays);

            using (var rockContext = new RockContext())
            {
                // get the last run date or yesterday
                DateTime?lastStartDateTime = null;

                // get job type id
                int jobId = context.JobDetail.Description.AsInteger();

                // load job
                var job = new ServiceJobService(rockContext)
                          .GetNoTracking(jobId);

                if (job != null && job.Guid != Rock.SystemGuid.ServiceJob.JOB_PULSE.AsGuid())
                {
                    lastStartDateTime = job.LastRunDateTime?.AddSeconds(0.0d - ( double )job.LastRunDurationSeconds);
                }
                var beginDateTime = lastStartDateTime ?? JobStartDateTime.AddDays(-1);
                //beginDateTime = JobStartDateTime.AddDays( -3 );

                var careNeedService       = new CareNeedService(rockContext);
                var assignedPersonService = new AssignedPersonService(rockContext);

                var noteType         = NoteTypeCache.GetByEntity(EntityTypeCache.Get(typeof(CareNeed)).Id, "", "", true).FirstOrDefault();
                var careNeedNotesQry = new NoteService(rockContext)
                                       .GetByNoteTypeId(noteType.Id).AsNoTracking();

                var closedValueId = DefinedValueCache.Get(SystemGuid.DefinedValue.CARE_NEED_STATUS_CLOSED.AsGuid()).Id;
                var followUpValue = DefinedValueCache.Get(SystemGuid.DefinedValue.CARE_NEED_STATUS_FOLLOWUP.AsGuid());
                var openValueId   = DefinedValueCache.Get(SystemGuid.DefinedValue.CARE_NEED_STATUS_OPEN.AsGuid()).Id;

                var careNeeds    = careNeedService.Queryable("PersonAlias,SubmitterPersonAlias").Where(n => n.StatusValueId != closedValueId);
                var careAssigned = assignedPersonService.Queryable().Where(ap => ap.PersonAliasId != null && ap.NeedId != null && ap.CareNeed.StatusValueId != closedValueId).DistinctBy(ap => ap.PersonAliasId);

                var careNeedFollowUp = careNeeds.Where(n => n.StatusValueId == openValueId && n.DateEntered <= DbFunctions.AddDays(RockDateTime.Now, -followUpDays));

                var careNeed24Hrs   = careNeeds.Where(n => n.StatusValueId == openValueId && DbFunctions.DiffHours(n.DateEntered.Value, RockDateTime.Now) >= minimumCareTouchesHours);
                var careNeedFlagged = careNeed24Hrs
                                      .SelectMany(cn => careNeedNotesQry.Where(n => n.EntityId == cn.Id && cn.AssignedPersons.Any(ap => ap.FollowUpWorker.HasValue && ap.FollowUpWorker.Value && ap.PersonAliasId == n.CreatedByPersonAliasId)).DefaultIfEmpty(),
                                                  (cn, n) => new
                {
                    CareNeed = cn,
                    HasFollowUpWorkerNote = n != null,
                    TouchCount            = careNeedNotesQry.Where(note => note.EntityId == cn.Id).Count()
                })
                                      .Where(f => !f.HasFollowUpWorkerNote || f.TouchCount <= minimumCareTouches)
                                      .ToList();

                var followUpSystemCommunicationGuid   = dataMap.GetString(AttributeKey.FollowUpSystemCommunication).AsGuid();
                var careTouchNeededCommunicationGuid  = dataMap.GetString(AttributeKey.CareTouchNeededCommunication).AsGuid();
                var outstandingNeedsCommunicationGuid = dataMap.GetString(AttributeKey.OutstandingNeedsCommunication).AsGuid();
                var followUpSystemCommunication       = new SystemCommunicationService(rockContext).Get(followUpSystemCommunicationGuid);
                var careTouchNeededCommunication      = new SystemCommunicationService(rockContext).Get(careTouchNeededCommunicationGuid);
                var outstandingNeedsCommunication     = new SystemCommunicationService(rockContext).Get(outstandingNeedsCommunicationGuid);

                var detailPage         = PageCache.Get(dataMap.GetString(AttributeKey.CareDetailPage));
                var detailPageRoute    = detailPage.PageRoutes.FirstOrDefault();
                var dashboardPage      = PageCache.Get(dataMap.GetString(AttributeKey.CareDashboardPage));
                var dashboardPageRoute = dashboardPage.PageRoutes.FirstOrDefault();
                Dictionary <string, object> linkedPages = new Dictionary <string, object>();
                linkedPages.Add("CareDetail", detailPageRoute != null ? "/" + detailPageRoute.Route : "/page/" + detailPage.Id);
                linkedPages.Add("CareDashboard", dashboardPageRoute != null ? "/" + dashboardPageRoute.Route : "/page/" + dashboardPage.Id);

                var errors    = new List <string>();
                var errorsSms = new List <string>();

                // Update status to follow up and email follow up messages
                foreach (var careNeed in careNeedFollowUp)
                {
                    careNeed.StatusValueId = followUpValue.Id;
                    careNeed.LoadAttributes();

                    if (!followUpSystemCommunicationGuid.IsEmpty())
                    {
                        var emailMessage = new RockEmailMessage(followUpSystemCommunication);
                        var smsMessage   = new RockSMSMessage(followUpSystemCommunication);

                        foreach (var assignee in careNeed.AssignedPersons.Where(ap => ap.FollowUpWorker.HasValue && ap.FollowUpWorker.Value))
                        {
                            assignee.PersonAlias.Person.LoadAttributes();

                            var smsNumber = assignee.PersonAlias.Person.PhoneNumbers.GetFirstSmsNumber();
                            if (!assignee.PersonAlias.Person.CanReceiveEmail(false) && smsNumber.IsNullOrWhiteSpace())
                            {
                                continue;
                            }
                            var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null, assignee.PersonAlias.Person);
                            mergeFields.Add("CareNeed", careNeed);
                            mergeFields.Add("LinkedPages", linkedPages);
                            mergeFields.Add("AssignedPerson", assignee);
                            mergeFields.Add("Person", assignee.PersonAlias.Person);

                            var recipients = new List <RockMessageRecipient>();
                            recipients.Add(new RockEmailMessageRecipient(assignee.PersonAlias.Person, mergeFields));

                            var notificationType = assignee.PersonAlias.Person.GetAttributeValue(SystemGuid.PersonAttribute.NOTIFICATION.AsGuid());

                            if (notificationType == null || notificationType == "Email" || notificationType == "Both")
                            {
                                if (!assignee.PersonAlias.Person.CanReceiveEmail(false))
                                {
                                    errorCount += 1;
                                    errorMessages.Add(string.Format("{0} does not have a valid email address.", assignee.PersonAlias.Person.FullName));
                                }
                                else
                                {
                                    emailMessage.AddRecipient(new RockEmailMessageRecipient(assignee.PersonAlias.Person, mergeFields));
                                }
                            }
                            if (notificationType == "SMS" || notificationType == "Both")
                            {
                                if (string.IsNullOrWhiteSpace(smsNumber))
                                {
                                    errorCount += 1;
                                    errorMessages.Add(string.Format("No SMS number could be found for {0}.", assignee.PersonAlias.Person.FullName));
                                }
                                smsMessage.AddRecipient(new RockSMSMessageRecipient(assignee.PersonAlias.Person, smsNumber, mergeFields));
                            }
                            //pushMessage.AddRecipient( new RockPushMessageRecipient( assignee.PersonAlias.Person, assignee.PersonAlias.Person.Devices, mergeFields ) );
                        }

                        if (emailMessage.GetRecipients().Count > 0)
                        {
                            emailMessage.Send(out errors);
                        }
                        if (smsMessage.GetRecipients().Count > 0)
                        {
                            smsMessage.Send(out errorsSms);
                        }

                        if (errors.Any())
                        {
                            errorCount += errors.Count;
                            errorMessages.AddRange(errors);
                        }
                        else
                        {
                            assignedPersonEmails++;
                        }
                        if (errorsSms.Any())
                        {
                            errorCount += errorsSms.Count;
                            errorMessages.AddRange(errorsSms);
                        }
                        else
                        {
                            assignedPersonSms++;
                        }
                    }
                }
                rockContext.SaveChanges();

                // Send notification about "Flagged" messages (any messages without a care touch by the follow up worker or minimum care touches within the set minimum Care Touches Hours.
                if (careTouchNeededCommunication != null && careTouchNeededCommunication.Id > 0)
                {
                    foreach (var flagNeed in careNeedFlagged)
                    {
                        var careNeed = flagNeed.CareNeed;
                        careNeed.LoadAttributes();
                        var emailMessage = new RockEmailMessage(careTouchNeededCommunication);
                        var smsMessage   = new RockSMSMessage(careTouchNeededCommunication);
                        //var pushMessage = new RockPushMessage( careTouchNeededCommunication );
                        var recipients = new List <RockMessageRecipient>();

                        foreach (var assignee in careNeed.AssignedPersons)
                        {
                            assignee.PersonAlias.Person.LoadAttributes();

                            var smsNumber = assignee.PersonAlias.Person.PhoneNumbers.GetFirstSmsNumber();
                            if (!assignee.PersonAlias.Person.CanReceiveEmail(false) && smsNumber.IsNullOrWhiteSpace())
                            {
                                continue;
                            }

                            var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null, assignee.PersonAlias.Person);
                            mergeFields.Add("CareNeed", careNeed);
                            mergeFields.Add("LinkedPages", linkedPages);
                            mergeFields.Add("AssignedPerson", assignee);
                            mergeFields.Add("Person", assignee.PersonAlias.Person);
                            mergeFields.Add("TouchCount", flagNeed.TouchCount);
                            mergeFields.Add("HasFollowUpWorkerNote", flagNeed.HasFollowUpWorkerNote);

                            var notificationType = assignee.PersonAlias.Person.GetAttributeValue(SystemGuid.PersonAttribute.NOTIFICATION.AsGuid());

                            if (notificationType == null || notificationType == "Email" || notificationType == "Both")
                            {
                                if (!assignee.PersonAlias.Person.CanReceiveEmail(false))
                                {
                                    errorCount += 1;
                                    errorMessages.Add(string.Format("{0} does not have a valid email address.", assignee.PersonAlias.Person.FullName));
                                }
                                else
                                {
                                    emailMessage.AddRecipient(new RockEmailMessageRecipient(assignee.PersonAlias.Person, mergeFields));
                                }
                            }
                            if (notificationType == "SMS" || notificationType == "Both")
                            {
                                if (string.IsNullOrWhiteSpace(smsNumber))
                                {
                                    errorCount += 1;
                                    errorMessages.Add(string.Format("No SMS number could be found for {0}.", assignee.PersonAlias.Person.FullName));
                                }
                                smsMessage.AddRecipient(new RockSMSMessageRecipient(assignee.PersonAlias.Person, smsNumber, mergeFields));
                            }
                            //pushMessage.AddRecipient( new RockPushMessageRecipient( assignee.PersonAlias.Person, assignee.PersonAlias.Person.Devices, mergeFields ) );
                        }
                        if (emailMessage.GetRecipients().Count > 0)
                        {
                            emailMessage.Send(out errors);
                        }
                        if (smsMessage.GetRecipients().Count > 0)
                        {
                            smsMessage.Send(out errorsSms);
                        }

                        if (errors.Any())
                        {
                            errorCount += errors.Count;
                            errorMessages.AddRange(errors);
                        }
                        else
                        {
                            assignedPersonEmails++;
                        }
                        if (errorsSms.Any())
                        {
                            errorCount += errorsSms.Count;
                            errorMessages.AddRange(errorsSms);
                        }
                        else
                        {
                            assignedPersonSms++;
                        }
                    }
                }

                // Send Outstanding needs daily notification
                if (outstandingNeedsCommunication != null && outstandingNeedsCommunication.Id > 0)
                {
                    foreach (var assigned in careAssigned)
                    {
                        var smsNumber = assigned.PersonAlias.Person.PhoneNumbers.GetFirstSmsNumber();

                        if (!assigned.PersonAlias.Person.CanReceiveEmail(false) && smsNumber.IsNullOrWhiteSpace())
                        {
                            continue;
                        }
                        var emailMessage = new RockEmailMessage(outstandingNeedsCommunication);
                        var smsMessage   = new RockSMSMessage(outstandingNeedsCommunication);
                        //var pushMessage = new RockPushMessage( outstandingNeedsCommunication );
                        var recipients = new List <RockMessageRecipient>();

                        var assignedNeeds = careNeeds.Where(cn => cn.AssignedPersons.Any(ap => ap.PersonAliasId == assigned.PersonAliasId));

                        assigned.PersonAlias.Person.LoadAttributes();

                        var mergeFields = Rock.Lava.LavaHelper.GetCommonMergeFields(null, assigned.PersonAlias.Person);
                        mergeFields.Add("CareNeeds", assignedNeeds);
                        mergeFields.Add("LinkedPages", linkedPages);
                        mergeFields.Add("AssignedPerson", assigned);
                        mergeFields.Add("Person", assigned.PersonAlias.Person);

                        var notificationType = assigned.PersonAlias.Person.GetAttributeValue(SystemGuid.PersonAttribute.NOTIFICATION.AsGuid());

                        if (notificationType == null || notificationType == "Email" || notificationType == "Both")
                        {
                            if (!assigned.PersonAlias.Person.CanReceiveEmail(false))
                            {
                                errorCount += 1;
                                errorMessages.Add(string.Format("{0} does not have a valid email address.", assigned.PersonAlias.Person.FullName));
                            }
                            else
                            {
                                emailMessage.AddRecipient(new RockEmailMessageRecipient(assigned.PersonAlias.Person, mergeFields));
                            }
                        }
                        if (notificationType == "SMS" || notificationType == "Both")
                        {
                            if (string.IsNullOrWhiteSpace(smsNumber))
                            {
                                errorCount += 1;
                                errorMessages.Add(string.Format("No SMS number could be found for {0}.", assigned.PersonAlias.Person.FullName));
                            }
                            smsMessage.AddRecipient(new RockSMSMessageRecipient(assigned.PersonAlias.Person, smsNumber, mergeFields));
                        }
                        //pushMessage.AddRecipient( new RockPushMessageRecipient( assignee.PersonAlias.Person, assignee.PersonAlias.Person.Devices, mergeFields ) );

                        if (emailMessage.GetRecipients().Count > 0)
                        {
                            emailMessage.Send(out errors);
                        }
                        if (smsMessage.GetRecipients().Count > 0)
                        {
                            smsMessage.Send(out errorsSms);
                        }

                        if (errors.Any())
                        {
                            errorCount += errors.Count;
                            errorMessages.AddRange(errors);
                        }
                        else
                        {
                            assignedPersonEmails++;
                        }
                        if (errorsSms.Any())
                        {
                            errorCount += errorsSms.Count;
                            errorMessages.AddRange(errorsSms);
                        }
                        else
                        {
                            assignedPersonSms++;
                        }
                    }
                }
            }
            context.Result = string.Format("{0} emails sent \n{1} SMS messages sent", assignedPersonEmails, assignedPersonSms);
            if (errorMessages.Any())
            {
                StringBuilder sb = new StringBuilder();
                sb.AppendLine();
                sb.Append(string.Format("{0} Errors: ", errorCount));
                errorMessages.ForEach(e => { sb.AppendLine(); sb.Append(e); });
                string errors = sb.ToString();
                context.Result += errors;
                var         exception = new Exception(errors);
                HttpContext context2  = HttpContext.Current;
                ExceptionLogService.LogException(exception, context2);
                throw exception;
            }
        }