Inventory

You can customize the way your storefront application handles inventory.

Some of the customizations you can implement include:

  • Use or extend the SiteGenesis application to track product stock levels. See Inventory Scenarios.
  • Integrate with other Inventory Management Systems.
  • Extend the product inventory record object. (Not supported when using Omnichannel Inventory.)
  • Use inventory-specific B2C Commerce APIs to calculate product availability.
  • Access inventory list data via templates. See the SiteGenesis application for examples.
  • Clean up unnecessary inventory transactions for improved cart checkout.

Consider the following as you implement inventory into your storefront application.

  1. What information can your Inventory Management System send to Salesforce B2C Commerce?
    • Does it support backorder or pre-order status?
    • Can it send all required data in a single batch transmission?
  2. What information can your Order Management System receive from B2C Commerce?
    • Does it support backorder or pre-order status?
    • Can it receive all required data in a single batch transmission?
  3. Model the use cases to determine what happens: if a product not available, if there isn't enough stock, or other circumstances.
  4. Identify when the availability stock level validation occurs:
    • Product page
    • Add to shopping cart
    • Checkout
  5. When tracking stock levels within B2C Commerce, understand:
    • What information tracking is there within B2C Commerce?
    • When would you like inventory levels to be decremented, at order confirmation or add to cart?
  6. If supporting backorders:
    • Do you want to present an estimated availability date?
    • Can your backend system support backorders? If yes, what information is required?
    • How backorders impact your shipping logic?
  7. If supporting pre-orders:
    • Do you want to present an estimated availability date?
    • Can your backend system support pre-orders? If yes, what information is required?
    • How pre-orders impact your shipping logic?

Follow these inventory guidelines as you develop customizations to your storefront inventory.

The developer must provide the marketing and merchandising teams with a clear understanding of how stock level tracking has been implemented within their storefront.

  • Inventory record updates are tested in staging before going into production.
  • Inventory record updates are monitored when they go live into production.

Develop a workflow for the inventory management application:

  • Identify clear roles and responsibilities related to inventory management within your organization
  • When are product inventory records transmitted to Salesforce B2C Commerce?
  • What information do the product inventory records contain?
  • Do batch transmissions replace all product inventory records or only merge changed records?
  • Who is managing inventory once the products go live?
  • What signatures are required, at which steps?
  • What are the specific timelines and deadlines?
  • Retrieve inventory data in the XML format defined by inventory.xsd, then import the product inventory records using a scheduled job in Business Manager: Administration > Operations > Job Schedules.
  • If possible, retrieve changed product inventory records instead of all product inventory records.
  • Import inventory into both the Production and Staging instances.
  • Assign the inventory list. You assign each inventory list to one or more sites. Navigate to site > Merchant Tools > Products and Catalogs > Inventory Lists > inventory list > Site Assignments tab. The assignment is a manual process.

You can speed record access (and cart checkout) time. Delete zero amount inventory transactions and inventory transactions with zero sum that correspond to the same order as frequently as possible. See Inventory Transactions Cleanup.

This topic describes how the following APIs calculate >availability. There are some release-specific considerations for updating stock levels.

Simple product

Returns true if

  • product is online, product has no record and default availability = true or
  • product is online, product has record and is perpetual or
  • product is online, product has record and isn't perpetual and ATS is greater than or equal to the product.minOrderQuantity

Product bundle

Returns true if

  • all bundled products are orderable and
  • bundle is online, bundle has no record or
  • bundle is online, bundle has record and is perpetual or
  • bundle is online, bundle has record and isn't perpetual and ATS is greater than or equal to the bundle.minOrderQuantity

Base product

Returns true if all of the following conditions are true:

  • base product is online
  • at least one variation product is orderable

Product set

Returns true if all of the following conditions are true:

  • product set is online
  • at least one set product is orderable

isOrderable(quantity) doesn't depend on minOrderQuantity of product

Simple product

Identical to isOrderable(), except that the quantity must be greater than or equal to the specified quantity.

Product bundle

Identical to isOrderable(), except that the quantity must be greater than or equal to the specified quantity.

Base product

Identical to isOrderable(), except that the sum of orderable variation products must be greater than or equal to the quantity.

Product set

