Transitioning from Sitecore Experience Commerce to OrderCloud: Catalogs and Categories

Reading Time: 6 minutes

In this article, we will review and compare catalogs and categories between Sitecore Experience Commerce and OrderCloud to facilitate developers looking to transition from XC to OrderCloud as well as identify a path for migration of existing XC solutions to OrderCloud.

We will look at a high-level comparison of architecture, functionality, and data models, with greater focus on transitioning from Sitecore Experience Commerce, meaning identifying a close path to parity in OrderCloud, using the Habitat catalog and SXA Storefront.

Conceptual Architecture and Features

Catalogs and Categories

In XC, the structure of catalogs, categories, and sellable items/products can be recreated in OrderCloud. In a nutshell, categories are tied to their catalogs and can only have one parent, either another category or the catalog itself, while sellable items or products are separate to the catalog and can be assigned to one or more catalogs and/or categories.

In earlier versions of XC categories were allowed to have multiple parents, but support was subsequently removed. If an XC solution still contains categories with multiple parents this would be a consideration for pre-migration cleansing.

Figure 1: XC relationships between catalogs, categories, and sellable items.
Figure 2: OrderCloud relationships between catalogs, categories, and products.

The Storefront to Catalog Association

In Customer to Buyer Users we discussed that in XC, a storefront was required in order to associate a customer to a catalog. while OrderCloud has a direct assignment between buyers and catalogs. We will now revisit this to complete the context for catalogs.

In the SXA storefront, only a single catalog can be associated to the storefront, which is configured in the Content Editor under /sitecore/content/<tenant>/<site>/Home/Catalogs.

Figure 3: An example catalog configuration for a storefront.

Over in OrderCloud, a catalog assignment creates a link between a catalog and a buyer, bypassing the need for a storefront.

Figure 4: XC associates a catalog to a site while OrderCloud assigns catalogs directly to a buyer

The catalog assignment also contains two additional boolean properties in ViewAllCategories and ViewAllProducts, which as the names suggest allow all categories and products to be viewed by buyer users via the /me/products resource. These properties are important when understanding how XC customers can view sellable items vs OrderCloud buyers viewing products, which we cover in the next section SXA Scope Query vs Product Visibility.

SXA Scope Query vs Product Visibility

Now that we have established that the catalog structure can be identical between XC and OrderCloud, how do both systems handle product search functionality?

In an SXA storefront, there are two primary search scopes that are used for searching sellable items; the catalog scope and the category scope. These scopes are defined in the Content Editor under /sitecore/content/<tenant>/<site>/Settings/Scopes.

Figure 5: The catalog and category scopes in an SXA storefront.
Catalog Scope

The catalog scope is used by the global site search component, and will perform a search query returning all active sellable items associated to the catalog. An optional search term can be provided by the storefront user to further filter the results.

Referencing OrderCloud’s documentation, Product Visibility Requirements, we see Scenario 3 replicates the XC and the SXA storefront visibility rules for the catalog scope, excluding the search term filter. “When I assign a catalog to a buyer organization, I just want everybody in that organization to see everything in the catalog.” In short the ViewAllCategories and ViewAllProducts of a catalog assignment should be set to true.

Category Scope

The category scope is used for the category search results page and is just a more refined scope than the catalog scope in that it will return all active sellable items associated to a specific defined category. Again, an optional search term is available for further filtering.

The Search Term Filter

For the search term filter, the SXA query builder appends a comparison between the search term appends a fuzzy query against the sxacontent index field, which is an array consisting of the following sellable item properties:

  • Tags
  • ProductId
  • Name
  • DisplayName
  • ItemDefinition
  • Brand

The resulting query for a global search will look something like the following, with the highlighted section representing the example search term of “Spectra”.

In OrderCloud, we can achieve an equivalent query using the /me/products resource and applying a filter that allows us to filter on multiple fields with logical “OR” syntax to query each of the raw OrderCloud properties that make up the XC sxacontent index field.

  • Catalog scope: /me/products?catalogID=Habitat_Catalog&ID|Name|xp.Tags|xp.ItemDefinitions|xp.Brand=*Spectra*
  • Category scope: /me/products?catalogID=Habitat_Catalog&categoryID=Televisions&ID|Name|xp.Tags|xp.ItemDefinitions|xp.Brand=*Spectra*

