Tutorial

How to create a Product Bundle

Let’s assume our shop offers winter sports equipment, namely snowboards, bindings, boots and so on. The snowboards in this example do not have bindings assembled by default so the customer needs to attach some bindings first before he or she can get out to the slope. Therefore it makes sense to offer the customers some product bundles containing a plain snowboard and a pair of bindings.

Image Product Bundle

In this tutorial we are going to explain how you can model such product bundles with the data models provided by the commercetools™ platform.

Prerequisites

Before starting this tutorial you need to have valid credentials for accessing commercetools™ platform projects. If you need assistance with that please have a look at Getting Started with the commercetools™ platform.

We assume that your project already contains the products to be bundled.

Create ProductType for bundles

In this tutorial we are going to explain how you can model product bundles like the snowboard/binding-bundle with the data models provided by the commercetools™ platform.

The approach to follow is to create a particular ProductType that is made for bundles containing two or more different products.

We could extend the product bundle even further by adding a pair boots to the board and binding. To keep it simple we’ll stick to a bundle of two products for now, one snowboard and one binding. The diagram below shows the custom attributes board and binding that we need to define for our SnowboardBundle ProductType.

Image ProductType Bundle

As you can see in the diagram, the values of the attributes are particular Products. Therefore we need to define the type of the board and binding attributes as such. The commercetools™ platform provides the ReferenceType for those attributes that refer to other commercetools™ platform objects. The ReferenceType fits best to our use case when we further specify to what sort of object the attributes should refer to. The commercetools supports several objects, but as shown in the diagram above we want the attributes refer to a Product.

Now let’s create our SnowboardBundle ProductType at the ↗ Admin Center EU (or ↗ Admin Center US ). If you are not yet familiar with this tool we recommend you studying the Getting Started with the commercetools™ platform first.

If you would like to know how to create the SnowboardBundle ProductType with the API instead of the Admin Center, please head to the respective API tutorial.

On the Admin Center’s Developers View we’ll find the PRODUCT TYPES tab where we are able to create our new product type:

Image ProductType Bundle 1

After clicking the + symbol in the New product type box we’ll type in the name and a description of our bundle product type, like shown below:

Image ProductType Bundle 2

After hitting the Create button, we’ll have the opportunity to specify the attributes of our new bundle product type. Let’s start with creating the board attribute.
On the New attribute drop-down menu we can see which attributes types are available in the commercetools™ platform. As explained before, we need a ReferenceType for our purpose and so we’ll select this type like shown below:

Image ProductType Bundle 3

On the following page we’ll give the attribute the name board as well as a respective label:

Image ProductType Bundle 4

We need to make sure we select product for the TYPE field since our bundle contains products we like to refer to with this attribute. We don’t put any constraints on this attribute here, so we’ll keep it to NONE. But we need to tick the box for the Required flag to make sure that the bundle must contain a board. By selecting Searchable we make sure the product bundle will be indexed when searching for the referenced product. Upon save we’ll see the following overview of our bundle product type:

Image ProductType Bundle 5

We’ll repeat the last steps for creating the binding attribute in the same way, so that we end up with this overview of the bundle product type:

Image ProductType Bundle 6

We just have extended our existing bundle ProductType with two attributes of the ReferenceType. We have further specified that the attributes board and binding contain references to Products. Both attributes have been defined as required and searchable.

Create Product bundle

As we now have created the ProductType for our product bundle we are now able to create concrete product bundles. In this section are going to create the “Bundle Feather Cartel” made of following products already stored in our project:

"Bundle Feather Cartel"
board "Feather 56" binding "Cartel R"
a snowboard a binding
173€ in all countries for all customer groups 115€ in all countries for all customer groups


To create the bundle it is enough to specify the references to those two existing products; there is no need to repeat specifications of “Feather 56” and “Cartel R”. Thus the values of attributes board and binding contain the identifiers of those products only.

This section of the tutorial explains how to create a product bundle with the ↗ Admin Center EU (or ↗ Admin Center US ). If you want to know how to do the same with the API, we recommend studying the API tutorial dedicated to this.
In the Products view of the Admin Center, we’ll click on the + button to add our new product:

Image Bundle Product 1

We’ll select our SnowboardBundle product type we created before:

Image Bundle Product 2

We’ll give the product bundle a name and a description:

Image Bundle Product 3

and we’ll enter the product-IDs of the products we want to have in our bundle; namely the resource-ID of the “Feather 56” snowboard and the “Cartel R” binding.
The Admin Center evaluates those identifiers and gives an error in case they do not belong to products.
After we saved the product we can see it in the Overview tab where we could set additional attributes:

Image Bundle Product 4

