A workflow is the method of automating actions based on events. A chain of events can be set up leading from a start to an end action with each event waiting for a trigger in the chain before being activated, all under the whatchful eye of the workflow runtime. Workflows are commonly used in many different areas, for instance in content publishing procedures and in online e-commerce business processes.
In EPiServer Commerce, workflows are used for validation and calculating totals in the checkout process, and there are several default workflows included (BusinessLayer/OrderSystem/OrderWorkflow project). Checkout activities like calculating cart totals, updating inventory, and processing payments are handled outside of the core API using Windows Workflow Foundation (WF) 3.5 workflows shipped with the .NET Framework.
Each workflow contains a number of activities, each with a distinct purpose such as calculating discounts, and the activities may be re-used among workflows. This division allows for greater flexibility and easier business rules management. If you want to change the business rules associated with checkout, EPiServer Commerce allows you to incorporate your own workflows. Refer to Customizing Order Processing Workflows for more information.
Classes referred to here are available in the following namespaces:
Key files and controls
Calculates shopping cart totals, including discounts, and validates if a product is available. This workflow is executed every time the cart view page is loaded. It is called in the CartViewModule.ascx control, which renders the cart. It uses the following activities, in order:
- RemoveDiscountsActivity - discounts are removed so that pre-discount totals can be calculated in the next step
- CalculateTotalsActivity - this second calculation of totals includes discounts
Associates line items with shipments in the OrderForm object (allows split shipment), calculates shipment prices, tax totals, order total. Shipments require custom shipping provider, the workflow uses the interfaces that your shipment and tax providers will implement. This workflow is executed just prior to completing the order. It performs all of the calculations necessary to ensure the cart includes all relevant discounts and ancillary costs such as taxes and shipping charges. It uses the following activities, in order:
- RemoveDiscountsActivity - discounts are removed so that pre-discount and pre-tax totals can be calculated in the next step
- CalculateTotalsActivity - this second calculation of totals includes discounts and taxes
Validates order total, process payment (again, requires custom payment provider). This workflow is executed upon submission of the cart for processing. It uses the following activities, in order:
- AdjustInventoryActivity - If Inventory tracking is enabled, will adjust SKU inventory after purchase.
- CalculateDiscountsActivity - Calculates the discounts associated with each lineitem, shipment discounts, and order discounts. Discounts are saved in line item Discounts, Shipment's Discounts collection, and OrderForm Discounts collection.
- CalculateTaxActivity - Calculates tax associated with order. For more information on this, see the Taxes section.
- CalculateTotalsActivity - Calculates total for cart based on lineitem price, quantity of each lineitem, shipping totals, handling totals, and taxes. OrderForm, Cart, and lineitem properties regarding totals are updated.
- CheckInventoryActivity - If inventory tracking is enabled, determines whether sufficient stock is on hand for each lineitem. If not, quantities of SKUs greater than stock are removed and warnings returned to indicate the cart change.
- ProcessHandlingActivity - No implementation is included.
- ProcessPaymentActivity - Calls the ProcessPayment method associated with the payment providers associated with the cart.
- ProcessShipmentsActivity - Determines the shipping rates associated with an order by calling the GetRate method associated with each Shipment of line items in a Cart.
- RecordPromotionUsageActivity - Saves promotion usage data to the PromotionUsage table, where its used to track each promotion entry for enforcement of promotion redemption limits.
- RemoveDiscountsActivity - Empties the discount collections associated with LineItem, Shipment, and OrderForm instances.
- ShipmentSplitActivity - Associates items in cart with the shipments they've been added to previously. List of items in each Shipment are stored in LineItemIndexes field.
- ValidateLineItemsActivity - Transfers catalog entry inventory properties to each LineItem, returns an error message if the price for a lineitem has changed. returns an error message if the quantity of a LineItem is reduced due to an inventory shortage, and removes SKUs (with an error message returned) that are no longer active or are members of inactive catalogs.
How it works
- Workflows are executed using the CartHelper.RunWorkflow() method.
- Errors from workflow activities can be of numerous types. A common way to handle the exceptions is to wrap a Try/Catch around the RunWorkflow method, and then use the ErrorManager GenerateError() method to publish the event to any listeners attached to the ErrorManagers Error event.
- An example of this is the ErrorModule control (located in the FrontEnd/_cmsctls/Base/Controls/Common folder), which attaches to the Error event of the ErrorManager class and then renders the errors to the user.
- The ErrorModule is associated with page templates included out-of-the box, and can be used for any purpose. Out-of-the box, it is only used to render errors relating to the checkout process and CMS Editor issues.
- If you want your own workflows, you will want to create your own workflows and activities in your own project. Workflows are configured to work with EPiServer Commerce in the <Workflow> section of the web.config file. Refer to Customizing Order Processing Workflow for more information.
- Controls to look at for examples: Templates/Everything/BusinessControls/CheckoutControls/CartView.ascx and Templates/Everything/BusinessControls/CheckoutControls/CheckoutWizardModule.ascx