Loading...
Area: Optimizely Commerce
Applies to versions: 10 and higher
Other versions:

Catalog DTO and object models

Recommended reading 
Note: This documentation is for the preview version of the upcoming release of CMS 12/Commerce 14/Search & Navigation 14. Features included here might not be complete, and might be changed before becoming available in the public release. This documentation is provided for evaluation purposes only.

This topics describes how to work with caching and catalog entry DTOs (Data Transfer Objects) in Optimizely Commerce.

Catalog entry DTOs and caching

DTOs are simple objects that carry data between processes. Catalog entry DTOs transfer data between an application and the database.

[New in Commerce 14]
Catalog entry DTOs are cached based on CatalogOptions

Example:

"EPiServer": {
  "Commerce": {
    "CatalogOptions": {
      "Cache": {
        "UseCache": true,
        "ContentVersionCacheExpiration": "00:15:00",
        "CollectionCacheExpiration": "00:15:00",
        "EntryCacheExpiration": "00:15:00",
        "NodeCacheExpiration": "00:15:00"
      }
    }
  }
}

During development, it can be beneficial to disable caching. When deploying your e-commerce site, enable catalog caching, and use cache timeouts appropriate for your requirements and environment.

CatalogEntry DTOs are cached based on the response group(s) used to retrieve them. Types of CatalogEntry response groups:

  • Request
  • CatalogEntryInfo
  • CatalogEntryFull
  • Associations
  • Children
  • Assets
  • Nodes
  • Variants
  • Inventory
  • RecursiveAssociations

Catalog entry objects vs. catalog entry DTOs

Entry objects are used to further abstract catalog entry DTOs.

namespace Mediachase.Commerce.Catalog.Objects
{
    /// <summary>
    /// The Entry parameter serves as a container element that is a child of the Entries element, and
    /// represents the Catalog Entry element, which can be Product, Variant, Bundle or any other type of product.
    /// </summary>
    [Serializable]
    public class Entry
    {
    }
}

Entry objects are not cached, but the underlying DTOs from which they are constructed are cached.

Catalog guidelines

Importing using API

Example: Using the Catalog API data transfer objects (DTOs) to create a catalog entry. The CatalogContext is the main entry point to the Catalog system.