As we will review in an upcoming article, the Name property tends to be a duplicate of the DisplayName, so we won’t bloat the product’s xp in OrderCloud with redundant data, however you can choose to include the Name property and amend the /me/products queries as necessary.

Catalog – Item Definitions

Item definitions allow composer templates to be associated with sellable items to create extended properties on the sellable items. The name of the item definition is also used in storefront search indexes for search components

OrderCloud also has the capability of creating extended properties (XP), however it requires that the XP object on all Product objects be consistent to prevent breaking indexes, therefore we merge all non-standard properties into a consistent xp structure along side the item definition itself.

Figure 6: The XC architecture for item definitions vs a sample architecture approach in OrderCloud.

Other Considerations

Entity Versioning and Workflow

As OrderCloud has no concept of entity versioning, one approach towards migration is to only migrate the latest published versions of catalogs and categories. In a similar manner the publishing workflow that applies to catalogs and categories may see a project consider the latest entity version as the source of truth regardless of its published state. Considerations would need to be made on project by project basis, which may entail a level of data cleansing.

Catalogs and Categories Pending Purge

A gotcha in migrating catalogs and categories is that the entities can still exist if they are pending purge, which is represented on the entity with an instance of PurgeCatalogsComponent or PurgeCategoriesComponent. These entities can be safely ignored during migration.

Property Localisation

XC provides entity properties to be localisable for content that can be displayed in multiple languages. OrderCloud does not support localisation, so this may be a consideration for workshopping a solution to be handled by the custom middleware.

Data Mapping

With the conceptual analysis above, we will now review what data mapping would look like for migration and from a comparison standpoint.

In the XC Entity/Component column, components are assumed to live on the primary XC entity being mapped.

OrderCloud IDs do not allow spaces. It is important that the IDs are parsed to remove/replace invalid characters consistently.

Catalogs

Catalog mapping is fairly basic as there aren’t many properties on the catalogs of either system

OC PropertyData TypeRequiredXC Entity/ComponentXC PropertyData TypeNotes
IDstringYesCatalogFriendlyIdstring
OwnerIDstringNoN/AN/AN/A
NamestringYesCatalogDisplayNamestring
DescriptionstringNoN/AN/AN/A
ActivebooleanNoCatalogPublishedbooleanThis assumes only the latest published entity version is being migrated.
xpobjectNoN/AN/AN/AXC composer views and programatic components can be added to xp as needed.

Catalog Assignments

Catalog assignments are simply a relational mapping with the added control over category and product visibility.

OC PropertyData TypeRequiredXC Entity/ComponentXC PropertyData TypeNotes
CatalogIDstringYesCatalogFriendlyIdstring
BuyerIDstringNoN/AN/AN/AThe Sitecore Domain taken from the Storefront with the associated catalog.
ViewAllCategoriesbooleanNoN/AN/AN/ASet to true.
ViewAllProductsbooleanNoN/AN/AN/ASet to true.

Categories

XC orders categories alphabetically using list ids, while OrderCloud generates the ListOrder property, so this may result in different ordering between the two systems.

OC PropertyData TypeRequiredXC Entity/ComponentXC PropertyData TypeNotes
catalogIDstringYesCategoryFriendlyIdstringIs a resource parameter, not body property.
IDstringNoCategoryFriendlyIdstring
NamestringYesCategoryDisplayNamestring
DescriptionstringNoCategoryDescriptionN/A
ListOrderstringNoN/AN/AN/AListOrder will be generated (auto-increment) when creating categories.
ActivebooleanNoCategoryPublishedbooleanThis assumes only the latest published entity version is being migrated.
xpobjectNoN/AN/AN/AXC composer views and programatic components can be added to xp as needed.

References

Transitioning from Sitecore Experience Commerce to OrderCloud: Inventory and Pricing

Reading Time: 8 minutes

In this article, we will review and compare Sitecore Experience Commerce inventory and pricing entities against OrderCloud’s inventory and pricing to facilitate developers looking to transition from XC to OrderCloud as well as identify a path for migration of existing XC solutions to OrderCloud.

