Software to help you build a better store
SEARCH
November 21, 2006

Update BVC5 Order Status Workflow Task

Previously, I wrote about the Add Order Note workflow task that I use to help test Shipper Service for BVC5. As you might imagine, when I test Shipper Service I end up shipping and then "unshipping" the same order many times. BVC5 will mark the order Complete when it is paid and shipped, but the order remains Complete even after the shipments and payments are deleted. Although this does not affect my testing, I found it distracting. If the order is "unshipped", I'd like the order status to change to something other than Complete.

The order status is changed to Complete by the workflow task called "Mark Completed When Order is Shipped And Paid" which is included with BVC5. This task evaluates the PaymentStatus and the ShippingStatus. If the PaymentStatus is Paid and the ShippingStatus is FullyShipped, then the OrderStatus is set to Complete; otherwise the OrderStatus is not changed.

My version of this task is called "Update Order Status". Like BV's, it evaluates the PaymentStatus and the OrderStatus. And like BV's if the order is paid and shipped, then the OrderStatus is set to Complete. Unlike BV's, the other three combinations are also handled:

Payment Status Shipping Status Resulting Order Status
Not Paid Not Shipped In Process
Paid Not Shipped Customizable (default: In Process)
Not Paid Shipped Customizable (default: In Process)
Paid Shipped Complete

Using the task editor, you can choose the order status you want assigned when either PaymentStatus is Paid or ShippingStatus is FullyShipped, but not both.

Create the Task Processor and Editor

  1. Create a new file in your web site's App_Code directory called UpdateOrderClass.vb. See Listing 1.
  2. Create a new directory in BVModules/OrderTasks/ called "Update Order Status".
  3. Create a new file in "BVModules/OrderTasks/Update Order Status/" called Edit.ascx. See Listing 2.
  4. Create a new file in "BVModules/OrderTasks/Update Order Status/" called Edit.ascx.cs. See Listing 3.
  5. Modify App_Code/TaskLoader.vb to load the "Update Order Status" task. See Partial Listing 4.

Using the Task Processor

  1. Edit the "Shipping Changed" workflow.
  2. Delete the "Mark Completed When Order is Shipped And Paid" task.
  3. Add a new "Update Order Status" task.
  4. Move the "Update Order Status" task so it appears before the "Update Order" task.
  5. Edit the "Update Order Status" settings to assign custom order status codes.

Using Update Order Status as a Model for Your Own Tasks

If you use this task as a model for your own workflow task, there are a couple things you should change:

  1. Change the TaskName function so that it returns a unique name for your task.
  2. Change the TaskId function so that it returns a unique ID for your task. BVC5 uses a Globally Unique Identifier (GUID). There are many web sites that will generate one for you, including http://www.somacon.com/p113.php.
Listing 1. UpdateOrderStatus.vb
Imports BVSoftware.Bvc5.Core
Imports BVSoftware.Bvc5.Core.BusinessRules
Imports BVSoftware.Bvc5.Core.Orders
 
Public Class UpdateOrderStatus
    Inherits OrderTask
 
    Public Overrides Function Clone() As Task
        Return New UpdateOrderStatus
    End Function
 
    Public Overloads Overrides Function Execute(ByVal context As OrderTaskContext) As Boolean
        ' Skip order if it is On Hold
        If String.Compare(context.Order.StatusCode, WebAppSettings.OrderStatusCodeOnHold, True) <> 0 Then
            ' Force calculation of shipping and payment status
            context.Order.CalculateGrandTotalOnly(True, True)
            Dim shippingStatus As OrderShippingStatus = context.Order.ShippingStatus
            Dim paymentStatus As OrderPaymentStatus = context.Order.PaymentStatus
 
            Dim orderStatus As Orders.OrderStatusCode = Nothing
            If (shippingStatus = OrderShippingStatus.FullyShipped) _
                AndAlso (paymentStatus = OrderPaymentStatus.Paid) Then
                ' Paid and shipped
                orderStatus = Orders.OrderStatusCode.FindByBvin(WebAppSettings.OrderStatusCodeComplete)
            ElseIf paymentStatus = OrderPaymentStatus.Paid Then
                ' Paid, not shipped
                orderStatus = Orders.OrderStatusCode.FindByBvin( _
                    Me.SettingsManager.GetSetting("Paid", WebAppSettings.OrderStatusCodeInProcess))
            ElseIf shippingStatus = OrderShippingStatus.FullyShipped Then
                ' Not paid, shipped
                orderStatus = Orders.OrderStatusCode.FindByBvin( _
                    Me.SettingsManager.GetSetting("Shipped", WebAppSettings.OrderStatusCodeInProcess))
            Else
                ' Not paid, not shipped
                orderStatus = Orders.OrderStatusCode.FindByBvin(WebAppSettings.OrderStatusCodeInProcess)
            End If
 
            If orderStatus IsNot Nothing Then
                context.Order.StatusCode = orderStatus.Bvin
                context.Order.StatusName = orderStatus.StatusName
            End If
 
        End If
        Return True
    End Function
 
    Public Overloads Overrides Function Rollback(ByVal context As OrderTaskContext) As Boolean
        Return True
    End Function
 
    Public Overrides Function TaskId() As String
        Return "B5B67924-18D2-43AC-9994-8D17FB73A8CF"
    End Function
 
    Public Overrides Function TaskName() As String
        Return "Update Order Status"
    End Function
 
