• Blog
  • Designing a Workflow Engine for nopCommerce CMS Part 4: Actions

Designing a Workflow Engine for nopCommerce CMS Part 4: Actions

  • 1:23:46 PM
  • Sunday, October 22, 2017

This is Part 4 of a seven-part series describing how to implement Workflow Engine for nopCommerce CMS. Click here for Part 1
Having already defined our Workflow Infrastructure, and our StateTypes and Transitions, we can now start to design models for what a User can actually perform to an Entity in this engine.
Let's start by creating Actions.

Actions

Actions are things a user can perform upon an Entity.
Say we've got a request Entity to deliver a new bumper BMW X5 2005, and that Entity includes the shipping address. The person who is in charge of approving new Entity, Store owner, takes a look at the Entity and decides that, yeah, it's a good Entity without ads. He submits an Approval to the Entity, which can cause the Entity to go to the next state. Store owner has submitted an Action.
Now we need the model for the Actions themselves. Actions can be used for different Workflows so our model will look like this:

namespace DevPartner.Nop.Plugin.Core.Models.Workflow
{
    [SystemName("Action")]
    [Parent("System/Workflow/Action")]
    [AdminMenu("DevCommerce/Workflow/Action")]
    public class ActionModel : DPModel
    {
        public string AssemblyType { get; set; }
    }
}

Since we don't want to allow an infinite number of kinds of actions that can be performed, we are going to implement several basic Actions:

  • Approve: The actioner is suggesting that the entity should move to the next state.
    namespace DevPartner.Nop.Plugin.Core.Services.Actions
    {
        /// 
        /// The actioner is suggesting that the entity should move to the next state.
        /// 
        [SystemName("Approve")]
        public class ApproveAction : IAction
        {
            public void Execute(object msg)
            {
                throw new NotImplementedException();
            }
        }
    }
  • Deny: The actioner is suggesting that the entity should move to the previous state.
  • Cancel: The actioner is suggesting that the entity should move to the Cancelled state in the workflow.
  • Restart: The actioner suggesting that the entity be moved back to the Start state in the Workflow.
  • Resolve: The actioner is suggesting that the request be entity all the way to the Completed state.
Transition Actions

Now that we've defined what Actions could ever be performed, we need to get more specific: which Action can be performed for a particular Transition?
The relationship between Transition and Action is many-to-one in our case. So let’s add Action field to the Transition model.

namespace DevPartner.Nop.Plugin.Core.Models.Workflow
{
    [SystemName("Transition")]
    public class TransitionModel : DPModel
    {
        [DataSource("../*[@type='State']")]
        [Required]
        [ShowOnListPage]
        [EditorTemplate("DropDownList")]
        public int FromState { get; set; }
        [DataSource("../*[@type='State']")]
        [Required]
        [ShowOnListPage]
        [EditorTemplate("DropDownList")]
        public int ToState { get; set; }
        [DataSource("System/Workflow/Action")]
        [ShowOnListPage]
        [EditorTemplate("DropdownList")]
        public int? Action { get; set; }
        [DPParent]
        public WorkflowModel Parent { get; set; }
    }
}

In this post, we demonstrated how we can store what Actions can be performed by Customers.
We still have an outstanding problem, though: What should happen each time we go to a new State (or follow a new Transition) for a given Entity? All that and more in the next post, Part 5 of this adventure, which discusses Activities.