We will look at a high-level comparison of architecture, functionality, and data models, with greater focus on transitioning from Sitecore Experience Commerce, meaning identifying the closest path to parity as possible in OrderCloud, using the Habitat catalog and SXA Storefront.

Conceptual Architecture and Features

Inventory

Single Inventory Approach

When it comes to inventory management, in its most basic form, a sellable item or item variation will contain inventory information on an associated entity within an inventory set. To be able to resolve the inventory, the sellable item must be associated to a catalog (or category within a catalog) and the catalog must be associated to the inventory set.

Figure 1: The sellable item and item variation relationship to inventory information.

In a more simplified comparison, OrderCloud also has a separate underlying inventory object assigned to a product or variant, however it’s represented and managed as a sub-object of the product/variant. No relationship to a catalog or inventory set equivalent is required.

Figure 2: The product and variant relationship to inventory, equivalent to XC’s standard inventory architecture for single inventory management.

Multi-Inventory Approach

When it comes to dealing with multiple catalogs in XC, the approach has a new layer of complexity; catalogs may have different associated inventory sets, which means that the inventory information entity the commerce engine resolves to is based on catalog-inventory set association.

Figure 3: Sellable item vs item variation inventory management in XC.

In OrderCloud, it is also possible to store multiple sets of inventory data using inventory records, providing two paths for inventory management. For implementations where single sets of inventory data will only ever be required, the traditional inventory management approach in figure 2 can be used. Where multi-inventory management is required, inventory records can be leveraged.

In OrderCloud’s multi-inventory management approach, admin addresses are effectively the inventory set equivalent in creating a logical grouping of inventory records; catalog assignments are still not required to resolve inventory.

Multiple inventory records can be assigned to an address, and although it’s not required in the XC to OrderCloud migration, it’s mentioned simply for a more complete understanding of the OrderCloud architecture.

Figure 4: OrderCloud’s inventory record approach for both single and multi-inventory support.

The most notable difference between the two systems is the Commerce Engine controls the logic to resolve the appropriate inventory information entity, while the middleware application of an OrderCloud implementation would be responsible for resolving applicable inventory records.

Inventory sets can represent the grouping of inventory information entities, typically for source or purpose, e.g. warehouse stock or reserved inventory for online sales. These are used in common customisations, such as click and collect, where more than one inventory set is utilised in a storefront. Using inventory records in OrderCloud can achieve the same result.

Inventory Properties

Apart from the expected quantity property, XC’s inventory information also contains information such as invoice unit price and currency, preorderable and backorderable details. While the commerce engine does perform some logic for decrementing backorder and preorder inventory quantities, the implementation is not complete, therefore we won’t treat this as a functional gap between the two systems and simply adding them to OrderCloud’s extended properties (xp) will suffice from the data migration perspective.

Inventory records have the additional benefit of owning their xp. This means that additional properties such as preorderable and backorderable details better fit the context in the inventory record xp, over the product xp, which would be required when using the traditional product inventory approach.

Pricing

The pricing architecture is where we run into some challenges during an XC to OrderCloud migration. As XC supports both list prices and price cards at both the sellable item level and the item variation level, including a mix of both, we’ll try and cover the most likely scenarios.

List Pricing Approach – Sellable Item Level

Starting with the most basic approach to pricing migration, sellable items have a list price policy that stores a list of multi-currency pricing. Note that item variations do not have list pricing in this example and will inherit from the sellable item. Also leaving the price card architecture out of the equation, the list pricing approach is represented in figure 5.

Figure 5: XC list pricing for sellable items and item variations.

In OrderCloud, pricing is managed via price schedule objects that are assigned to products. In order to replicate the XC architecture, a price schedule is required to represent each list price, then a product assignment is used to create the relationship between the product, the price schedule, and finally a buyer user group. The buyer user group represents the currency that will be resolved by the OrderCloud API and the custom middleware would then be responsible for moving a buyer user between the buyer groups.

This approach would only work for profiled users. See OrderCloud: How to Globalize your eCommerce for more information.

Figure 6: A multi-currency approach for profiled users.

