HomeGuides
Submit Documentation FeedbackJoin Developer CommunityLog In

CheckInventory activity

This topic describes how to check the warehouse inventory when adding or changing a cart item.

During checkout, activity flows check remaining item stock quantities and calculate cart totals. Optimizely 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:

  • Mediachase.Commerce.Workflow.Activities. Contains CheckInventoryActivity

How it works

The CartPrepare activity flow is run prior to rendering the page where the customer confirms the order. This flow performs the following tasks:

  • Determines if the item is available, based on the Active status and the item's start and end dates. If an item is not available, it is removed from the cart, and an error message appears on the Cart view page.
  • Determines if cart items are still available based on remaining stock in inventory, reserved inventory stock, and whether backordering is permitted. If the item is not available, it is removed, and an error message appears on the Cart view page.
  • Calculates the price of each cart item, based on tiered pricing. If pricing has changed, a message regarding the change is returned and can be displayed to the customer.
  • Calculates a cart item's extended price, for instance multiplying the price by the quantity purchased.
  • Calculates discounts that apply to cart items.
  • If multiple shipments are created, splits line items into respective shipping addresses.
  • Adds shipping costs and applicable taxes to the cart.

The CheckInventoryActivity determines whether cart items are available.

Example: CheckInventoryActivity

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);
                      }
                  }
              }
          }
      }

Example: UpdateInventoryOrRemoveLineItems

/// 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);
          }
      }

Example: AddWarningMessages

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;
                  }
              }
          }
      }

Customizing the CheckInventory activity

To customize the inventory checking activity, create an activity flow that mirrors the CartPrepareActivityFlow and replace the CheckInventoryActivity activity with your implementation.


Did this page help you?