End Class
Listing 2. Edit.ascx
<%@ Control 
    AutoEventWireup="true" 
    CodeFile="Edit.ascx.cs" 
    Inherits="BVModules_OrderTasks_Update_Order_Status_Edit" 
    Language="C#" 
%>
<table border="0" cellspacing="0" cellpadding="3">
<tr>
    <th>
        Payment Status
    </th>
    <th>
        Shipping Status
    </th>
    <th>
        Order Status
    </th>
</tr>
<tr>
    <td>
        Not Paid
    </td>
    <td>
        Not Shipped
    </td>
    <td class="formfield">
        <asp:Label ID="OrderInProcessField" runat="server" Text="In Process" />
    </td>
</tr>
<tr>
    <td>
        <asp:Label ID="OrderPaidLabel1" runat="server" 
            AssociatedControlID="OrderPaidField" 
            Text="Paid" />
    </td>
    <td>
        <asp:Label ID="OrderPaidLabel2" runat="server" 
            AssociatedControlID="OrderPaidField" 
            Text="Not Shipped" />
    </td>
    <td class="formfield">
        <asp:DropDownList ID="OrderPaidField" runat="server" />
    </td>
</tr>
<tr>
    <td>
        <asp:Label ID="OrderShippedlabel1" runat="server" 
            AssociatedControlID="OrderShippedField" 
            Text="Not Paid" />
    </td>
    <td>
        <asp:Label ID="OrderShippedlabel2" runat="server" 
            AssociatedControlID="OrderShippedField" 
            Text="Shipped" />
    </td>
    <td class="formfield">
        <asp:DropDownList ID="OrderShippedField" runat="server" />
    </td>
</tr>
<tr>
    <td>
        Paid
    </td>
    <td>
        Shipped
    </td>
    <td class="formfield">
        <asp:Label ID="OrderCompleteField" runat="server" Text="Complete" />
    </td>
</tr>
<tr>
    <td class="formlabel">
        <asp:ImageButton ID="btnCancel" runat="server" 
            CausesValidation="false" 
            ImageUrl="~/BVAdmin/Images/Buttons/Cancel.png"
            OnClick="btnCancel_Click" />
    </td>
    <td class="formfield">
        <asp:ImageButton ID="btnSave" runat="server" 
            ImageUrl="~/BVAdmin/Images/Buttons/SaveChanges.png"
            OnClick="btnSave_Click" />
    </td>
</tr>
</table>
Listing 3. Edit.ascx.cs
using System;
 
using BVSoftware.Bvc5.Core;
using BVSoftware.Bvc5.Core.Content;
using BVSoftware.Bvc5.Core.Orders;
 
public partial class BVModules_OrderTasks_Update_Order_Status_Edit : BVModule
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            this.DataBind();
        }
    }
 
    public override void DataBind()
    {
        base.DataBind();
 
        OrderStatusCode statusCode = null;
 
        statusCode = OrderStatusCode.FindByBvin(WebAppSettings.OrderStatusCodeInProcess);
        if (statusCode != null)
        {
            this.OrderInProcessField.Text = statusCode.StatusName;
        }
 
        statusCode = OrderStatusCode.FindByBvin(WebAppSettings.OrderStatusCodeComplete);
        if (statusCode != null)
        {
            this.OrderCompleteField.Text = statusCode.StatusName;
        }
 
        this.OrderPaidField.DataSource = OrderStatusCode.FindAll();
        this.OrderPaidField.DataTextField = "StatusName";
        this.OrderPaidField.DataValueField = "Bvin";
        this.OrderPaidField.DataBind();
        this.OrderPaidField.SelectedValue = 
            this.SettingsManager.GetSetting("Paid", 
            WebAppSettings.OrderStatusCodeInProcess);
 
        this.OrderShippedField.DataSource = OrderStatusCode.FindAll();
        this.OrderShippedField.DataTextField = "StatusName";
        this.OrderShippedField.DataValueField = "Bvin";
        this.OrderShippedField.DataBind();
        this.OrderShippedField.SelectedValue = 
            this.SettingsManager.GetSetting("Shipped", 
            WebAppSettings.OrderStatusCodeInProcess);
    }
 
    protected void btnCancel_Click(object sender, System.Web.UI.ImageClickEventArgs e)
    {
        this.NotifyFinishedEditing();
    }
 
    protected void btnSave_Click(object sender, System.Web.UI.ImageClickEventArgs e)
    {
        this.SaveData();
        this.NotifyFinishedEditing();
    }
 
    private void SaveData()
    {
        this.SettingsManager.SaveSetting("Paid", 
            this.OrderPaidField.SelectedValue,  
            "Structured Solutions", 
            "Order Tasks", 
            "Update Order Status");
 
        this.SettingsManager.SaveSetting("Shipped", 
            this.OrderShippedField.SelectedValue, 
            "Structured Solutions", 
            "Order Tasks", 
            "Update Order Status");
    }
}
Listing 4. Partial TaskLoader.vb
Public Shared Function LoadOrderTasks() As Collection(Of BusinessRules.OrderTask)
    Dim result As New Collection(Of BusinessRules.OrderTask)
    result.Add(New UpdateOrderStatus)

This site looks much better in a browser that supports current web standards, but it is accessible to any browser. Download one now This link is to a third party web site which will open in a new window

Some parts of this site will not work effectively on this older browser.
Please consider updating your browser This link is to a third party web site which will open in a new window

SSL