Five New Optimizely Certifications are Here! Validate your expertise and advance your career with our latest certification exams. Click here to find out more
Five New Optimizely Certifications are Here! Validate your expertise and advance your career with our latest certification exams. Click here to find out more
This document provides an introduction to the customization of workflows. In order to replace or customize an existing workflow, the basic steps you need to perform are:
Classes referred to here are available in the following namespaces:
Workflow configuration is found in \Configs\ecf.workflow.config. This is the default content of ecf.workflow.config:
<?xml version="1.0"?>
<Workflow>
<Workflows>
<add name="CartValidate" displayname="Validate Cart" description="Checks inventory, populates extra fields" type="Mediachase.Commerce.Workflow.CartValidateWorkflow, Mediachase.Commerce.Workflow" xomlpath="" rulespath=""/>
<add name="CartPrepare" displayname="Cart Prepare" description="Creates shipments" type="Mediachase.Commerce.Workflow.CartPrepareWorkflow, Mediachase.Commerce.Workflow" xomlpath="" rulespath=""/>
<add name="CartCheckout" displayname="Cart Checkout" description="Processes credit card information" type="Mediachase.Commerce.Workflow.CartCheckoutWorkflow, Mediachase.Commerce.Workflow" xomlpath="" rulespath=""/>
<\!-\- Administration Workflowsmapped totoolbar actionsadd name="cmdPurchaseOrderCalculateTotals" displayname="Calculate Totals" description="Calculates totals" type="Mediachase.Commerce.Workflow.Admin.POCalculateTotalsWorkflow, Mediachase.Commerce.Workflow" xomlpath="" rulespath=""/>
<add name="cmdPurchaseOrderProcessPayment" displayname="Process Payment" description="Process Payment" type="Mediachase.Commerce.Workflow.Admin.POProcessPaymentWorkflow, Mediachase.Commerce.Workflow" xomlpath="" rulespath=""/>
</Workflows>
</Workflow>
In the following example, we create a new workflow activity and then utilize it in a new workflow. We then use this workflow to replace the shipped CartCheckout workflow. The new activity sends an automated email to store customers after an order completion. The main aim of this example is to illustrate how a workflow can be updated and customized.
Here we shall add the activity (created above) along with other activities contained in the Mediachase.Commerce.Workflow.Activities.dll in a new workflow. We will then use this workflow to replace the CartCheckout workflow (Mediachase.Commerce.Workflow.CartCheckoutWorkflow).
Example: the starting code for the SendNotification activity
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Threading;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using Mediachase.Commerce.Orders;
using Mediachase.Commerce.Catalog;
using Mediachase.Commerce.Catalog.Dto;
using Mediachase.Commerce.Orders.Managers;
using Mediachase.Commerce.Catalog.Managers;
namespace CustomActivity
{
public partial class SendNotification: Activity
{
public static DependencyProperty OrderGroupProperty = DependencyProperty.Register("OrderGroup", typeof(OrderGroup), typeof(SendNotification));
/// <summary>
/// Gets or sets the order group.
/// </summary>
/// <value>The order group.</value>
[ValidationOption(ValidationOption.Required)]
[BrowsableAttribute(true)]
public OrderGroup OrderGroup
{
get
{
return (OrderGroup)(base.GetValue(SendNotification.OrderGroupProperty));
}
set
{
base.SetValue(SendNotification.OrderGroupProperty, value);
}
}
/// <summary>
/// Initializes a new instance of the <see cref="CalculateTaxActivity"/> class.
/// </summary>
public SendNotification()
{
InitializeComponent();
}
/// <summary>
/// Called by the workflow runtime to execute an activity.
/// </summary>
/// <param name="executionContext">The <see cref="T:System.Workflow.ComponentModel.ActivityExecutionContext"/> to associate with this <see cref="T:System.Workflow.ComponentModel.Activity"/> and execution.</param>
/// <returns>
/// The <see cref="T:System.Workflow.ComponentModel.ActivityExecutionStatus"/> of the run task, which determines whether the activity remains in the executing state, or transitions to the closed state.
/// </returns>
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
try
{
// Validate the properties at runtime
this.ValidateRuntime();
//Send notification
this.SendEmailNotification();
// Retun the closed status indicating that this activity is complete.
return ActivityExecutionStatus.Closed;
}
catch
{
// An unhandled exception occured. Throw it back to the WorkflowRuntime.
throw;
}
}
/// <summary>
/// Calculates the sale taxes.
/// </summary>
private void SendEmailNotification()
{
//provide implementation here
}
/// <summary>
/// Validates the runtime.
/// </summary>
/// <returns></returns>
private bool ValidateRuntime()
{
// Create a new collection for storing the validation errors
ValidationErrorCollection validationErrors = new ValidationErrorCollection();
// Validate the Order Properties
this.ValidateOrderProperties(validationErrors);
// Raise an exception if we have ValidationErrors
if (validationErrors.HasErrors)
{
string validationErrorsMessage = String.Empty;
foreach (ValidationError error in validationErrors)
{
validationErrorsMessage +=
string.Format("Validation Error: Number {0} - '{1}' \n",
error.ErrorNumber, error.ErrorText);
}
// Throw a new exception with the validation errors.
throw new WorkflowValidationFailedException(validationErrorsMessage, validationErrors);
}
// If we made it this far, then the data must be valid.
return true;
}
private void ValidateOrderProperties(ValidationErrorCollection validationErrors)
{
// Validate the To property
if (this.OrderGroup == null)
{
ValidationError validationError = ValidationError.GetNotSetValidationError(SendNotification.OrderGroupProperty.Name);
validationErrors.Add(validationError);
}
}
}
}
Example: the properties to be added to the workflow .cs file
private OrderGroup _OrderGroup;
/// <summary>
/// Gets or sets the order group.
/// </summary>
/// <value>The order group.</value>
public OrderGroup OrderGroup
{
get
{
return _OrderGroup;
}
set
{
_OrderGroup = value;
}
}
private StringDictionary _Warnings = new StringDictionary();
/// <summary>
/// Gets the warnings.
/// </summary>
/// <value>The warnings.</value>
public StringDictionary Warnings
{
get
{
return _Warnings;
}
}
Last updated: Oct 21, 2014