# Company-specific Product catalogs In the [Model your business structure](/learning-model-your-business-structure) path you used [Product Selections](/api/projects/product-selections.md) to give different brand sites different assortments. The B2B problem is the same shape with a different driver: instead of a brand or region, the assortment is scoped to a **buyer organization**. This page assumes you know what a Product Selection is and focuses on the B2B-specific configuration and the one behavior that most often trips architects up. ## Restricting a catalog to a buyer A buyer organization sees a restricted catalog because of a chain you already assembled in Module 1: the **Business Unit resolves to a Store**, and the **Store carries the Product Selections**. That Store can be assigned directly or inherited from the Business Unit hierarchy. You do not assign Products to a Business Unit directly. You scope the Store, and the Business Unit inherits that scope by resolving to it. This indirection is deliberate. Because the restriction lives on the Store, you can point several Business Units at the same Store to share an assortment, or give a Division its own Store (using the Store Override Rule from Module 1) when it needs a different one. The catalog follows the Store, not the buyer. The default is permissive: a **Store with no Product Selections includes every Product in the Project**. Restriction is something you add deliberately by attaching at least one Product Selection. Product Selections are the standard way to restrict a buyer's catalog, but they are not the only one. Some sellers drive restriction through search instead: middleware passes the buyer's price Channel, inventory Channel, or Customer Group as filter criteria on a Product Search query, so results return only the Products that match the buyer's negotiated scope. This approach is a more advanced customization that suits sellers who already resolve a buyer's catalog from pricing context rather than Store-attached selections. For scoping search to a buyer's context, see [Product Search for B2B catalogs](/learning-model-b2b-commerce/discover-and-order-products-in-b2b/product-search-for-b2b-catalogs.md). ## Choosing a mode: Individual vs IndividualExclusion A Product Selection specifies a subset of the catalog in one of two modes. You pick the mode based on which list is shorter to maintain. - **[`Individual`](/api/projects/product-selections.md#mode-individual)**: use this as an allowlist when the buyer should see a small, curated slice of the catalog. - **[`IndividualExclusion`](/api/projects/product-selections.md#mode-individual-exclusion)**: use this as a denylist when the buyer should see most of the catalog, with only a few restricted lines removed. The two modes describe the same assortment from opposite ends. A buyer who may see 200 of 5,000 Products is far easier to model with `Individual`; a buyer who may see 4,950 of 5,000 is far easier to model with `IndividualExclusion`. The mode is fixed when you create the Product Selection, so choose based on how the assortment will be maintained over time, not just its initial size. The following request creates an `Individual` Product Selection for Pacific Property Group's Commercial division. With `Individual` mode, the selection starts empty and you add Products to it explicitly. ```http POST /{projectKey}/product-selections HTTP/1.1 Content-Type: application/json { "key": "pacific-commercial-assortment", "name": { "en-AU": "Pacific Commercial assortment" }, "mode": "Individual" } ``` In the response, `mode` confirms the selection's behavior and `productCount` starts at zero until you add Products. ```json { "id": "b2c3d4e5-1111-2222-3333-444455556666", "version": 1, "key": "pacific-commercial-assortment", "name": { "en-AU": "Pacific Commercial assortment" }, "mode": "Individual", "productCount": 0 } ``` Before the selection changes a Store assortment, assign Products to it with the [Add Product](/api/projects/product-selections.md#add-product) update action. The Store attachment only activates the Products already assigned to the Product Selection. ## Attaching selections to a Store A Product Selection has no effect until a Store uses it. Attaching it both links the selection and sets whether it is **active** for that Store. ```http POST /{projectKey}/stores/key=pacific-commercial-store HTTP/1.1 Content-Type: application/json { "version": 2, "actions": [ { "action": "addProductSelection", "productSelection": { "typeId": "product-selection", "key": "pacific-commercial-assortment" }, "active": true } ] } ``` The `active` flag defaults to `false`. Omitting it attaches the selection in an inactive state, so its Products do **not** become part of the assortment until you activate it. Set `active: true` explicitly when you intend the selection to take effect immediately. A Store can hold more than one Product Selection, and its assortment is the **union of all active selections**. This is the standard pattern for "shared base plus buyer-specific extras": attach one shared Product Selection that every buyer's Store includes, and supplement it with a buyer-specific selection on each Store. For the field-level definition of the active flag, see [ProductSelectionSetting](/api/projects/stores.md#productselectionsetting). ## The inactive-selection trap The behavior that most often surprises architects is the difference between **no selections** and **inactive selections**, and it depends on the mode of the inactive selections: - A Store with **no Product Selections** includes **all** Products in the Project. - A Store with **at least one active** Product Selection includes only the Products in its **active** selections. - A Store whose selections are **all inactive** and include at least one **`Individual`** selection includes **no** Products at all, an empty assortment. - A Store whose only selections are **inactive `IndividualExclusion`** selections still includes **all** Products in the Project. The trap is specific to assortments built with `Individual` selections: deactivating the last active selection does not fall back to "show everything." It falls forward to "show nothing." A buyer whose Store has one or more `Individual` selections attached but all of them inactive sees an empty catalog and cannot place an order, even though the Project is full of Products. There are two ways to fall into this trap. The first is **deactivating** the Store's last active selection. The second is quieter: because `active` defaults to `false`, **attaching** a selection without setting `active: true` adds it in an inactive state. A Store whose only `Individual` selection was added with the default flag is already empty, before anyone deactivates anything. Deactivating every Product Selection on a Store does **not** automatically revert it to showing all Products. If any of those inactive selections uses `Individual` mode, the assortment becomes empty; only a Store with **no** Product Selections, or one left with solely inactive `IndividualExclusion` selections, shows the full catalog. When troubleshooting an unexpectedly empty B2B catalog, check the `active` flag and mode on each of the Store's Product Selections before anything else. You toggle the active state with the Change Product Selection Active action. The following request deactivates a selection, the operation behind an empty-assortment incident if it is the Store's only selection. ```http POST /{projectKey}/stores/key=pacific-commercial-store HTTP/1.1 Content-Type: application/json { "version": 3, "actions": [ { "action": "changeProductSelectionActive", "productSelection": { "typeId": "product-selection", "key": "pacific-commercial-assortment" }, "active": false } ] } ``` ## Worked example: Pacific Property Group Pacific Property Group is a Company with two Divisions, Residential and Commercial. Both buy from Zen Electron Trade's catalog, but Commercial is entitled to a broader range that includes commercial-grade appliances Residential should not see. A clean way to model this with the shared-base pattern: 1. **Create a shared Product Selection** in `Individual` mode, `zen-trade-core`, holding the Products both Divisions may buy. Attach it, active, to both Divisions' Stores. 2. **Create a Commercial-only Product Selection** in `Individual` mode, `pacific-commercial-assortment`, holding only the commercial-grade Products. Attach it, active, to the Commercial Store only. 3. **Residential's Store** carries just `zen-trade-core`; its assortment is the shared range. 4. **Commercial's Store** carries `zen-trade-core` plus `pacific-commercial-assortment`; its assortment is the union: the shared range plus commercial-grade lines. Residential and Commercial now see different catalogs from the same underlying Products, with no duplication. If a future audit requires temporarily pulling the commercial-grade range, you deactivate `pacific-commercial-assortment` on the Commercial Store, and because `zen-trade-core` is still active there, the Store falls back to the shared range rather than to an empty assortment, avoiding the inactive-selection trap. Had you instead modeled Commercial with a **single** selection covering its full range, deactivating it would have emptied the Store entirely. Keeping the shared base as its own always-active selection is what makes the configuration safe to change. ## Key takeaways - A buyer's catalog is restricted by attaching Product Selections to the buyer's Store; Products are never assigned to a Business Unit directly. - A Store with no Product Selections shows every Product; restriction is something you add deliberately. - `Individual` mode lists the Products to include; `IndividualExclusion` lists the Products to exclude. Choose the mode whose list is shorter to maintain. - A Store's assortment is the union of its active Product Selections, which enables a shared-base-plus-buyer-specific pattern. - Deactivating every selection on a Store empties it when any inactive selection uses `Individual` mode, rather than reverting to the full catalog: the inactive-selection trap. ## Related pages - [Area overview page with navigation](/learning-model-b2b-commerce.md) - [Previous page: Resource clustering: a unifying model](/learning-model-b2b-commerce/design-b2b-catalogs/resource-clustering.md) - [Next page: Product Tailoring for B2B](/learning-model-b2b-commerce/design-b2b-catalogs/product-tailoring-for-b2b.md)