예제 #1
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.ActionTypeCache.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 = WorkflowActivityTypeCache.Get(activityGuid.Value);
                    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);
                        }
                    }
                }
            }
        }
예제 #2
0
        protected void btnUpdate_Click(object sender, EventArgs e)
        {
            var         errors      = new List <string>();
            RockContext rockContext = new RockContext();
            var         workflows   = GetWorkflows(rockContext);

            //Get the new attribute values from the repeater
            Dictionary <string, string> attributeUpdates = GetNewAttributeValues();

            if (attributeUpdates.Any())
            {
                var mergeFields = LavaHelper.GetCommonMergeFields(this.RockPage, this.CurrentPerson);
                foreach (var workflow in workflows)
                {
                    //Reuse the mergefields with new workflow
                    mergeFields["Workflow"] = workflow;

                    //We will store the attribute value changes and apply them all at once
                    Dictionary <string, string> toUpdate = new Dictionary <string, string>();
                    foreach (var update in attributeUpdates)
                    {
                        toUpdate[update.Key] = update.Value.ResolveMergeFields(mergeFields);
                        //if (toUpdate[update.Key])
                        //{

                        //}
                    }

                    foreach (var update in toUpdate)
                    {
                        workflow.SetAttributeValue(update.Key, update.Value);
                    }

                    workflow.SaveAttributeValues();
                }
            }

            //Workflow settings

            //Activate the workflows if requested or if a new activity is activated
            if (ddlState.SelectedValue == "NotComplete" || ddlActivities.SelectedValue.IsNotNullOrWhiteSpace())
            {
                foreach (var workflow in workflows)
                {
                    workflow.CompletedDateTime = null;
                }
            }
            else if (ddlState.SelectedValue == "Complete")
            {
                foreach (var workflow in workflows)
                {
                    workflow.MarkComplete();
                }
            }

            //Update Status message
            if (tbStatus.Text.IsNotNullOrWhiteSpace())
            {
                var mergeFields = LavaHelper.GetCommonMergeFields(this.RockPage, this.CurrentPerson);
                foreach (var workflow in workflows)
                {
                    mergeFields["Workflow"] = workflow;
                    workflow.Status         = tbStatus.Text.ResolveMergeFields(mergeFields);
                }
            }

            //Activate New Activity

            int?activityTypeId = ddlActivities.SelectedValueAsId();

            if (activityTypeId.HasValue)
            {
                var activityType = WorkflowActivityTypeCache.Get(activityTypeId.Value);
                if (activityType != null)
                {
                    foreach (var workflow in workflows)
                    {
                        var activity = WorkflowActivity.Activate(activityType, workflow, rockContext);
                        activity.Guid = Guid.NewGuid();

                        foreach (var action in activity.Actions)
                        {
                            action.Guid = Guid.NewGuid();
                        }
                    }
                }
            }
            rockContext.SaveChanges();

            //Process workflows
            List <string> errorMessages = new List <string>();

            if (workflows.Where(w => w.IsActive).Any())
            {
                foreach (var workflow in workflows)
                {
                    WorkflowService workflowService = new WorkflowService(new RockContext());
                    workflowService.Process(workflow, out errorMessages);
                }
            }

            pnlConfirmation.Visible = false;
            pnlDisplay.Visible      = false;
            pnlDone.Visible         = true;
        }
예제 #3
0
        protected void btnReopen_Command(object sender, CommandEventArgs e)
        {
            using (RockContext rockContext = new RockContext())
            {
                WorkflowService workflowService = new WorkflowService(rockContext);
                Workflow        workflow        = workflowService.Get(e.CommandArgument.ToString().AsInteger());
                if (workflow != null && !workflow.IsActive)
                {
                    workflow.Status            = "Active";
                    workflow.CompletedDateTime = null;

                    // Find the summary activity and activate it.
                    WorkflowActivityType workflowActivityType = workflow.WorkflowType.ActivityTypes.Where(at => at.Name.Contains("Summary")).FirstOrDefault();
                    WorkflowActivity     workflowActivity     = WorkflowActivity.Activate(WorkflowActivityTypeCache.Get(workflowActivityType.Id, rockContext), workflow, rockContext);
                }
                rockContext.SaveChanges();
            }
            BindGrid();
        }
