Variants

Summary

Overview

The goal of the variant module is to group similar products to push them as models & children in the PIM. Note that despite this module being exclusively used by Akeneo PIM customers, it is built, like the rest of the app, to be compatible with different systems. That's why SDM may not always assume the same things as it would when solely using Akeneo.

The grouping of products can be done automatically based on simple rules. See the automation keyword in the Configuration section below.

Note that this module does not assume that a specific "parent" row exists in the input file. The parent will be created automatically when products are grouped.

 

Interface & Use Cases

More info in our dedicated guide

 

The top of the screen is similar to other table-based modules: some clickable stats filters with 4 groups :

  • Rows to add in product model (red): rows that still have to be processed. As for all others, this step can't be finalized if there are still rows to process.
  • Rows added in product model by you (green): rows that the user has manually grouped
  • Independent rows: rows marked by the user as having no parent, will be pushed as simple products in the PIM

⬇️ Then there are two tables, the first one, on the left, shows all products matching the current filter grouped by product model. This table has a "Group" column used to show which products can be grouped inside a product model. The second table, on the right, lists product models created by the user.

Grouping the products

When selecting multiple ungrouped products (in the left table) you can use the "Create a product model" button. This will open the following pop-up allowing you to add the following information :

The id of the product model: this is used internally to know which products belong together and will be stored in an attribute (see product_model_name_column config entry). This will also be used as the id of the product model when pushing to the PIM.

The variant columns: the columns marked as variant are attributes whose values are allowed to change for each product related to the product model.

The parent row: one row must be selected as "parent". What it means is that every attribute not marked as variant, when the step is done, will be set to the same value as for the parent.

When grouping products, there are multiple validations done based on the matching_groups configuration.

  1. If allow_product_model_without_matching_group is disabled SDM checks that all the products being grouped all have a matching group.
  2. SDM checks that the products grouped together belong to the same matching group, otherwise, the creation/update is rejected
  3. Finally, based on the matching group SDM also checks that the set unique_columns all have different values. For instance, SDM can't group two blue, size L, t-shirts if they only unique_columns are "size" and "color".

Configuration

This configuration has been moved to the connector

 

How does it work with the Akeneo connector?

For project creation

By default the connector does not leverage variants, this has to be activated. To do that, simply set use_variants it to true. This will do multiple things :

  1. The family hierarchy will be changed from one level (just the families) to two levels (the families and all their variant families as children).
  2. When creating the steps for the project, instead of having the boilerplate Akeneo project:

The project gets more complicated with:

The reason the project is done that way is to reduce the amount of duplicated work:

  1. first, SDM only works on variant attributes for products that have a family variant assigned. That way SDM will work on most products BUT only on a limited set of attributes and SDM makes sure not to fill multiple times an attribute that will have the same value because it belongs to a model and not a child.
  2. Then at the variant step, it is automatically configured to only output "parents" and "independent". That means that the following steps will be only working on simple products or product models.
  3. From that point, SDM works on all attributes.

The Variant step is configured entirely and the matching_groups entry is made to represent variant families. SDM does not make the distinction between variant families with one or two axes of variation. Everything is flattened to just one level and will be reconstructed during the push. Each family variant is configured as a matching group with the following config in the connector:

  • name: id of the family variant
  • label: translations of the family variant
  • conditions: rules that check that the "family_variant" attribute is not empty and matches the id of the family variant.
  • unique_columns: list all variation axes from both levels
  • variant_columns: list all variant attributes from both levels
  • invariant columns: empty list

One last thing done when generating the config is making sure that variation axes are marked as required even if a max_requirement_level is set. SDM do that because if a variation axis is empty, the PIM refuses the push so SDM need to force the value to be filled.

 

For project config updates

When a config sync is triggered for a connector, the Variant step config is automatically updated. Specifically, SDM makes sure that the matching_groups entry is kept up to date to be able to properly validate created groups.

Note that for now, a config sync, if there is not exactly one Variant step in the project, will trigger an error if the option "use_variants" is active in the connector.

 

For pushing to the PIM

When a job is done, if a connector is linked to said job's project and the push is activated then SDM pushes products in multiple stages :

  1. SDM pushes simple products directly
  2. SDM identifies all products marked as "parent" and pushes them as product models. The id of the product model is the id of that the user filled in when creating the group.
  3. For variant families with two axes of variations, SDM randomly selects one "parent" for each unique set of values in the first variation axis. 
    From that, SDM creates an intermediary parent who carries the first axis attributes and has for id the id of the parent concatenated with the values of the first axis. So for instance if we have t-shirts varying by color then size and one parent has the id "tshirt-collection-aw25" then the blue t-shirt intermediary parent regrouping the different sizes would have "tshirt-collection-aw25-blue" as the id.
  4. Finally, SDM creates all children as products linked to the appropriate parent (first or second level depending on the family variant).