Since the ‘OVERVIEW’ tab doesn’t show the values of our custom attributes board and binding we’ll need to look deeper into the Product to verify what we’ve created before.

Verify created Product bundle

We’ll find the custom attributes board and binding of our product bundle on the VARIANTS tab of the Product view in the Admin Center as depicted below:

Image Bundle Product 5

As you can see, the reference attributes are filled with the resource IDs of the board and the binding products the bundle contains. From this view you can’t see any more information about the bundled products, only by using the API’s Reference Expansion feature you can retrieve the product data of the board and the binding too with just one request to the platform.
This feature is not yet supported by the Admin Center, but in the next section we’ll explain how Reference Expansion can be used on the Impex Tools and API Playground EU (works in the same way on the Impex Tools and API Playground US ).

Using Reference Expansion

To showcase what Reference Expansion means we will query the product bundle we created in the previous section of this tutorial. In this section we are using the Impex Tools and API Playground EU (works in the same way on the Impex Tools and API Playground US ) for requesting the API, but if you want to use any other HTTP client of your choice, please head to the API tutorial to find more information.

We want to query the Bundle Product by its resource ID on the Product Projections API Endpoint. Before we can do so, we need to find out the resource ID and the projection of the product we query for. Let’s have a look at the Bundle Product in the Admin Center again:

Image Get Bundle Product 0

The resource ID of the Bundle Product we’ll get from the URL of the Bundle Product’s overview page. This ID will be different to the one shown in the screenshot above. All resource IDs are unique on the commercetools™ platform and so it will be different in your personal project. If the cloud symbol looks like the one in the red circle above it indicates that the product has not yet been published and it is still the staged representation we’ll see here. We need those information in the API Playground now for our query on the Product Projections API endpoint:

Image Get Bundle Product 1

We assume that you have filled the Project Credentials already as explained in the Getting Started article. Since we use the Query by ID method, we need to fill the resource ID of the Bundle Product (that we got from the Admin Center URL before) into the field Resource ID. We also make sure we have the Staged projection selected before we hit the GO!!! button.
The response to the query should look like the one shown below:

{
  "id": "<snowboard-bundle-product-id>",
  "version": 1,
  "productType": {
    "typeId": "product-type",
    "id": "<snowboard-bundle-product-type-id>"
  },
  "name": {
    "en": "Bundle Feather Cartel"
  },
  "description": {
    "en": "<p>bundle of board Feather 56 and binding Cartel R</p>"
  },
  "categories": [],
  "slug": {
    "en": "bundle-feather-cartel-1434718221140"
  },
  "masterVariant": {
    "id": 1,
    "prices": [],
    "images": [],
    "attributes": [ {
      "name": "board",
      "value": {
        "typeId": "product",
        "id": "<snowboard-Feather-56-product-id>"
      }
    }, {
      "name": "binding",
      "value": {
        "typeId": "product",
        "id": "<binding-Cartel-R-product-id>"
      }
    } ]
  },
  "variants": [],
  "searchKeywords": {},
  "hasStagedChanges": false,
  "published": false,
  "createdAt": "2015-06-19T12:54:07.503Z",
  "lastModifiedAt": "2015-06-19T12:54:07.503Z"
}

As we see the in the JSON response the bundled products (the snowboard “Feather 65” and the binding “Cartel R”) are just mentioned by their Resource IDs marked as:

"<snowboard-Feather-56-product-id>"

and

"<binding-Cartel-R-product-id>"

Those placeholders are shown as proper resource IDs in your response, but they still do not provide enough information about the products themselves. In order to get the full information about the single products you will have to make additional requests on the product API endpoint by using the single product’s resource IDs.
Of course, you can do it this way, but by using commercetools™ platform’s Reference Expansion feature you’ll get the product representations of snowboard “Feather 56” and binding “Cartel R” embedded into the “Bundle Feather Cartel” product representation so that you don’t need additional requests.

To retrieve the entire product information including the bundled products we’ll add the Expand parameter to the request, like this:

Image Get Bundle Product 2

The Expand parameter tells the commercetools™ platform to expand the values on the attributes of the bundle product’s master ProductVariant. This is just a special case for this tutorial in which the bundle product has just one variant. All other variants of the product will not be expanded by using Reference Expansion on the Master Variant only. You can find more about this in the API tutorial.
Please find below the response to the query request containing the product information of the bundled products as result of the Reference Expansion:

{
  "id": "<snowboard-bundle-product-id>",
  "version": 1,
  "productType": {
    "typeId": "product-type",
    "id": "<snowboard-bundle-product-type-id>"
  },
  "name": {
    "en": "Bundle Feather Cartel"
  },
  "description": {
    "en": "<p>bundle of board Feather 56 and binding Cartel R</p>"
  },
  "categories": [],
  "slug": {
    "en": "bundle-feather-cartel-1434718221140"
  },
  "masterVariant": {
    "id": 1,
    "prices": [],
    "images": [],
    "attributes": [ {
      "name": "board",
      "value": {
        "typeId": "product",
        "id": "<snowboard-Feather-56-product-id>",
        "obj": {
          "id": "<snowboard-Feather-56-product-id>",
          "version": 1,
          "productType": {
            "typeId": "product-type",
            "id": "<snowboard-product-type-id>"
          },
          "catalogs": [],
          "masterData": {
            "current": {
              "name": {
                "en": "Feather-56"
              },
              "description": {
                "en": "<p>board \"Feather 56\"</p>"
              },
              "categories": [],
              "slug": {
                "en": "feather-56-1434717727520"
              },
              "masterVariant": {
                "id": 1,
                "prices": [],
                "images": [],
                "attributes": []
              },
              "variants": [],
              "searchKeywords": {}
            },
            "staged": {
              "name": {
                "en": "Feather-56"
              },
              "description": {
                "en": "<p>board \"Feather 56\"</p>"
              },
              "categories": [],
              "slug": {
                "en": "feather-56-1434717727520"
              },
              "masterVariant": {
                "id": 1,
                "prices": [],
                "images": [],
                "attributes": []
              },
              "variants": [],
              "searchKeywords": {}
            },
            "published": false,
            "hasStagedChanges": false
          },
          "catalogData": {},
          "lastVariantId": 1,
          "createdAt": "2015-06-19T12:41:54.630Z",
          "lastModifiedAt": "2015-06-19T12:41:54.630Z"
        }
      }
    },
      {
        "name": "binding",
        "value": {
          "typeId": "product",
          "id": "<binding-Cartel-R-product-id>",
          "obj": {
            "id": "<binding-Cartel-R-product-id>",
            "version": 1,
            "productType": {
              "typeId": "product-type",
              "id": "<binding-product-type-id>"
            },
            "catalogs": [],
            "masterData": {
              "current": {
                "name": {
                  "en": "Cartel R"
                },
                "description": {
                  "en": "<p>binding \"Cartel R\"</p>"
                },
                "categories": [],
                "slug": {
                  "en": "cartel-r-1434717970161"
                },
                "masterVariant": {
                  "id": 1,
                  "prices": [],
                  "images": [],
                  "attributes": []
                },
                "variants": [],
                "searchKeywords": {}
              },
              "staged": {
                "name": {
                  "en": "Cartel R"
                },
                "description": {
                  "en": "<p>binding \"Cartel R\"</p>"
                },
                "categories": [],
                "slug": {
                  "en": "cartel-r-1434717970161"
                },
                "masterVariant": {
                  "id": 1,
                  "prices": [],
                  "images": [],
                  "attributes": []
                },
                "variants": [],
                "searchKeywords": {}
              },
              "published": false,
              "hasStagedChanges": false
            },
            "catalogData": {},
            "lastVariantId": 1,
            "createdAt": "2015-06-19T12:45:49.963Z",
            "lastModifiedAt": "2015-06-19T12:45:49.963Z"
          }
        }
      } ]
  },
  "variants": [],
  "searchKeywords": {},
  "hasStagedChanges": false,
  "published": false,
  "createdAt": "2015-06-19T12:54:07.503Z",
  "lastModifiedAt": "2015-06-19T12:54:07.503Z"
}

The whole representations of the single products are now part of the response encapsulated as obj.
In the next section we’ll show you that you can search for products that are part of a bundle.

Search for the bundles that contain a particular Product

Let’s say you want to search for the bundles that contain the binding “Cartel R”. For this you would use the Product Projection Search functionality provided by the commercetools™ platform. In this section we’ll use the Impex Tools and API Playground EU (works in the same way on the Impex Tools and API Playground US ) for demonstration, but you can use any other HTTP client instead as described in the API tutorial.

For our search request we’ll set the filter expression to the binding attribute and the product id of the binding “Cartel R” as value like shown in the figure below:

Image Search Bundled Product

Remark: At the search endpoint you have the opportunity to search for either the current or the staged ProductProjections. If you want to search for the unpublished products you need to set the Projection to Staged as in the figure above, but if you want to search for published products you need to set this switch to Current.

In the response to our search request you’ll find the ‘Bundle Feather Cartel’ product that contains the binding “Cartel R”.

As just demonstrated, you can search for products that are part of bundles in the commercetools™ platform. Please bare in mind that this will only work if you’ve configured the respective attribute (binding in this case) as Searchable in the product type definition beforehand as explained in the first section of this tutorial.

comments powered by Disqus