Identical to isOrderable(), except that the sum of orderable products in the set must be greater than or equal to the quantity.

Simple product

Returns true if

  • product has no record and default in-stock is true or
  • product has record and is perpetual or
  • product has record and isn't perpetual and stock-level is greater than or equal to the product.minOrderQuantity.

Product bundle

Returns true if

  • all bundled products are in-stock and
  • bundle has no record or
  • bundle has record and is perpetual or
  • bundle has record and isn't perpetual and stock-level is greater than or equal to the bundle.minOrderQuantity

Base product

Returns true if

  • at least one variation product is in-stock

Product set

Returns true if

  • at least one set product is in-stock

isInStock(quantity) doesn't depend on minOrderQuantity of product

Simple product

As above, but stock-level must be greater than or equal to the quantity, and the quantity must be greater than or equal to one.

Product bundle

As above, but stock-level must be greater than or equal to the quantity, and the quantity must be greater than or equal to one.

Base product

As above, but sum of variation product stock-levels must be greater than or equal to the quantity, and the quantity must be greater than or equal to one.

Product set

As above, but sum of set product stock-levels must be greater than or equal to the quantity, and the quantity must be greater than or equal to one.

Simple product

Returns availability status for quantity one. Possible statuses are:

  • IN_STOCK - returned if product is in stock
  • BACKORDER - returned if product isn't in stock, but back-orderable, and at least one back-orderable item is left.
  • PREORDER - returned if product isn't in stock, but pre-orderable, and at least one pre-orderable item is left
  • NOT_AVAILABLE - returned if product is not IN_STOCK, nor BACKORDER, nor PREORDER

Product bundle

Returns availability status for quantity one. See "Simple Product" column for possible statuses.

Returned status is computed based on the records of the bundled products and the record of the bundle if it exists, and represents the lowest availability status of the involved products.

For example, if all bundled products are IN_STOCK, but the bundle has a record and is NOT_AVAILABLE, method returns NOT_AVAILABLE.

Base product

Returns availability status for the variation product with the best availability for quantity one. For example, if all variation products are BACKORDER, but only one is IN_STOCK, method returns IN_STOCK.

Product set

Returns availability status for the set product with the best availability.

Simple product

Returns availability statuses for quantity. For example, if requested quantity is 10, and stock level is two, and product can be backordered, and backorder quantity is five, the method returns the following: IN_STOCK-2, BACKORDER-5, NOT_AVAILABLE-3

Product bundle

Returns availability statuses for quantity. Based on the rules described previously, but computation combines the availability levels of all bundled products and the bundle itself (if it has a record).

Base product

Returns availability status for quantity based on the variation products with the best availability.

Product set

Returns availability statuses for quantity based on the set products with the best availability

Simple product

Decrement product stock-level. Fails if ATS is less than the productLineItem.quantity.

Product bundle

If bundle has record, decrement stock-level of bundle. Decrement stock-levels of bundled product line items recursively. Fails if the available to sell (ATS) value is less than the productLineItem.quantity.

Base product

Fails if product line item is base product. A base product can't be ordered.

Product set

Fails if product line item is product set. A product set can't be ordered.

Uses the preorder/backorder allocation and the inventory list default-in-stock flag to calculate availability.

You can customize your application with programmatic inventory access.

Use the following:

  • API Methods: use to manage inventory lists, and to retrieve product inventory and availability information.
  • Pipelets: use to get and set inventory record values.
  • Resources: use for inventory-related (localizable) messages.

Salesforce B2C Commerce APIs also enable you to determine product availability within your application.

Salesforce B2C Commerce exports an Inventory List record and its associated Product Inventory Records via an XML file. The structure of the XML file follows the semantic of the XML inventory.xsd schema definition.

Inventory list export contains these attributes:

  • allocation
  • allocation-timestamp
  • perpetual
  • preorder-backorder-handling
  • preorder-backorder-allocation
  • in-stock-date
  • in-stock-datetime
  • ats (available to sell)
  • on-order
  • turnover

Salesforce B2C Commerce imports an Inventory List record and its associated Product Inventory Records via an XML file. The structure of the XML file follows the semantic of the XML inventory.xsd schema definition.