예제 #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>();

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

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

                WorkflowActivityTypeCache unopenedActivityType = null;
                int? unopenedTimeout = null;
                Guid?guid            = GetAttributeValue(action, "UnopenedTimeoutActivity").AsGuidOrNull();
                if (guid.HasValue)
                {
                    unopenedActivityType = WorkflowActivityTypeCache.Get(guid.Value);
                    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;
                    }
                }

                WorkflowActivityTypeCache noActionActivityType = null;
                int?noActionTimeout = null;
                guid = GetAttributeValue(action, "NoActionTimeoutActivity").AsGuidOrNull();
                if (guid.HasValue)
                {
                    noActionActivityType = WorkflowActivityTypeCache.Get(guid.Value);
                    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);
        }
 /// <summary>
 /// Updates any Cache Objects that are associated with this entity
 /// </summary>
 /// <param name="entityState">State of the entity.</param>
 /// <param name="dbContext">The database context.</param>
 public void UpdateCache(EntityState entityState, Data.DbContext dbContext)
 {
     WorkflowTypeCache.UpdateCachedEntity(this.WorkflowTypeId, EntityState.Modified);
     WorkflowActivityTypeCache.UpdateCachedEntity(this.Id, entityState);
 }
 /// <summary>
 /// Gets the cache object associated with this Entity
 /// </summary>
 /// <returns></returns>
 public IEntityCache GetCacheObject()
 {
     return(WorkflowActivityTypeCache.Get(this.Id));
 }
예제 #7
0
파일: Attribute.cs 프로젝트: waldo2590/Rock
        /// <summary>
        /// Updates any Cache Objects that are associated with this entity
        /// </summary>
        /// <param name="entityState">State of the entity.</param>
        /// <param name="dbContext">The database context.</param>
        public void UpdateCache(EntityState entityState, Rock.Data.DbContext dbContext)
        {
            AttributeCache.UpdateCachedEntity(this.Id, entityState);
            AttributeCache.UpdateCacheEntityAttributes(this, entityState);

            int?   entityTypeId;
            string entityTypeQualifierColumn;
            string entityTypeQualifierValue;

            if (entityState == EntityState.Deleted)
            {
                entityTypeId = originalEntityTypeId;
                entityTypeQualifierColumn = originalEntityTypeQualifierColumn;
                entityTypeQualifierValue  = originalEntityTypeQualifierValue;
            }
            else
            {
                entityTypeId = this.EntityTypeId;
                entityTypeQualifierColumn = this.EntityTypeQualifierColumn;
                entityTypeQualifierValue  = this.EntityTypeQualifierValue;
            }

            if ((!entityTypeId.HasValue || entityTypeId.Value == 0) && string.IsNullOrEmpty(entityTypeQualifierColumn) && string.IsNullOrEmpty(entityTypeQualifierValue))
            {
                GlobalAttributesCache.Remove();
            }

            if ((!entityTypeId.HasValue || entityTypeId.Value == 0) && entityTypeQualifierColumn == Attribute.SYSTEM_SETTING_QUALIFIER && string.IsNullOrEmpty(entityTypeQualifierValue))
            {
                Rock.Web.SystemSettings.Remove();
            }

            if (entityTypeId.HasValue)
            {
                if (entityTypeId == EntityTypeCache.GetId <Block>())
                {
                    // Update BlockTypes/Blocks that reference this attribute
                    if (entityTypeQualifierColumn.Equals("BlockTypeId", StringComparison.OrdinalIgnoreCase))
                    {
                        int?blockTypeId = entityTypeQualifierValue.AsIntegerOrNull();
                        if (blockTypeId.HasValue)
                        {
                            BlockTypeCache.FlushItem(blockTypeId.Value);

                            foreach (var blockId in new BlockService(dbContext as RockContext).GetByBlockTypeId(blockTypeId.Value).Select(a => a.Id).ToList())
                            {
                                BlockCache.FlushItem(blockId);
                            }
                        }
                    }
                }
                else if (entityTypeId == EntityTypeCache.GetId <DefinedValue>())
                {
                    // Update DefinedTypes/DefinedValues that reference this attribute
                    if (entityTypeQualifierColumn.Equals("DefinedTypeId", StringComparison.OrdinalIgnoreCase))
                    {
                        int?definedTypeId = entityTypeQualifierValue.AsIntegerOrNull();
                        if (definedTypeId.HasValue)
                        {
                            DefinedTypeCache.FlushItem(definedTypeId.Value);

                            foreach (var definedValueId in new DefinedValueService(dbContext as RockContext).GetByDefinedTypeId(definedTypeId.Value).Select(a => a.Id).ToList())
                            {
                                DefinedValueCache.FlushItem(definedValueId);
                            }
                        }
                    }
                }
                else if (entityTypeId == EntityTypeCache.GetId <WorkflowActivityType>())
                {
                    if (entityTypeQualifierColumn.Equals("ActivityTypeId", StringComparison.OrdinalIgnoreCase))
                    {
                        int?activityTypeId = entityTypeQualifierValue.AsIntegerOrNull();
                        if (activityTypeId.HasValue)
                        {
                            WorkflowActivityTypeCache.FlushItem(activityTypeId.Value);
                        }
                    }
                }
                else if (entityTypeId == EntityTypeCache.GetId <GroupType>())
                {
                    if (entityTypeQualifierColumn.Equals("Id", StringComparison.OrdinalIgnoreCase))
                    {
                        int?groupTypeId = entityTypeQualifierValue.AsIntegerOrNull();
                        if (groupTypeId.HasValue)
                        {
                            GroupTypeCache.FlushItem(groupTypeId.Value);
                        }
                    }
                    else if (entityTypeQualifierColumn.Equals("GroupTypePurposeValueId", StringComparison.OrdinalIgnoreCase))
                    {
                        int?groupTypePurposeValueId = entityTypeQualifierValue.AsIntegerOrNull();
                        if (groupTypePurposeValueId.HasValue)
                        {
                            foreach (var groupTypeId in GroupTypeCache.All().Where(a => a.GroupTypePurposeValueId == groupTypePurposeValueId.Value).Select(a => a.Id).ToList())
                            {
                                GroupTypeCache.FlushItem(groupTypeId);
                            }
                        }
                    }
                }
                else if (entityTypeId.HasValue)
                {
                    // some other EntityType. If it the EntityType has a CacheItem associated with it, clear out all the CachedItems of that type to ensure they have a clean read of the Attributes that were Added, Changed or Removed
                    EntityTypeCache entityType = EntityTypeCache.Get(entityTypeId.Value, dbContext as RockContext);

                    if (entityType?.HasEntityCache() == true)
                    {
                        entityType.ClearCachedItems();
                    }
                }
            }
        }
