Edit this doc

Product Visibility

Users access products in the API through two different routes: /products and /me/products. Typically seller or supplier users have ProductAdmin or ProductReader roles allowing them to view products through the /products route. The /products route will return all products regardless of assignments, including those with Active set to false.

Buyer users on the other hand generally access products through the /me/products route. Making products appear for a Buyer user on the /me/products route requires carefully constructed catalog, price schedule, and product assignments. Below we will cover the different options for handling the /me/products visibility allowing for flexibility in the experience of different buyers.

In this guide we will explore product visibility in three different ways, it's a complex concept, but an important one to understand well.

  • : A quick and dirty checklist to double-check visibility is set up correctly
  • : A conceptual deep-dive into each piece that determines visibility

You have many options to achieve product visibility, each with a unique purpose. The path you take depends on your business requirements. By the end of this guide you will be familiar enough with the available product visibility options to choose a method that works best for your organization.

Visibility Rules Checklist

All of the following must be true for a Buyer User to see a Product (via me routes):

  • Product.Active = true
  • Catalog exists where:
    • Catalog.Active = true
    • Buyer is assigned via CatalogAssignment
    • Product is assigned via ProductCatalogAssignment
  • One of the following is true:
    • CatalogAssignment.ViewAllProducts = true, OR
    • Category exists in Catalog where
      • Active = true
      • Product assigned via CategoryProductAssignment
      • CategoryAssignment exists where
        • Buyer, User, or Group matches the user
        • ViewAllProducts = true for first non-null setting up the tree
    • ProductAssignment exists for Buyer or any Group the user belongs to (PriceScheduleID not required)

Components of Product Visibility

Buyer product visibility is powered completely via assignments. Recall that assignments are explicit meaning that, to start with, a user will have no assignments made to them and thus will not see any products.

At a high level three types of assignments need to be made before a user can begin seeing products.

  • The product is assigned to the catalog
  • The user is assigned to the catalog
  • A price schedule is assigned to the product/user

The product is assigned to the catalog

Here's our first fork in the road. An assignment can be one of two:

  • A direct product to catalog assignment
  • A product assignment to a category that is assigned to the catalog

Both of these make a product visible in a catalog. The main difference between these options is that the first enables you to create a category-less presentation.

The user is assigned to the catalog

POST https://api.ordercloud.io/v1/catalogs/assignments HTTP/1.1
Authentication: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
Content-Type: application/json; charset=UTF-8

{
	"CatalogID": "MyCatalogName"
	"BuyerID": "MyBuyerID",
	"ViewAllCategories": true,
	"ViewAllProducts": true
},

Users receive access to products when a respective catalog is assigned to the buyer company in which the user exists. The assignment format is shown above. Users receive access to all categories or products if the ViewAll configurations are set to true. If these are set false then more granular category to user or product to user assignments will be required.

These catalog level assignment configurations play very nicely with category level configurations.

POST https://api.ordercloud.io/v1/catalogs/dsf/categories/assignments HTTP/1.1
Authentication: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
Content-Type: application/json; charset=UTF-8

{
  "CategoryID": "MyCategoryID",
  "BuyerID": "MyBuyerID",
  "UserGroupID": "MyUserGroupID",
  "Visible": true,
  "ViewAllProducts": true
}

CategoryAssignment.Visible and CategoryAssignment.ViewAllProducts which have 3 possible values: true, false, or null. null means "inherit this setting from my parent", i.e. the parent category or, in the case of top-level categories, the catalog. This is a very powerful concept - it means you can set ViewAllCategories and ViewAllProducts on the CatalogAssignment, and then turn on or off either or both anywhere down the category tree. Category-level settings, whether true or false, will always override their corresponding catalog-level settings. Now your control becomes a bit more granular, but not quite down to the product level yet.

Hopefully you were able to take advantage of one of the assignment configuration options. They give you broad control and make management of your products much easier. If you do need more granular control of visibility at the product/category level we recommend setting the above mentioned configurations to false all the way down. That means the category and product must be explicitly assigned to the user in order for either to be visible to that user.

