• Blog
  • Designing a Workflow Engine for nopCommerce CMS Part 5: Activities

Designing a Workflow Engine for nopCommerce CMS Part 5: Activities

  • 1:40:18 PM
  • Sunday, October 22, 2017

This is Part 5 of a seven-part series describing how to implement Workflow Engine for nopCommerce CMS. Click here for Part 1
In previous post, we showed what Customers can do to Entities, and this post we will show what happens to the Customers as a result.

Activities

Activities are things that can happen as a result of a request Entity entering a State or following a Transition.
For example, let's see the diagram from Part 1 again.



In Step 3 of this flowchart, we may want to create notifications and send message to all subscribers according to their preferences on a request, so that they will receive automatic emails about new product request. However, if the Store Owner denies the request we will want to notify the Buyer, but if Store Owner approves the request we need to notify the Buyer and all subscribers.
In other words, in this example adding notification is an activity that we want to happen when an entity reaches a certain state, and sending email is an activity that we want to happen when a certain transition is followed. We need to design for both scenarios.
First, we need to know what kinds of activity we can do. This model is just like Action model. Here's the design for the Activity model:


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

We'll use the following activities:

  • Send Email: Specifies that we should send an email to one or more recipients.
    
    namespace DevPartner.Nop.Plugin.Core.Services.Activities
    {
        /// 
        /// Send Email: Specifies that we should send an email to one or more recipients.
        /// 
        [SystemName("SendEmail")]
        public class SendEmailActivity : IActivity
        {
            public void Execute(object msg)
            {
                throw new NotImplementedException();
            }
        }
    }
                
  • Create product: Specifies that we should convert entity to nopCommerce product.
  • Create notifications: Specifies that we should create notifications to subscribers according to their subscriptions preferences.

You could define quite a few more kinds of Activities, but for now we'll just use those three.

State and Transition Activities

Once we've got the base Activity defined, we can start designing how the Activities are associated to States and Transitions. As a reminder, we want to be able to kick off Activities in two situations:

  • When the Entity enters a State
  • When the Entity follows a Transition

This means that we still need to associate Activities with States and Transitions, So let’s add Activity field to the Transition and State 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; }
        [DataSource("System/Workflow/Activity")]
        [EditorTemplate("SuggestionList")]
        public int? Activity { get; set; }
        [DPParent]
        public WorkflowModel Parent { get; set; }
    }
}
namespace DevPartner.Nop.Plugin.Core.Models.Workflow
{
    [SystemName("State")]
    public class StateModel : DPModel
    {
        [AttExtRefType("StateType")]
        [Required]
        [ShowOnListPage]
        [EditorTemplate("DropdownList")]
        public int StateType { get; set; }
        [DataSource("System/Workflow/Activity")]
        [EditorTemplate("SuggestionList")]
        public int? Activity { get; set; }
        [DPParent]
        public WorkflowModel Parent { get; set; }
    }
}
What did we accomplish?

In this post, we demonstrated what kinds of Activities can be kicked off by certain States or Transitions.
We still have a piece of all this missing, though: exactly who can actually perform the Transitions? We'll answer that question in the next post, Part 6 of this series, where we will discuss Security.