protected void ddlActivateNewActivity_SelectedIndexChanged(object sender, EventArgs e)
        {
            ParseControls();

            int?activityTypeId = ddlActivateNewActivity.SelectedValueAsId();

            if (activityTypeId.HasValue)
            {
                var activityType = new WorkflowActivityTypeService(new RockContext()).Get(activityTypeId.Value);
                if (activityType != null)
                {
                    var activity = WorkflowActivity.Activate(activityType, Workflow);
                    activity.ActivityTypeId = activity.ActivityType.Id;
                    activity.Guid           = Guid.NewGuid();

                    foreach (var action in activity.Actions)
                    {
                        action.ActionTypeId = action.ActionType.Id;
                        action.Guid         = Guid.NewGuid();
                    }

                    Workflow.AddLogEntry(string.Format("Manually Activated new '{0}' activity", activityType.ToString()));

                    ExpandedActivities.Add(activity.Guid);

                    BuildControls(true, activity.Guid);
                }
            }

            ddlActivateNewActivity.SelectedIndex = 0;
        }
        /// <summary>
        /// Returns the field's current value(s)
        /// </summary>
        /// <param name="parentControl">The parent control.</param>
        /// <param name="value">Information about the value</param>
        /// <param name="configurationValues">The configuration values.</param>
        /// <param name="condensed">Flag indicating if the value should be condensed (i.e. for use in a grid column)</param>
        /// <returns></returns>
        public override string FormatValue(Control parentControl, string value, Dictionary <string, ConfigurationValue> configurationValues, bool condensed)
        {
            string formattedValue = string.Empty;

            Guid guid = value.AsGuid();

            if (!guid.IsEmpty())
            {
                var workflowType = GetContextWorkflowType();
                if (workflowType != null)
                {
                    formattedValue = workflowType.ActivityTypes
                                     .Where(a => a.Guid.Equals(guid))
                                     .Select(a => a.Name)
                                     .FirstOrDefault();
                }

                if (string.IsNullOrWhiteSpace(formattedValue))
                {
                    formattedValue = new WorkflowActivityTypeService(new RockContext()).Queryable()
                                     .Where(a => a.Guid.Equals(guid))
                                     .Select(a => a.Name)
                                     .FirstOrDefault();
                }
            }

            return(base.FormatValue(parentControl, formattedValue, null, condensed));
        }
        /// <summary>
        /// Sets the edit value from IEntity.Id value
        /// </summary>
        /// <param name="control">The control.</param>
        /// <param name="configurationValues">The configuration values.</param>
        /// <param name="id">The identifier.</param>
        public void SetEditValueFromEntityId(Control control, Dictionary <string, ConfigurationValue> configurationValues, int?id)
        {
            var item      = new WorkflowActivityTypeService(new RockContext()).Get(id ?? 0);
            var guidValue = item != null?item.Guid.ToString() : string.Empty;

            SetEditValue(control, configurationValues, guidValue);
        }
Exemple #4
0
        /// <summary>
        /// Executes the specified workflow.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="action">The action.</param>
        /// <param name="entity">The entity.</param>
        /// <param name="errorMessages">The error messages.</param>
        /// <returns></returns>
        public override bool Execute(RockContext rockContext, WorkflowAction action, Object entity, out List <string> errorMessages)
        {
            errorMessages = new List <string>();

            Guid guid = GetAttributeValue(action, "Activity").AsGuid();

            if (guid.IsEmpty())
            {
                action.AddLogEntry("Invalid Activity Property", true);
                return(false);
            }

            var workflow = action.Activity.Workflow;

            var activityType = new WorkflowActivityTypeService(rockContext).Queryable()
                               .Where(a => a.Guid.Equals(guid)).FirstOrDefault();

            if (activityType == null)
            {
                action.AddLogEntry("Invalid Activity Property", true);
                return(false);
            }

            WorkflowActivity.Activate(activityType, workflow);
            action.AddLogEntry(string.Format("Activated new '{0}' activity", activityType.ToString()));

            return(true);
        }