private void SampleEntryAdd()
{
  int catalogId = 2;
 
  // Get a CatalogDto object.
  CatalogDto catalogDto = CatalogContext.Current.GetCatalogDto(catalogId, new CatalogResponseGroup(CatalogResponseGroup.ResponseGroup.CatalogInfo));
 
  if (catalogDto.Catalog.Count > 0)
  {
    // Get a CatalogEntryDto object.
    CatalogEntryDto entry = CatalogContext.Current.GetCatalogEntryDto("PRODUCT_CODE",
      new CatalogEntryResponseGroup(CatalogEntryResponseGroup.ResponseGroup.CatalogEntryInfo));
 
    if (entry.CatalogEntry.Count == 0)
    {
      // Get a new entry row for your catalog entry.
      CatalogEntryDto.CatalogEntryRow newEntryRow = entry.CatalogEntry.NewCatalogEntryRow();
 
      // Set entry properties.
      newEntryRow.ApplicationId = AppContext.Current.ApplicationId;
      newEntryRow.CatalogId = catalogDto.Catalog[0].CatalogId;
      newEntryRow.ClassTypeId = "Variation";
      newEntryRow.Code = "PRODUCT_CODE";
      newEntryRow.EndDate = DateTime.Now.AddYears(2).ToUniversalTime();
      newEntryRow.IsActive = true;
      newEntryRow.MetaClassId = 32;
      newEntryRow.Name = "PRODUCT_NAME";
      newEntryRow.StartDate = DateTime.UtcNow;
      newEntryRow.TemplateName = "DigitalCameras"; // system-defined template of type 'entry'
      newEntryRow.SetSerializedDataNull();
      if (newEntryRow.RowState == DataRowState.Detached)
        entry.CatalogEntry.AddCatalogEntryRow(newEntryRow);
 
      // Set variation properties.
      CatalogEntryDto.VariationRow newVariationRow = entry.Variation.NewVariationRow();
      newVariationRow.ListPrice = Convert.ToDecimal(1000.00);
      newVariationRow.MaxQuantity = 50;
      newVariationRow.SetMerchantIdNull();
      newVariationRow.MinQuantity = 5;
      newVariationRow.PackageId = 0;
      newVariationRow.TaxCategoryId = 0;
      newVariationRow.TrackInventory = true;
      newVariationRow.WarehouseId = 0;
      newVariationRow.Weight = Convert.ToDouble(4);
      newVariationRow.CatalogEntryId = entry.CatalogEntry[0].CatalogEntryId;
      if (newVariationRow.RowState == DataRowState.Detached)
        entry.Variation.AddVariationRow(newVariationRow);
 
      // Set inventory properties.
      CatalogEntryDto.InventoryRow newInventoryRow = entry.Inventory.NewInventoryRow();
      newInventoryRow.AllowBackorder = false;
      newInventoryRow.AllowPreorder = false;
      newInventoryRow.ApplicationId = AppContext.Current.ApplicationId;
      newInventoryRow.BackorderAvailabilityDate = DateTime.UtcNow;
      newInventoryRow.BackorderQuantity = 0;
      newInventoryRow.InStockQuantity = Convert.ToDecimal(75);
      newInventoryRow.InventoryStatus = 1;
      newInventoryRow.PreorderAvailabilityDate = DateTime.UtcNow;
      newInventoryRow.PreorderQuantity = 0;
      newInventoryRow.ReorderMinQuantity = 15;
      newInventoryRow.ReservedQuantity = 10;
      newInventoryRow.SkuId = "mark_test7";
      if (newInventoryRow.RowState == DataRowState.Detached)
        entry.Inventory.AddInventoryRow(newInventoryRow);
 
      // Set seo properties.
      CatalogEntryDto.CatalogItemSeoRow newSeoRow = entry.CatalogItemSeo.NewCatalogItemSeoRow();
      newSeoRow.ApplicationId = AppContext.Current.ApplicationId;
      newSeoRow.CatalogEntryId = entry.CatalogEntry[0].CatalogEntryId;
      newSeoRow.CatalogNodeId = 62;
      newSeoRow.Description = "DESCRIPTION";
      newSeoRow.LanguageCode = "en-us";
      newSeoRow.Uri = "SEO-FRIENDLY-URL.aspx";
      if (newSeoRow.RowState == DataRowState.Detached)
        entry.CatalogItemSeo.AddCatalogItemSeoRow(newSeoRow);
 
      // Save the entry.
      CatalogContext.Current.SaveCatalogEntry(entry);
 
      // Save the metadata attributes associated with the catalog entry.
      MetaDataContext metaContext = new MetaDataContext();
      MetaClass metaClass = MetaClass.Load(metaContext, "Publications");
      MetaObject metaObj = MetaObject.NewObject(metaContext, entry.CatalogEntry[0].CatalogEntryId, metaClass.Id, "name");
      MetaHelper.SetMetaFieldValue(metaContext, metaObj, "Title", new object[] { "New Book Title" });
      MetaHelper.SetMetaFieldValue(metaContext, metaObj, "ID", new object[] { "New Id" });
      MetaHelper.SetMetaFieldValue(metaContext, metaObj, "Description", new object[] { "New Description" });
      MetaHelper.SetMetaFieldValue(metaContext, metaObj, "Theme", new object[] { "New Book Title" });
      MetaHelper.SetMetaFieldValue(metaContext, metaObj, "Highlight", new object[] { false });
      metaObj.AcceptChanges(metaContext);
 
      // Set the entry node relation.
      CatalogRelationDto relation = new CatalogRelationDto();
      CatalogRelationDto.NodeEntryRelationRow nodeRelation = relation.NodeEntryRelation.NewNodeEntryRelationRow();
      nodeRelation.CatalogId = 2;
      nodeRelation.CatalogEntryId = entry.CatalogEntry[0].CatalogEntryId;
      nodeRelation.CatalogNodeId = 62;
      nodeRelation.SortOrder = 0;
      if (nodeRelation.RowState == DataRowState.Detached)
        relation.NodeEntryRelation.AddNodeEntryRelationRow(nodeRelation);
 
      // Save the relation.
      CatalogContext.Current.SaveCatalogRelationDto(relation);
    }
  }
}

Importing multiple language metadata

Example: Creating metadata in multiple languages for a catalog, using the MetaHelper.SetMetaFieldValue method.

MetaDataContext MDContext = CatalogContext.MetaDataContext;

  MDContext.UseCurrentUICulture = false;
  //string 
  foreach (string language in Languages)
    {
      MDContext.Language = language;
      MetaHelper.SetMetaFieldValue(metaobj)...
      metaObj.AcceptChanges(MDContext);
    }
  MDContext.UseCurrentUICulture = true; 
Do you find this information helpful? Please log in to provide feedback.

Last updated: Jul 02, 2021

Recommended reading