Take the community feedback survey now.
Take the community feedback survey now.
During checkout, activity flows check remaining item stock quantities and calculate cart totals. Episerver Commerce incorporates a check inventory activity into the activity flows. This activity checks the warehouse inventory when adding or changing a cart item.
Classes in this topic are available in the following namespace:
The CartPrepare activity flow is run prior to rendering the page where the customer confirms the order. This flow performs the following tasks:
The CheckInventoryActivity determines whether cart items are available.
using EPiServer.Commerce.Order;
using Mediachase.Commerce.Orders;
using Mediachase.Commerce.WorkflowCompatibility;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Mediachase.Commerce.Workflow.Activities
{
public class CheckInventoryActivity : OrderGroupActivityBase
{
///
/// Called by the workflow runtime to execute an activity.
///
///The to associate with this and execution.
///
/// The of the run task, which determines whether the activity remains in the executing state, or transitions to the closed state.
///
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
// Validate the properties at runtime
ValidateRuntime();
ValidateItems();
// Retun the closed status indicating that this activity is complete.
return ActivityExecutionStatus.Closed;
}
///
/// Validate inventory in the order group.
///
/// We don't need to validate quantity in the wishlist.
private void ValidateItems()
{
if (string.Equals(OrderGroup.Name, Mediachase.Commerce.Orders.Cart.WishListName, StringComparison.OrdinalIgnoreCase))
{
return;
}
var validationIssues = new Dictionary<ILineItem, IList>();
OrderGroup.UpdateInventoryOrRemoveLineItems((item, issue) => AddValidationIssues(validationIssues, item, issue));
AddWarningMessages(validationIssues);
// Update line item quantity in order form. This logic to support legacy line items
var allLineItemInShipment = OrderGroup.GetAllLineItems();
foreach (var lineItem in OrderGroup.OrderForms.SelectMany(x => x.LineItems))
{
var lineItemsInShipment = allLineItemInShipment.Where(x => x.LineItemId == lineItem.LineItemId);
if (lineItemsInShipment.Any())
{
lineItem.Quantity = lineItemsInShipment.Sum(l => l.Quantity);
}
}
}
}
}
/// Updates the inventory for the or removes the line item if no available inventory.
///
///The order group.
///A callback that is invoked if a validation issue is detected.
///The inventory processor.
public static void UpdateInventoryOrRemoveLineItems(this
IOrderGroup orderGroup,
Action<ILineItem,
ValidationIssue> onValidationError,
IInventoryProcessor inventoryProcessor)
{
foreach (var shipment in orderGroup.Forms.SelectMany(form => form.Shipments))
{
inventoryProcessor.UpdateInventoryOrRemoveLineItem(shipment, onValidationError);
}
}
protected void AddWarningMessages(IDictionary<ILineItem, IList> validationIssueCollections)
{
foreach (var validationIssue in validationIssueCollections)
{
var lineItemCode = validationIssue.Key.Code;
foreach (var issue in validationIssue.Value)
{
switch (issue)
{
case ValidationIssue.None:
break;
case ValidationIssue.RemovedGiftDueToInsufficientQuantityInInventory:
AddWarningSafe(Warnings,
ValidationIssue.RemovedGiftDueToInsufficientQuantityInInventory.ToString(),
$"The gift {lineItemCode} has not enough quantity in stock and was removed from your cart.");
break;
case ValidationIssue.CannotProcessDueToMissingOrderStatus:
AddWarningSafe(Warnings,
ValidationIssue.CannotProcessDueToMissingOrderStatus.ToString(),
$"Cannot process product {lineItemCode} because of missing order status.");
break;
case ValidationIssue.RemovedDueToCodeMissing:
AddWarningSafe(Warnings,
ValidationIssue.RemovedDueToCodeMissing.ToString(),
$"The product {lineItemCode} was removed from your cart because the catalog entry code that maps to the line item has been removed or changed.");
break;
case ValidationIssue.RemovedDueToNotAvailableInMarket:
AddWarningSafe(Warnings,
ValidationIssue.RemovedDueToNotAvailableInMarket.ToString(),
$"The product {lineItemCode} was removed from your cart because it is not available in your market..");
break;
case ValidationIssue.RemovedDueToInactiveWarehouse:
AddWarningSafe(Warnings,
ValidationIssue.RemovedDueToInactiveWarehouse.ToString(),
$"The product {lineItemCode} was removed from your cart because the selected warehouse is inactive.");
break;
case ValidationIssue.RemovedDueToMissingInventoryInformation:
AddWarningSafe(Warnings,
ValidationIssue.RemovedDueToMissingInventoryInformation.ToString(),
$"The product {lineItemCode} was removed from your cart due to missing inventory information.");
break;
case ValidationIssue.RemovedDueToUnavailableCatalog:
AddWarningSafe(Warnings,
ValidationIssue.RemovedDueToUnavailableCatalog.ToString(),
$"The product {lineItemCode} was removed from your cart because the catalog of this entry is not available.");
break;
case ValidationIssue.RemovedDueToUnavailableItem:
AddWarningSafe(Warnings,
ValidationIssue.RemovedDueToUnavailableItem.ToString(),
$"The product {lineItemCode} is not available in store and was removed from your cart.");
break;
case ValidationIssue.RemovedDueToInsufficientQuantityInInventory:
AddWarningSafe(Warnings,
ValidationIssue.RemovedGiftDueToInsufficientQuantityInInventory.ToString(),
$"The product {lineItemCode} is sold out and was removed from your cart.");
break;
case ValidationIssue.RemovedDueToInvalidPrice:
AddWarningSafe(Warnings,
ValidationIssue.RemovedDueToInvalidPrice.ToString(),
$"The product {lineItemCode} does not have a valid price and was removed from your cart.");
break;
case ValidationIssue.RemovedDueToInvalidMaxQuantitySetting:
AddWarningSafe(Warnings,
ValidationIssue.RemovedDueToInvalidMaxQuantitySetting.ToString(),
$"The product {lineItemCode} does not have a valid max quantity setting and was removed from your cart.");
break;
case ValidationIssue.AdjustedQuantityByMinQuantity:
AddWarningSafe(Warnings,
ValidationIssue.AdjustedQuantityByMinQuantity.ToString(),
$"The quantity of product {lineItemCode} has changed by Min Quantity setting.");
break;
case ValidationIssue.AdjustedQuantityByMaxQuantity:
AddWarningSafe(Warnings,
ValidationIssue.AdjustedQuantityByMaxQuantity.ToString(),
$"The quantity of product {lineItemCode} has changed by Max Quantity setting.");
break;
case ValidationIssue.AdjustedQuantityByBackorderQuantity:
AddWarningSafe(Warnings,
ValidationIssue.AdjustedQuantityByBackorderQuantity.ToString(),
$"The quantity of product {lineItemCode} has changed by Backorder setting.");
break;
case ValidationIssue.AdjustedQuantityByPreorderQuantity:
AddWarningSafe(Warnings,
ValidationIssue.AdjustedQuantityByPreorderQuantity.ToString(),
$"The quantity of product {lineItemCode} has changed by Preorder setting.");
break;
case ValidationIssue.AdjustedQuantityByAvailableQuantity:
AddWarningSafe(Warnings,
ValidationIssue.AdjustedQuantityByAvailableQuantity.ToString(),
$"The quantity of product {lineItemCode} has changed by current available quantity.");
break;
case ValidationIssue.PlacedPricedChanged:
AddWarningSafe(Warnings,
ValidationIssue.PlacedPricedChanged.ToString(),
$"The price for product {lineItemCode} has changed since it was added to your cart.");
break;
default:
AddWarningSafe(Warnings,
lineItemCode,
$"There was some issue with product {lineItemCode} in your cart.");
break;
}
}
}
}
To customize the inventory checking activity, create an activity flow that mirrors the CartPrepareActivityFlow and replace the CheckInventoryActivity activity with your implementation.
Last updated: Apr 01, 2021