Exemple #5
0
        private bool activateActivity(RockContext rockContext, WorkflowAction action, string activityAttributeName)
        {
            Guid guid = GetAttributeValue(action, activityAttributeName).AsGuid();

            if (guid.IsEmpty())
            {
                // No activity.  Just be done.
                return(true);
            }

            var workflow = action.Activity.Workflow;

            var activityType = new WorkflowActivityTypeService(rockContext).Queryable()
                               .Where(a => a.Guid.Equals(guid)).FirstOrDefault();

            if (activityType == null)
            {
                action.AddLogEntry("Invalid Activity Property", true);
                return(false);
            }

            WorkflowActivity.Activate(activityType, workflow);
            action.AddLogEntry(string.Format("Activated new '{0}' activity", activityType.ToString()));

            return(true);
        }
        /// <summary>
        /// Gets the edit value as the IEntity.Id
        /// </summary>
        /// <param name="control">The control.</param>
        /// <param name="configurationValues">The configuration values.</param>
        /// <returns></returns>
        public int?GetEditValueAsEntityId(Control control, Dictionary <string, ConfigurationValue> configurationValues)
        {
            var guid = GetEditValue(control, configurationValues).AsGuid();
            var item = new WorkflowActivityTypeService(new RockContext()).Get(guid);

            return(item != null ? item.Id : ( int? )null);
        }
Exemple #7
0
        private static int LoadByGuid2(Guid guid, RockContext rockContext)
        {
            var workflowActivityTypeService = new WorkflowActivityTypeService(rockContext);

            return(workflowActivityTypeService
                   .Queryable().AsNoTracking()
                   .Where(c => c.Guid.Equals(guid))
                   .Select(c => c.Id)
                   .FirstOrDefault());
        }
Exemple #8
0
 protected WorkflowImport()
 {
     rockContext                 = new RockContext();
     arenaContext                = new ArenaDataContext();
     workflowService             = new WorkflowService(rockContext);
     workflowActivityService     = new WorkflowActivityService(rockContext);
     workflowActivityTypeService = new WorkflowActivityTypeService(rockContext);
     workflowActionService       = new WorkflowActionService(rockContext);
     definedValueService         = new DefinedValueService(rockContext);
     personAliasService          = new PersonAliasService(rockContext);
 }
Exemple #9
0
        /// <summary>
        /// Executes the specified workflow.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="action">The action.</param>
        /// <param name="entity">The entity.</param>
        /// <param name="errorMessages">The error messages.</param>
        /// <returns></returns>
        public override bool Execute(RockContext rockContext, WorkflowAction action, Object entity, out List <string> errorMessages)
        {
            errorMessages = new List <string>();

            var workflowActivityGuid = action.GetWorklowAttributeValue(GetAttributeValue(action, "Activity").AsGuid()).AsGuid();

            if (workflowActivityGuid.IsEmpty())
            {
                action.AddLogEntry("Invalid Activity Property", true);
                return(false);
            }

            var attributeKey   = GetAttributeValue(action, "WorkflowAttributeKey", true);
            var attributeValue = GetAttributeValue(action, "WorkflowAttributeValue", true);

            if (string.IsNullOrWhiteSpace(attributeKey) || string.IsNullOrWhiteSpace(attributeValue))
            {
                action.AddLogEntry("Invalid Workflow Property", true);
                return(false);
            }

            var activityType = new WorkflowActivityTypeService(rockContext).Queryable()
                               .Where(a => a.Guid.Equals(workflowActivityGuid)).FirstOrDefault();

            if (activityType == null)
            {
                action.AddLogEntry("Invalid Activity Property", true);
                return(false);
            }

            var entityType = EntityTypeCache.Read(typeof(Rock.Model.Workflow));

            var workflowIds = new AttributeValueService(rockContext)
                              .Queryable()
                              .AsNoTracking()
                              .Where(a => a.Attribute.Key == attributeKey && a.Value == attributeValue && a.Attribute.EntityTypeId == entityType.Id)
                              .Select(a => a.EntityId);

            var workflows = new WorkflowService(rockContext)
                            .Queryable()
                            //.AsNoTracking()
                            .Where(w => w.WorkflowType.ActivityTypes.Any(a => a.Guid == activityType.Guid) && workflowIds.Contains(w.Id))
                            .ToList();

            foreach (var workflow in workflows)
            {
                WorkflowActivity.Activate(activityType, workflow);
                action.AddLogEntry(string.Format("Activated new '{0}' activity in {1} {2}", activityType.ToString(), workflow.TypeName, workflow.WorkflowId));
            }


            return(true);
        }