A typical import file is shown in the following example:

Specify the inventory.xsd file that defines the schema.

Set the stock level at 10 for product "ProductWithAllocation".

Set the stock level at 10 and the backorder allocation at 10 for product " ProductWithBackorderAllocation ".

Define "ProductWithPerpetualFlag" as a product always in stock.

Use these methods from the dw.catalog.ProductInventoryList class to manage your inventory lists, and retrieve product inventory and availability information.

ClassDescription
ProductInventoryListGiven a product or a product ID, the ProductInventoryList object provides access to the list's ID, description and defaultInStockFlag. Each site can have a single ProductInventoryList, although that ProductInventoryList can be used by more than one site. The main function of a ProductInventoryList is to hold ProductInventoryRecords, each of which holds the following inventory information about a single product.
ProductInventoryMgrThe ProductInventoryMgrobject provides access to inventory related objects.
ProductInventoryRecordThe ProductInventoryRecordholds information about a product's inventory and availability.
ProductAvailabilityModelThe ProductAvailabilityModelobject provides methods for retrieving all information on availability of a single product.
ProductAvailabilityLevelsThe ProductAvailabilityLevels object returns the quantity of items available for each availability status.

Use the following pipelets to modify or extend the inventory implementation in the SiteGenesis application. They provide convenient methods and properties for getting and setting inventory record values.

PipeletDescription
ReserveInventoryForOrder

Reserves the inventory for each product line item of the specified LineItemCtnr. The reserved inventory is automatically finalized with the commit of the order creation transaction (encloses the CreateOrder pipelet).

If no inventory finalization takes place within 10 minutes, the reservation expires. The pipelet cleans up existing reservations for the LineItemCtnr before it's called again. The reserved inventory doesn't count toward the current stock level.

This pipelet should only be used for the inventory reservation during an order creation.
ImportInventoryLists

Imports inventory lists from the given import file in the specified mode. The result of the import operation is represented by the Status output property. The pipelet returns to the error connector if a process error occurred when executing the import.

A process error prevents or interrupts the basic execution of the import. An example of a process error is when the specified import file doesn't exist on the file system.

Client code should consult the Statusobject details to determine if there were any problems importing the individual data within the import file.

You can use the following localizable resources for inventory-related messages. These are located in the SiteGenesis Storefront Core cartridge (templates/resources).

FileResourceDefault Text
checkout.propertiescart.cart.allBackorderThis item is available on backorder.
 cart.cart.allInStockThis item is in stock and ready to ship.
 cart.cart.allNotAvailableThis item is currently not available. Remove the item from your cart in order to proceed with the checkout.
 cart.cart.allPreorderThis item is available for pre-order.
 cart.cart.inStockDateThe expected in-stock date is
 cart.quantityBackorder{0} item(s) are available on backorder.
 cart.cart.quantityPreorder{0} item(s) are available for pre-order.
 cart.cart.quantityInStock{0} item(s) are in stock and ready to ship.
 cart.cart.remainingBackorderThe remaining items are available on backorder.
 cart.cart.remainingNotAvailableThe remaining items are currently not available. Adjust the quantity in your cart in order to proceed with the checkout.
 cart.cart.remainingPreorderThe remaining items are available for pre-order.
components.propertiescomponents.common-details.005This item is in stock.
 components.common-details.006This item isn't available.
 components.common-details.007Only {0} items left.
 components.common-details.008More items on backorder.
 components.common-details.backorderThis item is available on backorder.
 components.common-details.in-stock-dateThe expected in-stock date is
 components.common-details.pre-orderThis item is available for pre-order.

The inventory.xsd file defines how to structure the XML file that transmits inventory data to Salesforce B2C Commerce. This file defines the Inventory List record and its associated Product Inventory Records.

The inventory.xml file can contain 0 or more inventory lists.

An inventory list must always have a value for the default product availability flag.

The description field is optional and up to 4000 characters.

The list ID is required and up to 256 characters.

The import mode is optional.

The list can contain zero or more inventory records.

The allocation, perpetual, preorder-backorder-handling, preorder-backorder-allocation, in-stock-date, ats, on-order, turnover, and custom-attribute fields of an inventory record are optional.

Product IDs are required.