If we only need to support a single currency then we can take advantage of a more simplified approach using just the product and price schedule, using the DefaultPriceScheduleID.

Figure 7: OrderCloud single price approach for products and products with variants.

List Pricing Approach – Item Variation Level

XC also allows for list prices to be set at the item variation level, which includes fallback to the sellable item list pricing if not supplied. Excluding the fallback pricing, we see the following representation of a sellable item with list pricing configured against the item variations in figure 8.

Figure 8: XC list pricing at the variant level.

While OrderCloud does support price markups on spec options, which does alter variant pricing, the functionality is quite rigid and we will find that we won’t be able to replicate variant level pricing that XC allows.

More information regarding product specs and price markup can be found at OrderCloud: Working with Specs – Price Markup.

Price Card Approach

Associations

In XC, a price book can be associated to multiple catalogs, which represents the price book that the catalog will attempt to resolve price cards from for a given sellable item.

Figure 9: Price Books can be associated to more than one catalog.

Price cards can be resolved, by name or by tag association, to more than one price card across multiple price books. The Commerce Engine contains some additional logic to identify the eligible price cards, prioritise them, and determine the winning price card.

Figure 10: Sellable items are resolved back to a price book based on catalog-price book associations, however multiple price cards may also be resolved. Associations may be resolved by price card name or by tag.
Scheduled Pricing

Taking a step back to look at the minimal configuration of a single price card associated to a sellable item, the price snapshots on the price card represent scheduled pricing. Each snapshot supports multi-currency tiered pricing, and also has approval workflow to prevent new pricing from accidently going live.

Figure 11: Resolving a price from a single price card association in XC.

In OrderCloud, the price schedule contains PriceBreaks, allowing for tier pricing for a single currency. The SaleStart and SaleEnd date/time properties dictate the timeframe when the SalePrice values are active, which is also flagged by the calculated property IsOnSale.

PriceSchedule assignments support price scheduling without needing to differ from the assignment architecture shown in figure 6 and figure 7.

"PriceBreaks": [
  {
    "Quantity": 1,
    "Price": 3.99,
    "SalePrice": null
  },
  {
    "Quantity": 5,
    "Price": 3.49,
    "SalePrice": 2.99
  }
],
"Currency": "USD",
"SaleStart": "2022-03-03T00:00:00+00:00",
"SaleEnd": "2022-04-03T00:00:00+00:00",
"IsOnSale": true
Challenges

With an undertanding of XC price card functionality, OrderCloud does not have the capabilities to replicate the functionality. A summary of the challenges facing price card migration are documented in the table below.

XCOrderCloud
A sellable item can resolve to multiple price cards, which has logic to prioritise and resolve a single price card.Where OrderCloud has multiple price schedules assigned at the same level of specificity, there is no logic to identify which price schedule should be prioritised, which may result in unexpected pricing being applied.
Price cards are grouped into price books, which can be resolved by the price book association of the catalog.Price schedules can be assigned to a specific buyer group, however this is not enough to replicate XC behaviour for determining price by catalog assignment.
Price cards may contain multiple price snapshots for scheduled pricing support.Price schedules allow for sale pricing, based on a specific date and time, however I future sale price cannot be prepared ahead of time if a sale price is currently active.
Using price cards without list pricing allows standard pricing to be scheduled.Price schedules only allow sale pricing to be scheduled, however the standard price may still be updated in real-time.
Price cards support multi-currency.OrderCloud has partial multi-currency support, however there is no support for products that require variant-specific pricing.
XC pricing has support for item variation-specific pricing.OrderCloud has no support for products that require variant-specific pricing, although it does have price markups per spec option, which does not align with XC’s item variation-specific pricing.
XC Price Snapshots have approval workflow.Price schedules have no approval workflow.

Data Mapping

With the conceptual analysis above, we will now review what data mapping would look like for migration and from a comparison standpoint.

In the XC Entity/Component column, components are assumed to live on the primary XC entity being mapped.

OrderCloud IDs do not allow spaces. It is important that the IDs are parsed to remove/replace invalid characters consistently.

Admin Addresses

While admin addresses are a representation of inventory sets, there are a number of mandatory fields for address details that do not exist in XC. These fields can either be filled out with dummy data or enriched with the appropriate values.