Exemple #10
0
        /// <summary>
        /// Executes the specified workflow.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="action">The action.</param>
        /// <param name="entity">The entity.</param>
        /// <param name="errorMessages">The error messages.</param>
        /// <returns></returns>
        public override bool Execute(RockContext rockContext, WorkflowAction action, Object entity, out List <string> errorMessages)
        {
            errorMessages = new List <string>();

            var workflowActivityGuid = action.GetWorklowAttributeValue(GetAttributeValue(action, "Activity").AsGuid()).AsGuid();

            if (workflowActivityGuid.IsEmpty())
            {
                action.AddLogEntry("Invalid Activity Property", true);
                return(false);
            }

            var reference = GetAttributeValue(action, "WorkflowReference", true);

            Rock.Model.Workflow workflow = null;
            if (reference.AsGuidOrNull() != null)
            {
                var referenceGuid = reference.AsGuid();
                workflow = new WorkflowService(rockContext).Queryable()
                           .Where(w => w.Guid == referenceGuid)
                           .FirstOrDefault();
            }
            else if (reference.AsIntegerOrNull() != null)
            {
                var referenceInt = reference.AsInteger();
                workflow = new WorkflowService(rockContext).Queryable()
                           .Where(w => w.Id == referenceInt)
                           .FirstOrDefault();
            }
            else
            {
                action.AddLogEntry("Invalid Workflow Property", true);
                return(false);
            }

            var activityType = new WorkflowActivityTypeService(rockContext).Queryable()
                               .Where(a => a.Guid.Equals(workflowActivityGuid)).FirstOrDefault();

            if (activityType == null)
            {
                action.AddLogEntry("Invalid Activity Property", true);
                return(false);
            }

            WorkflowActivity.Activate(activityType, workflow);
            action.AddLogEntry(string.Format("Activated new '{0}' activity", activityType.ToString()));

            return(true);
        }
Exemple #11
0
        private static WorkflowActivityTypeCache LoadById2(int id, RockContext rockContext)
        {
            var workflowActivityTypeService = new WorkflowActivityTypeService(rockContext);
            var workflowActivityTypeModel   = workflowActivityTypeService
                                              .Queryable()
                                              .Where(t => t.Id == id)
                                              .FirstOrDefault();

            if (workflowActivityTypeModel != null)
            {
                return(new WorkflowActivityTypeCache(workflowActivityTypeModel));
            }

            return(null);
        }