Allocation contains a decimal value greater than or equal to "0.0".

ImportMode defaults to "delete".

The preorder backorder handling field must be equal to "none", "preorder" or "backorder".

This defines a "simpleType.Generic.String", which is the basis for the next three definitions.

This defines an optional string with a maximum length of 256 characters.

This defines an optional string with a maximum length of 4000 characters.

This defines a non-empty string with a maximum length of 256 characters.

The SiteGenesis storefront implements an inventory scenario that showcases a combination of variation products.

Variants include:

  • Pre-order, back-order, and discontinued products
  • Stock-level and availability based on getAvailabilityModel().isInStock()
  • Show available on-hand inventory level for quantity < 5 ("only x items left")
  • Out-of-stock products with and without available date

Availability is indicated on the following:

  • Product lists (catalog, search, shopping cart, wish lists)
  • Product details page

Availability is checked during the following steps of the order process:

  • Add-to-Cart
  • Checkout
  • Order-Now

The SiteGenesis application enables customers to order pre-order and back-order items.

The Salesforce B2C Commerce APIs allow for customization and the addition of new features not demonstrated in the SiteGenesis application.

When dealing with inventory, there are many ways you can manage inventory and communicate information about it to customers.

Inventory consists of the products you have available to sell. Review these scenarios, which illustrate how to use or extend the SiteGenesis application to track product stock levels, when considering your Salesforce B2C Commerce inventory implementation:

These models generally assume that you aren’t using Salesforce Omnichannel Inventory. Many of their details don’t apply to implementations that use Omnichannel Inventory.

Model NameDescription
Model 1Consider all products permanently in stock.
Model 2Some products have inventory records that control their availability. Other products without inventory records are considered to be permanently in stock.
Model 3All products are assumed to have inventory records. A front-end system frequently updates stock levels. There is no attempt to track inventory availability in B2C Commerce.
Model 4All products are assumed to have inventory records. B2C Commerce maintains stock levels for product display, cart display, and checkout.
Model 5B2C Commerce maintains stock levels for product display and checkout. B2C Commerce calls the external inventory system at add-to-cart for a real-time stock level check.
Model 6B2C Commerce maintains stock levels for product display and cart display. B2C Commerce calls the external inventory system at checkout for a real-time stock level check.

After reviewing these scenarios, answer the following questions and plan your inventory strategy.

  1. Do you maintain inventory levels?

    If no:

    • Do you want to treat all products as always available? Refer to Model 1 - No Product Records

    • Do you want to treat individual products as always available? Refer to Model 2 - Inventory Information for Some Products If yes:

    • What information can your Inventory Management System transmit to B2C Commerce?

    • Consider models 2 through 5.

  2. Do you support backorder or pre-order?

    If no:

    • How to you want to handle these orders? Refer to Model 3 - B2C Commerce Doesn't Calculate ATS Values and Model 4 - B2C Commerce Calculates ATS Values
    • What information does your Order Management System require? If yes, consider models 2 through 5.
  3. Do you support an in stock date?

    If no:

    • Do you want to treat all products as always available? Refer to Model 1 - No Product Records
    • Do you want to treat individual products as always available? Refer to Model 2 - Inventory Information for Some Products If yes, consider models 2 through 5.
  4. Can you support real-time stock level checks?

    If yes:

    • To check at Add-to-Cart, refer to Model 5 - Real-Time Inventory Availability At Add-to-Cart
    • To check at Checkout, refer to Model 6 - Real-Time Inventory Availability At Checkout
  5. Do you want to take a product off-line when out of stock?

    • If yes, refer to Common Implementations and Customizations
    • If no, no changes are required.
  6. How do you treat secondary products in a bundle? Refer to Updating Stock Levels

    • When the primary product becomes unavailable?
    • When the stock level of the primary product is incremented or decremented?
  7. How do you want to show unavailable products on category pages?

  8. Can you support partial inventory updates? If yes, how often do you want to run them?

  9. How often do you want to run full inventory updates?

  10. Do you support bundled products? If yes, how do you structure order information that you transmit back to the order management system?

Model 1 is appropriate for a merchant whose inventory is always physically in stock, and has no worries about product availability.

