Show Different Catalogs for Different Customer Types
With Ucommerce comes multi-channel functionality which is the ability to show different stores and catalogs with a different look and feel on different domains. Sometimes settings up multiple stores with multiple domains may be overkill. But if you still want to differentiate what different customer types see, you can do that by redirecting your customers to different catalogs based on your own business logic. This article will describe how to set that up.
Understanding Catalog Context
To help you know what a customer is currently browsing in your store, context is exposed via our Catalog Context. You'll know which store, catalog, category, and product the customer is currently browsing. In these context classes, you can also set up your own business logic for what a customer is currently looking at. This is what we want to Leverage in this article. All Libraries are context-aware, which means that the libraries will adhere to what the context says - or in the end, what your business logic says.
Ucommerce.Api.ICatalogContext
CurrentCatalogGroup
- Return type
Ucommerce.Search.Models.ProductCatalogGroup
CurrentCatalog
- Return type
Ucommerce.Search.Models.ProductCatalog
CurrentProduct
- Return type
Ucommerce.Search.Models.Product
CurrentCategory
- Return type
Ucommerce.Search.Models.Category
CurrentPriceGroup
- Return type
Ucommerce.Search.Models.PriceGroup
CurrentCategories
- Return type
ICollection<Ucommerce.Search.Models.Category>
Setting up a custom Catalog Context
In our case, we can inherit the existing implementation of Ucommerce.Api.ICatalogContext
which is implemented by Ucommerce.Api.CatalogContext
Let's see how it is done:
public class DifferentiateOnCustomerType : Ucommerce.Api.CatalogContext { public DifferentiateOnCustomerType() { } }
We could also choose to implement the interface from scratch, but for two reasons we do not want to do that in this particular case.
- We are only interested in changing behavior for the catalog part,
- If we are unable to decide in our implementation we can let the default implementation kick in.
This means that we can now override that specific property that determines the catalog.
public override ProductCatalog CurrentCatalog { get { return base.CurrentCatalog; } set { base.CurrentCatalog = value; } }
Now we just need to figure out what our business logic should be. Here comes reason number two why deriving from the default implementation is good. If we for some reason cannot figure out or decide what catalog to resolve, we'll just let the default implementation decide.
In our case, we want to resolve a catalog based on the customer type. Let's just go ahead and create two catalogs in the backend under our store called "private" and "public".
Now that we have those, let's resolve the catalog based on a naming convention, just to keep it simple.
public override ProductCatalog CurrentCatalog { get { //figure out the best way to find the currentCustomerType name. string currentCustomerType = GetCurrentCustomerType(); Ucommerce.Search.Models.ProductCatalog catalog = this.CatalogIndex.Find().Where(x => x.Name == GetCurrentCustomerType()).FirstOrDefault(); if (catalog == null) { return base.CurrentCatalog; } return catalog; } set { this.CurrentCatalog = value; } } protected virtual string GetCurrentCustomerType() { return "private"; }
The code above is quite simple. We query a product catalog based on the name, that we need to find. Notice on line 9 that we're returning base.CurrentCatalog if we cannot find an appropriate one. This is a good pattern as we can always rely on Ucommerce to use its own logic if our custom logic fails somehow. This might give unexpected results though, so make sure the default behavior suites your needs.
All there's left to do is following the article on how to register a custom component so we make sure that our new logic is used.