Exemple #12
0
        /// <summary>
        /// Restores the view-state information from a previous user control request that was saved by the <see cref="M:System.Web.UI.UserControl.SaveViewState" /> method.
        /// </summary>
        /// <param name="savedState">An <see cref="T:System.Object" /> that represents the user control state to be restored.</param>
        protected override void LoadViewState(object savedState)
        {
            base.LoadViewState(savedState);

            string json = ViewState["Workflow"] as string;

            if (string.IsNullOrWhiteSpace(json))
            {
                Workflow = new Workflow();
            }
            else
            {
                Workflow = JsonConvert.DeserializeObject <Workflow>(json);
            }

            // Wire up type objects since they are not serialized
            var rockContext         = new RockContext();
            var workflowTypeService = new WorkflowTypeService(rockContext);
            var activityTypeService = new WorkflowActivityTypeService(rockContext);
            var actionTypeService   = new WorkflowActionTypeService(rockContext);

            Workflow.WorkflowType = workflowTypeService.Get(Workflow.WorkflowTypeId);
            foreach (var activity in Workflow.Activities)
            {
                activity.ActivityType = activityTypeService.Get(activity.ActivityTypeId);
                foreach (var action in activity.Actions)
                {
                    action.ActionType = actionTypeService.Get(action.ActionTypeId);
                }
            }

            // Add new log entries since they are not serialized
            LogEntries = ViewState["LogEntries"] as List <string>;
            if (LogEntries == null)
            {
                LogEntries = new List <string>();
            }
            LogEntries.ForEach(l => Workflow.AddLogEntry(l));

            ExpandedActivities = ViewState["ExpandedActivities"] as List <Guid>;
            if (ExpandedActivities == null)
            {
                ExpandedActivities = new List <Guid>();
            }

            _canEdit = UserCanEdit || Workflow.IsAuthorized(Rock.Security.Authorization.EDIT, CurrentPerson);
            _canView = _canEdit || (Workflow.IsAuthorized(Authorization.VIEW, CurrentPerson) && Workflow.IsAuthorized("ViewList", CurrentPerson));
        }
        /// <summary>
        /// Creates the control(s) necessary for prompting user for a new value
        /// </summary>
        /// <param name="configurationValues">The configuration values.</param>
        /// <param name="id"></param>
        /// <returns>
        /// The control
        /// </returns>
        public override Control EditControl(Dictionary <string, ConfigurationValue> configurationValues, string id)
        {
            ListControl editControl;

            editControl = new Rock.Web.UI.Controls.RockDropDownList {
                ID = id
            };
            editControl.Items.Add(new ListItem());

            IEnumerable <WorkflowActivityType> activityTypes = null;

            var workflowType = GetContextWorkflowType();

            if (workflowType != null)
            {
                activityTypes = workflowType.ActivityTypes;
            }

            if (activityTypes == null && configurationValues != null && configurationValues.ContainsKey(WORKFLOW_TYPE_KEY))
            {
                Guid workflowTypeGuid = configurationValues[WORKFLOW_TYPE_KEY].Value.AsGuid();
                if (!workflowTypeGuid.IsEmpty())
                {
                    activityTypes = new WorkflowActivityTypeService(new RockContext())
                                    .Queryable()
                                    .Where(t => t.WorkflowType.Guid.Equals(workflowTypeGuid));
                }
            }

            if (activityTypes != null && activityTypes.Any())
            {
                foreach (var activityType in activityTypes.OrderBy(a => a.Order))
                {
                    editControl.Items.Add(new ListItem(activityType.Name ?? "[New Activity]", activityType.Guid.ToString().ToUpper()));
                }
            }

            return(editControl);
        }
        /// <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)
        {
            WorkflowType        workflowType;
            WorkflowTypeService service = new WorkflowTypeService();

            int workflowTypeId = int.Parse(hfWorkflowTypeId.Value);

            if (workflowTypeId == 0)
            {
                workflowType          = new WorkflowType();
                workflowType.IsSystem = false;
                workflowType.Name     = string.Empty;
            }
            else
            {
                workflowType = service.Get(workflowTypeId);
            }

            workflowType.Name        = tbName.Text;
            workflowType.Description = tbDescription.Text;
            workflowType.CategoryId  = cpCategory.SelectedValueAsInt();
            workflowType.Order       = int.Parse(tbOrder.Text);
            workflowType.WorkTerm    = tbWorkTerm.Text;
            if (!string.IsNullOrWhiteSpace(tbProcessingInterval.Text))
            {
                workflowType.ProcessingIntervalSeconds = int.Parse(tbProcessingInterval.Text);
            }

            workflowType.IsPersisted  = cbIsPersisted.Checked;
            workflowType.LoggingLevel = ddlLoggingLevel.SelectedValueAsEnum <WorkflowLoggingLevel>();
            workflowType.IsActive     = cbIsActive.Checked;

            if (!Page.IsValid)
            {
                return;
            }

            if (!workflowType.IsValid)
            {
                // Controls will render the error messages
                return;
            }

            RockTransactionScope.WrapTransaction(() =>
            {
                List <WorkflowActivityTypeEditor> workflowActivityTypeEditorList = phActivities.Controls.OfType <WorkflowActivityTypeEditor>().ToList();

                // delete WorkflowActionTypes that aren't assigned in the UI anymore
                WorkflowActionTypeService workflowActionTypeService = new WorkflowActionTypeService();
                List <WorkflowActionType> actionTypesInDB           = workflowActionTypeService.Queryable().Where(a => a.ActivityType.WorkflowTypeId.Equals(workflowType.Id)).ToList();
                List <WorkflowActionType> actionTypesInUI           = new List <WorkflowActionType>();
                foreach (WorkflowActivityTypeEditor workflowActivityTypeEditor in workflowActivityTypeEditorList)
                {
                    foreach (WorkflowActionTypeEditor editor in workflowActivityTypeEditor.Controls.OfType <WorkflowActionTypeEditor>())
                    {
                        actionTypesInUI.Add(editor.WorkflowActionType);
                    }
                }

                var deletedActionTypes = from actionType in actionTypesInDB
                                         where !actionTypesInUI.Select(u => u.Guid).Contains(actionType.Guid)
                                         select actionType;

                deletedActionTypes.ToList().ForEach(actionType =>
                {
                    workflowActionTypeService.Delete(actionType, CurrentPersonId);
                    workflowActionTypeService.Save(actionType, CurrentPersonId);
                });

                // delete WorkflowActivityTypes that aren't assigned in the UI anymore
                WorkflowActivityTypeService workflowActivityTypeService = new WorkflowActivityTypeService();
                List <WorkflowActivityType> activityTypesInDB           = workflowActivityTypeService.Queryable().Where(a => a.WorkflowTypeId.Equals(workflowType.Id)).ToList();
                List <WorkflowActivityType> activityTypesInUI           = workflowActivityTypeEditorList.Select(a => a.GetWorkflowActivityType()).ToList();

                var deletedActivityTypes = from activityType in activityTypesInDB
                                           where !activityTypesInUI.Select(u => u.Guid).Contains(activityType.Guid)
                                           select activityType;

                deletedActivityTypes.ToList().ForEach(activityType =>
                {
                    workflowActivityTypeService.Delete(activityType, CurrentPersonId);
                    workflowActivityTypeService.Save(activityType, CurrentPersonId);
                });

                // add or update WorkflowActivityTypes(and Actions) that are assigned in the UI
                int workflowActivityTypeOrder = 0;
                foreach (WorkflowActivityTypeEditor workflowActivityTypeEditor in workflowActivityTypeEditorList)
                {
                    WorkflowActivityType editorWorkflowActivityType = workflowActivityTypeEditor.GetWorkflowActivityType();
                    WorkflowActivityType workflowActivityType       = workflowType.ActivityTypes.FirstOrDefault(a => a.Guid.Equals(editorWorkflowActivityType.Guid));

                    if (workflowActivityType == null)
                    {
                        workflowActivityType = editorWorkflowActivityType;
                        workflowType.ActivityTypes.Add(workflowActivityType);
                    }
                    else
                    {
                        workflowActivityType.Name                    = editorWorkflowActivityType.Name;
                        workflowActivityType.Description             = editorWorkflowActivityType.Description;
                        workflowActivityType.IsActive                = editorWorkflowActivityType.IsActive;
                        workflowActivityType.IsActivatedWithWorkflow = editorWorkflowActivityType.IsActivatedWithWorkflow;
                    }

                    workflowActivityType.Order = workflowActivityTypeOrder++;

                    int workflowActionTypeOrder = 0;
                    foreach (WorkflowActionTypeEditor workflowActionTypeEditor in workflowActivityTypeEditor.Controls.OfType <WorkflowActionTypeEditor>())
                    {
                        WorkflowActionType editorWorkflowActionType = workflowActionTypeEditor.WorkflowActionType;
                        WorkflowActionType workflowActionType       = workflowActivityType.ActionTypes.FirstOrDefault(a => a.Guid.Equals(editorWorkflowActionType.Guid));
                        if (workflowActionType == null)
                        {
                            workflowActionType = editorWorkflowActionType;
                            workflowActivityType.ActionTypes.Add(workflowActionType);
                        }
                        else
                        {
                            workflowActionType.Name         = editorWorkflowActionType.Name;
                            workflowActionType.EntityTypeId = editorWorkflowActionType.EntityTypeId;
                            workflowActionType.IsActionCompletedOnSuccess   = editorWorkflowActionType.IsActionCompletedOnSuccess;
                            workflowActionType.IsActivityCompletedOnSuccess = editorWorkflowActionType.IsActivityCompletedOnSuccess;
                            workflowActionType.Attributes      = editorWorkflowActionType.Attributes;
                            workflowActionType.AttributeValues = editorWorkflowActionType.AttributeValues;
                        }


                        workflowActionType.Order = workflowActionTypeOrder++;
                    }
                }

                if (workflowType.Id.Equals(0))
                {
                    service.Add(workflowType, CurrentPersonId);
                }

                service.Save(workflowType, CurrentPersonId);

                foreach (var activityType in workflowType.ActivityTypes)
                {
                    foreach (var workflowActionType in activityType.ActionTypes)
                    {
                        Rock.Attribute.Helper.SaveAttributeValues(workflowActionType, CurrentPersonId);
                    }
                }
            });

            var qryParams = new Dictionary <string, string>();

            qryParams["workflowTypeId"] = workflowType.Id.ToString();
            NavigateToPage(RockPage.Guid, qryParams);
        }