예제 #8
0
        /// <summary>
        /// Renders the specified context.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="result">The result.</param>
        public override void Render(Context context, TextWriter result)
        {
            // first ensure that entity commands are allowed in the context
            if (!this.IsAuthorized(context))
            {
                result.Write(string.Format(RockLavaBlockBase.NotAuthorizedMessage, this.Name));
                base.Render(context, result);
                return;
            }

            var    attributes       = new Dictionary <string, string>();
            string parmWorkflowType = null;
            string parmWorkflowName = null;
            string parmWorkflowId   = null;
            string parmActivityType = null;

            /* Parse the markup text to pull out configuration parameters. */
            var parms = ParseMarkup(_markup, context);

            foreach (var p in parms)
            {
                if (p.Key.ToLower() == "workflowtype")
                {
                    parmWorkflowType = p.Value;
                }
                else if (p.Key.ToLower() == "workflowname")
                {
                    parmWorkflowName = p.Value;
                }
                else if (p.Key.ToLower() == "workflowid")
                {
                    parmWorkflowId = p.Value;
                }
                else if (p.Key.ToLower() == "activitytype")
                {
                    parmActivityType = p.Value;
                }
                else
                {
                    attributes.AddOrReplace(p.Key, p.Value);
                }
            }

            /* Process inside a new stack level so our own created variables do not
             * persist throughout the rest of the workflow. */
            context.Stack(() =>
            {
                using (var rockContext = new RockContext())
                {
                    WorkflowService workflowService = new WorkflowService(rockContext);
                    Rock.Model.Workflow workflow    = null;
                    WorkflowActivity activity       = null;

                    /* They provided a WorkflowType, so we need to kick off a new workflow. */
                    if (parmWorkflowType != null)
                    {
                        string type = parmWorkflowType;
                        string name = parmWorkflowName ?? string.Empty;
                        WorkflowTypeCache workflowType = null;

                        /* Get the type of workflow */
                        if (type.AsGuidOrNull() != null)
                        {
                            workflowType = WorkflowTypeCache.Read(type.AsGuid());
                        }
                        else if (type.AsIntegerOrNull() != null)
                        {
                            workflowType = WorkflowTypeCache.Read(type.AsInteger());
                        }

                        /* Try to activate the workflow */
                        if (workflowType != null)
                        {
                            workflow = Rock.Model.Workflow.Activate(workflowType, parmWorkflowName);

                            /* Set any workflow attributes that were specified. */
                            foreach (var attr in attributes)
                            {
                                if (workflow.Attributes.ContainsKey(attr.Key))
                                {
                                    workflow.SetAttributeValue(attr.Key, attr.Value.ToString());
                                }
                            }

                            if (workflow != null)
                            {
                                List <string> errorMessages;

                                workflowService.Process(workflow, out errorMessages);

                                if (errorMessages.Any())
                                {
                                    context["Error"] = string.Join("; ", errorMessages.ToArray());
                                }

                                context["Workflow"] = workflow;
                            }
                            else
                            {
                                context["Error"] = "Could not activate workflow.";
                            }
                        }
                        else
                        {
                            context["Error"] = "Workflow type not found.";
                        }
                    }

                    /* They instead provided a WorkflowId, so we are working with an existing Workflow. */
                    else if (parmWorkflowId != null)
                    {
                        string id = parmWorkflowId.ToString();

                        /* Get the workflow */
                        if (id.AsGuidOrNull() != null)
                        {
                            workflow = workflowService.Get(id.AsGuid());
                        }
                        else if (id.AsIntegerOrNull() != null)
                        {
                            workflow = workflowService.Get(id.AsInteger());
                        }

                        if (workflow != null)
                        {
                            if (workflow.CompletedDateTime == null)
                            {
                                /* Currently we cannot activate an activity in a workflow that is currently
                                 * being processed. The workflow is held in-memory so the activity we would
                                 * activate would not show up for the processor and probably never run.
                                 */
                                if (!workflow.IsProcessing)
                                {
                                    bool hasError = false;

                                    /* If they provided an ActivityType parameter then we need to activate
                                     * a new activity in the workflow.
                                     */
                                    if (parmActivityType != null)
                                    {
                                        string type = parmActivityType.ToString();
                                        WorkflowActivityTypeCache activityType = null;

                                        /* Get the type of activity */
                                        if (type.AsGuidOrNull() != null)
                                        {
                                            activityType = WorkflowActivityTypeCache.Read(type.AsGuid());
                                        }
                                        else if (type.AsIntegerOrNull() != null)
                                        {
                                            activityType = WorkflowActivityTypeCache.Read(type.AsInteger());
                                        }

                                        if (activityType != null)
                                        {
                                            activity = WorkflowActivity.Activate(activityType, workflow);

                                            /* Set any workflow attributes that were specified. */
                                            foreach (var attr in attributes)
                                            {
                                                if (activity.Attributes.ContainsKey(attr.Key))
                                                {
                                                    activity.SetAttributeValue(attr.Key, attr.Value.ToString());
                                                }
                                            }
                                        }
                                        else
                                        {
                                            context["Error"] = "Activity type was not found.";
                                            hasError         = true;
                                        }
                                    }

                                    /* Process the existing Workflow. */
                                    if (!hasError)
                                    {
                                        List <string> errorMessages;
                                        workflowService.Process(workflow, out errorMessages);

                                        if (errorMessages.Any())
                                        {
                                            context["Error"] = string.Join("; ", errorMessages.ToArray());
                                        }

                                        context["Workflow"] = workflow;
                                        context["Activity"] = activity;
                                    }
                                }
                                else
                                {
                                    context["Error"] = "Cannot activate activity on workflow that is currently being processed.";
                                }
                            }
                            else
                            {
                                context["Error"] = "Workflow has already been completed.";
                            }
                        }
                        else
                        {
                            context["Error"] = "Workflow not found.";
                        }
                    }
                    else
                    {
                        context["Error"] = "Must specify one of WorkflowType or WorkflowId.";
                    }

                    RenderAll(NodeList, context, result);
                }
            });
        }