6.02

Product Types

Describe product types: Simple, Virtual, Configurable, Grouped, Bundle. Understand use cases, parent-child relationships, quote/order behavior, and how to obtain products by type.

Why This Matters: Understanding product types is crucial for Magento development. Each type serves specific use cases, has unique parent-child relationships, and behaves differently in cart/order tables. Less code-focused, more admin implementation—you must know when to use which type and their implications.

Product Types Overview

mindmap root((Product Types)) Simple One to one inventory mapping Basic unit Can be child in types Virtual No physical inventory Subscriptions memberships Configurable Filter down to one product Parent child relationship Global dropdown swatch attributes Grouped List of similar products Add multiple to cart at once Bundle Customer configures product Optional discount Product Type Model getTypeInstance getChildrenIds getAssociatedProducts

Simple Product

Simple products should be a 1:1 mapping of a product in Magento to an item on the shelf. The basic unit of inventory.

Use Cases

  • Package of 10 pens = box on shelf (ships as one unit)
  • Small, red t-shirt (child in configurable product)
  • 64GB memory stick (child in bundle product)

Can Be Child In

  • Configurable products
  • Bundle products
  • Grouped products
Important: A simple product cannot be a child if it has custom options. You can associate it in admin, but it won't appear on frontend.
\Magento\Catalog\Model\Product\Type\Simple

Virtual Product

Virtual products are similar to simple products except they do not represent physical inventory. They represent non-tangible goods.

Use Cases

  • Magazine subscription
  • Gym membership
  • Gift card (though Magento Commerce includes this natively)
  • Fitness coaching plan (can be bundled with physical fitness equipment)
\Magento\Catalog\Model\Product\Type\Virtual

Configurable Product

A configurable product is a tool to filter down a list of products to one product.

Setup Process

  1. Create the configurable product.
  2. Assign product attributes (global scope and dropdown or swatch type).
  3. Create or assign simple products with values for each assigned attribute.

This creates a parent-child relationship where children are simple products.

\Magento\ConfigurableProduct\Model\Product\Type\Configurable

Quote and Order Behavior

When customer selects options (e.g., Size: S, Color: Blue) and adds to cart:

quote_item table:

  • Row 1: Parent configurable product (qty = 2)
  • Row 2: Child simple product (qty = 1)

Shipped quantity: [Child Qty] × [Parent Qty] = 1 × 2 = 2 children shipped

sales_order_item table:

  • Both parent and child appear
  • qty_ordered reflects actual products being shipped
  • Only the simple child is shipped, not the parent
Key: Configurable parent helps customer select; simple child is what ships.

Base Currency Columns

Magento allows uploading prices in one currency (base currency) and converting to display currency.

  • Base currency: Currency in which product price is uploaded and order is charged.
  • Display currency: Currency shown to customer (converted from base).

Scope: Configurable via Product Price Scope (Stores > Configuration > Catalog > Pricing).

Example: Base = USD, Display = INR. Payment processor receives USD; customer sees INR.

Reporting Tip: Use base currency for consistent reporting across orders.

Grouped Product

Grouped products display a list of similar products. Unlike configurables, you can add multiple products to cart at once.

Use Cases

  • Sandpaper with different roughnesses
  • Pipe fittings in multiple sizes
  • Any scenario where customer wants multiple similar products from one page
\Magento\GroupedProduct\Model\Product\Type\Grouped

Quote and Order Behavior

After adding to cart:

quote_item table:

  • Only simple child products appear (no parent row)
  • product_type inherits from parent (shows "grouped" even though parent not in table)

sales_order_item table:

  • Same behavior—only children, product_type shows "grouped"
  • Parent grouped product doesn't exist in quote_item or sales_order_item

Bundle Product

Bundle products allow customers to configure the product they want.

Use Cases

  • Configure a computer: processor, memory, hard drive
  • Build-your-own gift basket
  • Customizable product kits

Bundle products can apply a discount to incentivize bundling vs buying individually.

\Magento\Bundle\Model\Product\Type

Quote and Order Behavior

After adding configured bundle to cart:

quote_item table:

  • Parent bundle product row
  • Child simple products rows for each selected option