Exemple #15
0
        /// <summary>
        /// Executes the specified workflow.
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="action">The action.</param>
        /// <param name="entity">The entity.</param>
        /// <param name="errorMessages">The error messages.</param>
        /// <returns></returns>
        public override bool Execute(RockContext rockContext, WorkflowAction action, Object entity, out List <string> errorMessages)
        {
            errorMessages = new List <string>();

            double hoursElapsed = HoursElapsed(action);
            string emailStatus  = EmailStatus(action);

            if (hoursElapsed <= 0)
            {
                SendEmail(rockContext, action);
            }
            else
            {
                var timedOut = false;

                var activityTypeService = new WorkflowActivityTypeService(rockContext);

                WorkflowActivityType unopenedActivityType = null;
                int? unopenedTimeout = null;
                Guid?guid            = GetAttributeValue(action, "UnopenedTimeoutActivity").AsGuidOrNull();
                if (guid.HasValue)
                {
                    unopenedActivityType = activityTypeService.Queryable().Where(a => a.Guid.Equals(guid.Value)).FirstOrDefault();
                    unopenedTimeout      = GetAttributeValue(action, "UnopenedTimeoutLength").AsIntegerOrNull();

                    if (emailStatus != OPENED_STATUS &&
                        emailStatus != CLICKED_STATUS &&
                        unopenedActivityType != null &&
                        unopenedTimeout.HasValue &&
                        unopenedTimeout.Value < hoursElapsed)
                    {
                        action.AddLogEntry("Unopened Timeout Occurred", true);
                        WorkflowActivity.Activate(unopenedActivityType, action.Activity.Workflow, rockContext);
                        timedOut = true;
                    }
                }

                WorkflowActivityType noActionActivityType = null;
                int?noActionTimeout = null;
                guid = GetAttributeValue(action, "NoActionTimeoutActivity").AsGuidOrNull();
                if (guid.HasValue)
                {
                    noActionActivityType = activityTypeService.Queryable().Where(a => a.Guid.Equals(guid.Value)).FirstOrDefault();
                    noActionTimeout      = GetAttributeValue(action, "NoActionTimeoutLength").AsIntegerOrNull();

                    if (emailStatus != CLICKED_STATUS &&
                        noActionActivityType != null &&
                        noActionTimeout.HasValue &&
                        noActionTimeout.Value < hoursElapsed)
                    {
                        action.AddLogEntry("No Action Timeout Occurred", true);
                        WorkflowActivity.Activate(noActionActivityType, action.Activity.Workflow, rockContext);
                        timedOut = true;
                    }
                }

                if (timedOut)
                {
                    UpdateEmailStatus(action.Guid, TIMEOUT_STATUS, string.Empty, rockContext, false);
                    return(true);
                }
            }

            return(false);
        }