Module 1 is also appropriate for the merchant whose Inventory Management System is incapable of transmitting product availability data to Salesforce B2C Commerce.

This model can apply to implementations that use Salesforce Omnichannel Inventory.

This model considers all products permanently in stock. Standard B2C Commerce storefront functionality has two optional objects: ProductInventoryList(the inventory list) and ProductInventoryRecord(each product's inventory record).

If the following conditions exist:

  1. There is an inventory list.
  2. There are no product inventory records.
  3. ProductInventoryList.DefaultInStock = true

The result is that any particular product is considered to be in stock and available. The storefront behavior is as follows.

StatusBehavior
AvailableThe product record appears in product detail, cart, and checkout views. The product can be ordered.
BackorderedNot supported
Pre-orderedNot supported
Not availableNot supported

Model 2 is appropriate for a merchant who has some inventory that is always physically in stock.

Module 2 is also appropriate for a merchant who only monitors the availability of a subset of products.

This model has inventory records that control the availability of some products. Other products without inventory records are considered to be permanently in stock.

If you use Salesforce Omnichannel Inventory, then inventory records and availability data are managed in Omnichannel Inventory. The details of this model apply to implementations that don’t use Omnichannel Inventory.

If the following conditions exist:

  1. There is an inventory list that is periodically refreshed.
    • ProductInventoryList.DefaultInStock = true
  2. There are some product inventory records. The new and modified records have these values:
    • ProductInventoryRecord.allocation = {units}
    • ProductInventoryList.perpetual = false

The product inventory records can also have these values set. The values affect the calculation of ProductInventoryRecord.ATS.

  • ProductInventoryList.backorderable = true
  • ProductInventoryList.preorderable = true
  • ProductInventoryList.preorderBackorderAllocation= {units}
  • ProductInventoryList.inStockDate= {date}

Salesforce B2C Commerce calculates ProductInventoryRecord.ATS = {units} for all product records. The result is that any product without a product inventory record is considered to be in stock and available. Product inventory records for the other products indicate their availability.

The storefront behavior for products without inventory records is as follows.

StatusBehavior
AvailableThe product record appears in product detail, cart, and checkout views. The product can be ordered.
BackorderedNot supported
Pre-orderedNot supported
Not availableNot supported

The storefront behavior for products with inventory records is as follows.

StatusBehavior
AvailableThe product record appears in product detail, cart, and checkout views. The product can be ordered.
BackorderedThe product record appears. The product can be ordered. The backorder date appears in the shopping cart.
Pre-orderedThe product record appears. The product can be ordered. The pre-order date appears in the shopping cart.
Not availableThe product record appears with a no longer available message. The product can't be ordered.

Model 3 is appropriate for the merchant who is able to frequently refresh the inventory data in B2C Commerce.

The frequency would be sufficient to eliminate concerns about accidental out-of-stock conditions. Perhaps the merchant would only update product status for products that had been sold since the last full inventory update.

In this model, all products have inventory records, but there is no attempt to track inventory availability in B2C Commerce. B2C Commerce initially sets ATS equal to allocation, but both values remain unchanged after purchases. (The storefront doesn't use either the UpdateStockLevelpipelet or the ProductAvailabilityModel.UpdateStockLevel()method.) A front-end system frequently updates stock levels many times per day.

If you use Salesforce Omnichannel Inventory, then inventory records and availability data are managed in Omnichannel Inventory. The details of this model apply to implementations that don’t use Omnichannel Inventory.

If the following conditions exist:

  1. There is an inventory list that is periodically refreshed.
    • ProductInventoryList.DefaultInStock = true
  2. There are product inventory records for all products. The new and modified records have these values:
    • ProductInventoryRecord.allocation = {units}
    • ProductInventoryList.perpetual = false

Optionally, set these inventory record fields to support backorder. These record fields affect the calculation of ProductInventoryRecord.ATS.

  • ProductInventoryList.backorderable = true
  • ProductInventoryList.preorderBackorderAllocation= {units}
  • ProductInventoryList.inStockDate= {date}

Optionally, set these inventory record fields to support pre-order. These record fields affect the calculation of ProductInventoryRecord.ATS.

  • ProductInventoryList.preorderable = true
  • ProductInventoryList.preorderBackorderAllocation= {units}
  • ProductInventoryList.inStockDate= {date}

The result is that any product without a product inventory record is considered to be in stock and available. Product inventory records for the other products indicate their availability. There is no adjustment to allocation (stock level) values as products are sold.

The storefront behavior for products is as follows.

StatusBehavior
AvailableThe product record appears in product detail, cart, and checkout views. The product can be ordered.
BackorderedThe product record appears. The product can be ordered. The backorder date appears in the shopping cart.
Pre-orderedThe product record appears. The product can be ordered. The pre-order date appears in the shopping cart.
Not availableThe product record appears with a no longer available message. The product can't be ordered.

Model 4 is appropriate when you want to update B2C Commerce's inventory status. You can update the inventory status once per day or less frequently. B2C Commerce can warn your customers when products are out of stock, on backorder, or pre-order.

In this model, all products have inventory records. B2C Commerce maintains stock levels for product display, cart display, and checkout. The merchant keeps inventory data reasonably fresh, perhaps with a daily batch feed.

If you use Salesforce Omnichannel Inventory, then inventory records and availability data are managed in Omnichannel Inventory. The details of this model apply to implementations that don’t use Omnichannel Inventory.

If the following conditions exist:

  • There is an inventory list that is periodically refreshed.
  • ProductInventoryList.DefaultInStock = false

There are product inventory records for all products. The new and modified records have these values:

  • ProductInventoryRecord.allocation = {units}
  • ProductInventoryList.perpetual = false

Optionally, set these inventory record fields to support backorder. These record fields affect the calculation of ProductInventoryRecord.ATS.

  • ProductInventoryList.backorderable = true
  • ProductInventoryList.preorderBackorderAllocation = {units}
  • ProductInventoryList.inStockDate= {date}

Optionally, set these inventory record fields to support pre-order. These record fields affect the calculation ofProductInventoryRecord.ATS.

  • ProductInventoryList.preorderable = true
  • ProductInventoryList.preorderBackorderAllocation {units}
  • ProductInventoryList.inStockDate = {date}

The result is that product inventory records indicate their availability. You can presume that the calculated ATS values are close to actual. The storefront behavior is as follows.

StatusBehavior
AvailableThe product record appears. The product can be ordered.
BackorderedThe product record appears. The product can be ordered. The backorder date appears in the shopping cart.
Pre-orderedThe product record appears. The product can be ordered. The pre-order date appears in the shopping cart.
Not AvailableThe product record appears with a no longer available message. The product can't be ordered.

Model 5 is appropriate when you want to minimize the risk of having a customer order a product that is not available. And have your Inventory Management System respond to real-time requests for product inventory status.

Model 5 requires customization.

Salesforce B2C Commerce calls the front-end system at add-to-cart for a real-time stock level check. The merchant keeps inventory data reasonably fresh, perhaps with a daily batch feed.

This model doesn’t apply to implementations that use Salesforce Omnichannel Inventory.

If the following conditions exist:

  • There is an inventory list that is periodically refreshed.
  • ProductInventoryList.DefaultInStock = true

The result is that all products appear to be in stock until the customer attempts to add-to-cart. At this point, the customer can be notified that a product is partially or totally unavailable. B2C Commerce doesn't notify a customer of an availability issue at checkout. The storefront behavior is as follows.

StatusBehavior
AvailableThe product record appears in product detail, cart, and checkout views. The product can be ordered.
BackorderedNot implemented
Pre-orderedNot implemented
Not availableNot implemented

Model 6 is appropriate when you want to eliminate the risk of having a customer order a product that is not available. And your Inventory Management System responds to real-time requests for product inventory status.

Model 6 requires customization of the SiteGenesis application.

Salesforce B2C Commerce calls the inventory system at checkout for a real-time stock level check. The merchant keeps inventory data reasonably fresh, perhaps with a daily batch feed.

This model doesn’t apply to implementations that use Salesforce Omnichannel Inventory.

If the following conditions exist:

  • There is an inventory list that is periodically refreshed.
  • ProductInventoryList.DefaultInStock = true

The result is that all products appear to be in stock until the customer attempts to check out. At this point, the customer is notified that a product is partially or totally unavailable. B2C Commerce doesn't notify a customer of an availability issue at add-to-cart. The storefront behavior is as follows.

|Status|Behavior| |Available|The product record appears in product detail, cart, and checkout views. The product can be ordered.| |Backordered|Not implemented| |Pre-ordered|Not implemented| |Not available|Not implemented|

The mechanism for updating stock levels depends on the version of the API your storefront is using.

If an order is canceled or replaced, the inventory for the products in the order is updated. For example, if an order for five rings is canceled, the inventory for the rings increases by five. Because order cancellation and replacement are normally done through an integration with an order management system (OMS), there is no example of cancellation and replacement in SiteGenesis.

The stock update mechanism, which uses the ReserveInventoryForOrder pipelet is the recommended method for updating stock levels.

If you are using the inventory import feed to reset inventory levels, if the inventory level is set to zero via an import feed and an order is then replaced or canceled, the inventory is updated and the inventory level set to the quantity of inventory in the order. The replacement or cancellation is important in the case of a product recall or other situation in which you have decided to immediately stop selling a product and don't want it to appear as an available product.

Replacing an order uses the mechanism for canceling an order followed by the mechanism for creating an order. For replacement orders, the ReserveInventoryForOrder pipelet only reserves inventory for the new order and items for the order being replaced are available for the replacement order.

Order cancellation inventory Process

The following table shows the changes to inventory levels throughout the checkout process.

Checkout stepPipeletChangeInventory TotalExample
Customer has created an order, but has not entered the checkout process  

i

i is the inventory at the start of the checkout process.

5 shirts, 3 pants, 10 caps available

two shirts, one pants, three caps in order

Customer enters the checkout process for order XReserveInventoryForOrderReserves the change to the inventory for the order. This transaction includes an internal timestamp, so that reservations can timeout if the cart is abandoned.

i - x (while the timestamp is valid)

where:

i is the inventory at the start of the checkout process.

x is the quantity in order X.

Three shirts, two pants, seven caps available

two shirts, one pants, three caps in reserved for order

Customer submits order X

CreateOrderFinalizes the inventory change made using ReserveInventoryForOrder.

i - x

Three shirts, two pants, seven caps available
Customer cancels order XCancelOrderReturns the inventory for the order.

i -x + x

x is the quantity in order X.

5 shirts, 3 pants, 10 caps available
The cancellation mechanism isn't implemented in SiteGenesis, because replacement and cancellation are only used when Salesforce B2C Commerce is integrated with an order management system and SiteGenesis doesn't generally include integration functionality.

Order Replacement Inventory Process

The following table shows the changes to inventory levels throughout the checkout process. An order replacement is equivalent to an order cancellation followed by a new order, except that is it wholly handled by the CreateOrder pipelet. The process allows the inventory from the canceled order to be used for the new order. If the creation of the replacement order fails, the items continue to be reserved for the replacement order.

Checkout stepPipeletChangeInventory TotalExample
Customer has created an order, but has not entered the checkout process  

i

i is the inventory at the start of the checkout process.

5 shirts, 3 pants, 10 caps available

two shirts, one pants, three caps in order

Customer enters the checkout process for order XReserveInventoryForOrderReserves the change to the inventory for the order. This transaction includes an internal timestamp, so that reservations can timeout if the cart is abandoned.

i - x (while the timestamp is valid)

where:

i is the inventory at the start of the checkout process.

x is the quantity in order X.

Three shirts, two pants, seven caps available

Two shirts, one pants, three caps in reserved for order

Customer submits order X

CreateOrderFinalizes the inventory change made using ReserveInventoryForOrder.

i - x

Three shirts, two pants, seven caps available
Customer replaces order X with order YReserveInventoryForOrder

Calculates the change in order quantities and reserves the new quantity.

(x - y) = d

i + d

x is the quantity in order X.

y is the quantity in order Y.

d is the change quantity between in order X and Y. The change for each item in the order is calculated separately. The change can be either negative or positive depending on whether the replacement order item quantity is larger or smaller than the original order.

Four shirts, one pant, four caps in the new order

One shirt, two pants, six caps available

Four shirts, one pants, five caps in reserved for order

 CreateOrderUpdates the inventory for the order if the change, returning inventory if fewer items were ordered and finalizing the reservation if more items were ordered.

i + d

d is the change quantity between in order X and Y.

One shirt, two pants, six caps available

Four shirts, one pants, five caps in reserved for order

The order replacement mechanism isn't implemented in SiteGenesis, because replacement is only used when B2C Commerce is integrated with an order management system and SiteGenesis doesn't generally include integration functionality.

Canceling or replacing orders in Business Manager

While you can manually cancel or replace orders in Business Manager, the process doesn't update the stock level for your storefront.

Canceling or Replacing Orders Using Order.SetStatus()

While you can manually cancel or replace orders using the Order.setStatus() method, the process doesn't affect the stock level.

The stock update mechanism prevents accidental overselling by reserving inventory early in the transaction and not finalizing the stock update until the order is placed.

Checkout stepPipeletChangeInventory Total
Customer starts the checkout process  

i

where n is the inventory at the start of the checkout process.

After payment calculation and before personal information gatheredReserveInventoryForOrderReserves the change to the inventory for the order. This transaction includes an internal timestamp, so that reservations can timeout if the cart is abandoned.

i - x (while the timestamp is valid)

i (after the timestamp expires)

where:

  • n is the inventory at the start of the checkout process.

  • a is the quantity in the order.

After personal information gathered and before payment handlingCreateOrderFinalizes the inventory change made using ReserveInventoryForOrder.

i -x

An example of this mechanism is implemented in the SiteGenesis `COPlaceOrder` pipeline.

Using the Order.setStatus() method doesn't affect the stock level.

if an order is canceled or replaced, inventory isn't returned.

You can use the Salesforce B2C Commerce Inventory feature to track inventory levels between regular inventory updates to the production system from a backend inventory system.

You can use the inventory levels to present more accurate stock level information to customers. You can update the B2C Commerce inventory status in several ways:

  • Frequently - every 15 minutes or every hour
  • Infrequently - every 24 hours
  • With complete replacements of the product inventory records
  • With replacement of only those records that have changed

The data that the Inventory Management System transmits can be defined either:

  • By the default inventory schema (inventory.xsd), which allows for a wide range of features.
  • By a different schema (with customization) that has fewer, more, or different product inventory record attributes.

You can extend the ProductInventoryRecord object to store more fields.

For example, you can show a special message when the inventory of a particular product drops below its threshold value. There are multiple steps to this process.

See Inventory.

  1. Extend the ProductInventoryRecord object.

    1. Select Administration > Site Development > System Object Types.

    2. Select ProductInventoryRecord and click the Attribute Definitions tab.

    3. Add the new object attribute.

  2. Add a new message to the components.properties resource file.

  3. Modify availability.ismlto analyze and react to the Threshold value.

For instances that create many orders in a short time frame or at a constant high rate, retention of this inventory data slows checkout.

Load tests show a direct dependency between the number of existing transactions and the number of orders that can be created per second. The dependency is even more severe for flash sales where transactions are booked against only one or few distinct inventory records.

The CleanupInventoryTransaction job, introduced in Release 17.1, runs hourly to delete zero amount inventory transactions and inventory transactions with zero sum corresponding to the same order.

You are not permitted to update inventory allocation by setting the allocation reset date to older than it was. However, a feature switch enables you to suppress this restriction in a case of an exception.

A quota checks for violations of this value. The quota: The maximum hours reallocation date can be set in the past ( id="object.ProductInventoryRecordPO.maxReallocationTimeInPast" ) is set to 48 hours. The quota is violated if the inventory allocation reset date is set to a date earlier than 48 hours in the past.

Salesforce B2C Commerce doesn't enforce this quota because some customers must set an older allocation reset date.

We recommend that if your site doesn't violate this quote, you ask Commerce Cloud Support to enforce it for you. Enforcement enables you to take advantage of the inventory transactions cleanup capability.

  • When the quota is enforced, the CleanupInventoryTransaction job cleans up all final inventory transactions older than the corresponding allocation reset date and older than 48 hours.
  • When the quota isn't enforced, the CleanupInventoryTransaction job cleans up all final inventory transactions older than the corresponding allocation reset date and older than 7 days.