OC PropertyData TypeRequiredXC Entity/ComponentXC PropertyData TypeNotes
IDstringNoInventorySetFriendlyIdstring
CompanyNamestringNoN/AN/AN/A
FirstNamestringYesN/AN/AN/A
LastNamestringNoN/AN/AN/A
Street1stringYesN/AN/AN/ASample data will need to be supplied.
Street2stringNoN/AN/AN/A
CitystringYesN/AN/AN/ASample data will need to be supplied.
StatestringYesN/AN/AN/ASample data will need to be supplied.
ZipstringYesN/AN/AN/ASample data will need to be supplied.
CountrystringYesN/AN/AN/ASample data will need to be supplied.
PhonestringNoN/AN/AN/A
AddressNamestringNoInventorySetDisplayNamestring
xpobjectNoN/AN/AN/A
xp.DescriptionstringNoInventorySetDescriptionstring

Inventory Records

The xp in inventory records should only be mapped if they are being used in the XC implementation to avoid unnecessary bloating of the xp. The xp mapping can also be used on the product for the traditional inventory management approach.

OC PropertyData TypeRequiredXC Entity/ComponentXC PropertyData TypeNotes
productIDstringYesSellableItemFriendlyIdstring
IDstringNoInventoryInformationFriendlyIdstring
OwnerIDstringNoN/AN/AN/A
AddressIDstringNoInventorySetFriendlyIdstring
OrderCanExceedbooleanNoN/AN/AN/A
QuantityAvailableintegerNoInventoryInformationQuantityinteger
xpobjectNoN/AN/AN/A
xp.InvoiceUnitAmountdecimalNoInventoryInformationInvoiceUnitPrice.Amountdecimal
xp.InvoiceUnitCurrencystringNoInventoryInformationInvoiceUnitPrice.CurrencyCodestring
xp.PreorderablebooleanNo[PreorderableComponent]Preorderableboolean
xp.PreorderAvailabilityDatedatetimeoffsetNo[PreorderableComponent]PreorderAvailabilityDatedatetimeoffset
xp.PreorderedQuantityintegerNo[PreorderableComponent]PreorderedQuantityinteger
xp.PreorderLimitintegerNo[PreorderableComponent]PreorderLimitinteger
xp.BackorderablebooleanNo[BackorderableComponent]Backorderableboolean
xp.BackorderAvailabilityDatedatetimeoffsetNo[BackorderableComponent]BackorderAvailabilityDatedatetimeoffset
xp.BackorderedQuantityintegerNo[BackorderableComponent]BackorderedQuantityinteger
xp.BackorderLimitintegerNo[BackorderableComponent]BackorderLimitinteger

Price Schedules

As price schedules only support the equivalent of static list pricing of XC’s sellable items, this data mapping only covers this scenario.

OC PropertyData TypeRequiredXC Entity/ComponentXC PropertyData TypeNotes
OwnerIDstringNoN/AN/AN/A
IDstringNoSellableItem
[ListPricePolicy].Prices
FriendlyId
CurrencyCode
string
string
NamestringYesSellableItem
[ListPricePolicy].Prices
FriendlyId
CurrencyCode
string
string
ApplyTaxstringNoN/AN/AN/A
ApplyShippingbooleanNoN/AN/AN/A
MinQuantityintegerNoN/AN/AN/A
MaxQuantityintegerNo~[LineQuantityPolicy]MaximumdecimalXC stores this in the environment policies.
UseCumulativeQuantitybooleanNo~[RollupCartLinesPolicy]RollupbooleanXC stores this in the environment policies.
RestrictedQuantitybooleanNoN/AN/AN/A
PriceBreaksarrayNoN/AN/AN/A
PriceBreaks.QuantityintegerNoN/AN/AN/ASet to 1.
PriceBreaks.PricefloatNo[ListPricePolicy].PricesAmountdecimalFor a given price in the [ListPricePolicy].Prices array.
CurrencystringNo[ListPricePolicy].PricesCurrencyCodestringFor a given price in the [ListPricePolicy].Prices array.
xpobjectNoN/AN/AN/A

References