Exemple #16
0
        /// <summary>
        /// Updates the email status.
        /// </summary>
        /// <param name="actionGuid">The action unique identifier.</param>
        /// <param name="status">The status.</param>
        /// <param name="emailEventType">Type of the email event.</param>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="ProcessWorkflow">if set to <c>true</c> [process workflow].</param>
        public static void UpdateEmailStatus(Guid actionGuid, string status, string emailEventType, RockContext rockContext, bool ProcessWorkflow)
        {
            var action = new WorkflowActionService(rockContext).Get(actionGuid);

            if (action != null && action.Activity != null)
            {
                string attrKey = action.ActionType.Guid.ToString() + "_EmailStatus";

                action.Activity.LoadAttributes(rockContext);
                string currentStatus = action.Activity.GetAttributeValue(attrKey);

                // Sometimes Clicked events are reported before opens. If this is the case, do not update the status from clicked to opened.
                bool updateStatus = true;
                if (status == OPENED_STATUS && currentStatus == CLICKED_STATUS)
                {
                    updateStatus = false;
                }

                if (!string.IsNullOrWhiteSpace(emailEventType) && (emailEventType != status || !updateStatus))
                {
                    action.AddLogEntry(string.Format("Email Event Type: {0}", emailEventType), true);
                }

                if (updateStatus)
                {
                    action.Activity.SetAttributeValue(attrKey, status);
                    action.Activity.SaveAttributeValues(rockContext);
                    action.AddLogEntry(string.Format("Email Status Updated to '{0}'", status), true);
                }

                Guid?activityGuid = null;
                switch (status)
                {
                case OPENED_STATUS:
                {
                    activityGuid = GetActionAttributeValue(action, "OnOpenActivity").AsGuid();
                    break;
                }

                case CLICKED_STATUS:
                {
                    activityGuid = GetActionAttributeValue(action, "OnClickedActivity").AsGuid();
                    break;
                }

                case FAILED_STATUS:
                {
                    activityGuid = GetActionAttributeValue(action, "OnFailedActivity").AsGuid();
                    break;
                }
                }

                if (activityGuid.HasValue)
                {
                    var workflow     = action.Activity.Workflow;
                    var activityType = new WorkflowActivityTypeService(rockContext).Queryable()
                                       .Where(a => a.Guid.Equals(activityGuid.Value)).FirstOrDefault();
                    if (workflow != null && activityType != null)
                    {
                        WorkflowActivity.Activate(activityType, workflow);
                        action.AddLogEntry(string.Format("Activated new '{0}' activity", activityType.ToString()));

                        if (ProcessWorkflow)
                        {
                            List <string> workflowErrors;
                            new WorkflowService(rockContext).Process(workflow, out workflowErrors);
                        }
                    }
                }
            }
        }