The price schedule is assigned to the product

An astute observer might have noticed that fulfilling the previous two conditions is actually sufficient to make a product "visible" however the product still doesn't have any kind of pricing (price schedule) associated with it and is therefore not "orderable". In most practical situations you're going to want the product to be orderable and so we're adding that as part of the qualification but it's good to call out in case that scenario is desirable for your use-case.

To make the product orderable we have two options:

  • Define DefaultPriceScheduleID on the product
  • Create a product assignment which forms a relationship between the product, the priceschedule and the party.

Defining a default price schedule is recommended in the majority of cases as it simplifies the management of products. You only have to worry about assigning products to users and users will see the default price. If you want a subset of users to not see the default price you still have the option of creating a product assignment in addition to the default price which will essentially override what those users see.

Exploring Product Visibility by Use Case

Scenario 1

"I want control over who sees what, but pricing usually doesn't vary from buyer to buyer."

For this scenario you should use default price schedules. Just populate DefaultPriceScheduleID on the product model, leave it out of the ProductAssignments, and those assigned parties will get the default pricing. ProductAssignment still has a PriceScheduleID, and it takes precedence over the default, but it is now optional. Giving each product a default price schedule is recommended in the majority of cases.

Scenario 2

"I want to allow some users to see certain products but not buy them."

This is a case where you would NOT use a default price schedule. If other visibility requirements are met but neither Product.DefaultPriceSchedule nor any ProductAssignment.PriceScheduleID related to the user is populated, the product will be visible to the user but not purchase-able.

Scenario 3

"When I assign a catalog to a buyer organization, I just want everybody in that organization to see everything in the catalog."

If your visibility rules are fairly simple, you'll appreciate this one. CatalogAssignment (the relationship between Catalog and Buyer organization) has these two properties: ViewAllCategories and ViewAllProducts. And yup, setting them to true does exactly what you think it does. These settings tend to go hand in hand with default price schedules; without those, you'd need to create product assignments anyway just to get pricing in place.

Scenario 4

"I want to control visibility at the category level, but when I assign a category, I want all products and subcategories within it to be visible to the assigned party automatically."

Here we get a little more fine-grained with assignments, but still not all the way down to individual products. You'll want CatalogAssignment.ViewAllCategories and CatalogAssignment.ViewAllProducts set to false, and set CategoryAssignment.Visible and CategoryAssignment.ViewAllProducts to true as needed. Note that while CatalogAssignment can only be applied to an entire buyer organization, CategoryAssignment can apply to the entire organization or a user group within it.

Scenario 5

"I want everybody to see everything except a specific category."

CategoryAssignment.Visible and CategoryAssignment.ViewAllProducts have 3 possible values: true, false, or null. null means "inherit this setting from my parent", i.e. the parent category or, in the case of top-level categories, the catalog. This is a very powerful concept - it means you turn on ViewAllCategories and ViewAllProducts on the CatalogAssignment, and then turn off either or both anywhere down the category tree. Category-level settings, whether true or false, will always override their corresponding catalog-level settings.

Scenario 6

"I want to temporarily hide an entire catalog from all buyers it's assigned to."

Product and Category have always had an Active property, independent of assignments, that allows you to effectively hide it from everyone by setting it to false. We are now adding an Active property at the Catalog level as well.

Scenario 7

"I want a search-driven catalog where products do not belong to categories."

We've already discussed that a product's assignment to a buyer party (ProductAssignment) is no longer required for visibility. The same holds true for a product's assignment to a category. As long as CatalogAssignment.ViewAllProducts is true, the only requirement for a product to become visible via search or direct link is the existence of a CatalogProductAssignment. (Note: This assignment is technically required in all product visibility scenarios. If you do not create one before assigning the product to a category, it will be created implicitly. But if it doesn't exist before creating a ProductAssignment, an error will occur. No more "floating" product-party relationships - the Catalog is King!)

Validation Rules

In order to create a ProductAssignment, the Buyer and Product must be assigned to a common Catalog (via CatalogAssignment and CatalogProductAssignment).