Configuration exemple

Here is a sample of the variant_params as generated by the Akeneo Connector (with just one matching group for readability).

{
  "export_data": [
    "parent",
    "child",
    "independent"
  ],
  "output_data": [
    "parent",
    "independent"
  ],
  "matching_groups": [
    {
      "name": "fam_bathroom_sink_variant_1",
      "label": {
        "fr-FR": "Vasque - Forme, couleur"
      },
      "conditions": [
        {
          "name": "required",
          "field": "family",
          "negate": false
        },
        {
          "name": "isin",
          "field": "family",
          "negate": false,
          "values": [
            "fam_bathroom_sink"
          ]
        },
        {
          "name": "required",
          "field": "family_variant",
          "negate": false
        },
        {
          "name": "isin",
          "field": "family_variant",
          "negate": false,
          "values": [
            "fam_bathroom_sink_variant_1"
          ]
        }
      ],
      "unique_columns": [
        "product_shape",
        "product_color"
      ],
      "variant_columns": [
        "parcel_send_to_effitrace",
        "product_CBM",
        "product_PVR_TTC_PCS",
        "product_PVR_TTC_PCS-currency",
        "product_color",
        "product_depth",
        "product_depth-unit",
        "product_description_instructions-fr_FR",
        "product_diameter",
        "product_diameter-unit",
        "product_ean",
        "product_from_prestashop",
        "product_height",
        "product_height-unit",
        "product_origin_description",
        "product_origin_image_url",
        "product_origin_informations",
        "product_origin_name",
        "product_supplier_reference",
        "product_suppliers_purchase_price_per_pcs",
        "product_suppliers_purchase_price_per_pcs-currency",
        "product_variant_name-fr_FR",
        "product_weight",
        "product_weight-unit",
      ],
      "invariant_columns": []
    }
  ],
  "variant_columns": [],
  "default_id_column": "code_modele",
  "invariant_columns": [],
  "product_model_head_column": {
    "name": "is_parent",
    "label": {
      "fr": "est un parent"
    }
  },
  "product_model_name_column": {
    "name": "akeneo_parent_id",
    "label": {
      "fr": "Akeneo parent id"
    }
  },
  "allow_product_model_without_matching_group": false
}

Variant family as configured in client's PIM

{
    "code": "fam_bathroom_sink_variant_1",
    "labels": {
        "fr_FR": "Vasque - Forme, couleur"
    },
    "variant_attribute_sets": [
        {
            "axes": [
                "product_shape"
            ],
            "level": 1.0,
            "attributes": [
                "product_name",
                "product_styles",
                "product_summary",
                "product_seo_description",
                "product_height",
                "product_width",
                "product_depth",
                "product_diameter",
                "product_weight",
                "product_shape",
                "product_instruction_file",
                "product_installation_vid",
                "product_schema_pics",
                "product_description",
                "product_main_points",
                "product_long_name",
                "product_description_instructions",
                "product_syphon_diameter"
            ]
        },
        {
            "axes": [
                "product_color"
            ],
            "level": 2.0,
            "attributes": [
                "sku",
                "product_step_of_publication",
                "product_is_dropshipped",
                "parcel_send_to_effitrace",
                "product_color",
                "product_origin_name",
                "product_origin_description",
                "product_supplier_reference",
                "product_CBM",
                "product_suppliers_purchase_price_per_pcs",
                "product_packshot_pics",
                "product_ambience_pics",
                "product_zoom_pics",
                "product_influencers_pics",
                "product_trace_file",
                "product_PVR_TTC_PCS",
                "product_ean",
                "product_variant_full_name",
                "parcel",
                "product_origin_informations",
                "product_origin_image_url",
                "product_from_prestashop",
                "product_reverse_full_name",
                "product_variant_name",
                "product_total_parcel_qty",
                "product_reverse_variant_name_2"
            ]
        }
    ]
}

What you can see is that :

  • SDM output both “parent” and “independent” to make sure SDM fills all necessary attributes
  • The variant family (see in toggle) has two variation axes combined into a single matching group
  • They have in their input file the information of the product model name so default_id_column is filled.

Glossary

  • Parent products: this refers to a product model. It has no variation notion, only “common” attributes. This product is not real: it cannot be bought. One parent product may be linked to many child products.
  • Child products: this refers to products that can be bought. The child product has all of the variation notions (variant columns), which differentiate it from other child products.
  • Independant products: Product that has no product model attached to, no variation notion. Also called “simple products”. All fields composing an independent product are common.