sales_order_item table:

  • Parent and children both appear
  • Children are what actually ship

Obtaining Products by Type

Two approaches:

  1. SearchCriteriaBuilder with ProductRepository
  2. Product Collection with addFieldToFilter()

Approach 1: SearchCriteriaBuilder

private $productRepository;
private $searchCriteriaBuilder;

public function __construct(
    \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
    \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder
) {
    $this->productRepository = $productRepository;
    $this->searchCriteriaBuilder = $searchCriteriaBuilder;
}

public function getAllGroupedProducts(): array
{
    $criteria = $this->searchCriteriaBuilder->addFilter(
        'type_id',
        \Magento\GroupedProduct\Model\Product\Type\Grouped::TYPE_CODE
    )->create(); // Must call create()!
    
    return $this->productRepository->getList($criteria)->getItems();
}
Important: Must call create() method! SearchCriteriaBuilder doesn't inherit SearchCriteriaInterface.

Approach 2: Product Collection

private $collectionFactory;

public function __construct(
    \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $collectionFactory
) {
    $this->collectionFactory = $collectionFactory;
}

public function getAllGroupedProducts(): array
{
    $collection = $this->collectionFactory->create();
    $collection->addAttributeToSelect(['name', 'url_key']);
    $collection->addFieldToFilter(
        'type_id',
        \Magento\GroupedProduct\Model\Product\Type\Grouped::TYPE_CODE
    );
    
    return $collection->getItems();
}
Advantage: Collections only load specified attributes, reducing overhead.

Product Model vs Product Type Model

There are two parts to a product:

  1. Product Model: \Magento\Catalog\Model\Product (implements ProductInterface)
  2. Product Type Model: e.g., \Magento\GroupedProduct\Model\Product\Type\Grouped (extends AbstractType)

Why Two Models?

  • Product Model: Doorway to product—contains data (ID, SKU, name, etc.).
  • Product Type Model: Contains methods specific to this product type.

Access type model via: $product->getTypeInstance()

Product Type Model Methods (Example: Grouped)

  • getChildrenIds(): Find product IDs of all child products.
  • getParentIdsByChild(): Find all parents associated with a child.
  • getAssociatedProducts(): Load all products associated with parent.

Review These Files

  • \Magento\Catalog\Model\Product\Type\AbstractType
  • \Magento\Catalog\Model\Product\Type\Simple
  • \Magento\Catalog\Model\Product\Type\Virtual
  • \Magento\Downloadable\Model\Product\Type
  • \Magento\ConfigurableProduct\Model\Product\Type\Configurable
  • \Magento\Bundle\Model\Product\Type
  • \Magento\GroupedProduct\Model\Product\Type\Grouped

Cart Rendering for Configurable/Bundle

To understand how bundle/configurable products render in cart:

  1. Locate bundle product on frontend (e.g., /sprite-yoga-companion-kit.html).
  2. Add to cart, go to cart page.
  3. Inspect element in Chrome DevTools → look for "item-options".
  4. Search for template: Magento/Checkout/view/frontend/templates/cart/item/default.phtml
  5. Find layout handle: checkout_cart_item_renderers
  6. Examine checkout_cart_item_renderers.xml for renderer blocks.
  7. Block: checkout.cart.item.renderers (declared in checkout_cart_index.xml).
Debugging Tip: Search for "item-options" in template files, filter by .phtml to narrow results.

Further Reading

Exam Tips

  • Simple: 1:1 inventory; can be child in configurable/bundle/grouped; NOT if has custom options.
  • Virtual: No physical inventory; subscriptions, memberships.
  • Configurable: Filter to one product; global dropdown/swatch attributes; parent + child in quote/order; only child ships.
  • Grouped: Add multiple to cart; only children in quote/order tables; product_type inherits "grouped".
  • Bundle: Customer configures; discount option; parent + children in tables.
  • Obtaining Products: SearchCriteriaBuilder (call create()!) or Collection (addFieldToFilter).
  • Type Model: getTypeInstance() for type-specific methods.
  • Base Currency: Upload price currency; used for payment and reporting.