Configurable Product Overview
Configurable vs Simple
Simple Product:
TSHIRT-BLUE-L → Single SKU, one variant
Configurable Product:
TSHIRT → Parent product (no stock)
├── TSHIRT-BLUE-L → Child (simple product)
├── TSHIRT-BLUE-M → Child (simple product)
├── TSHIRT-RED-L → Child (simple product)
└── TSHIRT-RED-M → Child (simple product)
Configurable Product Structure
-- Parent configurable product
SELECT entity_id, sku, type_id
FROM catalog_product_entity
WHERE entity_id = 100;
+-----------+--------+--------------+
| entity_id | sku | type_id |
+-----------+--------+--------------+
| 100 | TSHIRT | configurable |
+-----------+--------+--------------+
-- Child simple products
SELECT entity_id, sku, type_id
FROM catalog_product_entity
WHERE entity_id IN (101, 102, 103, 104);
+-----------+---------------+--------+
| entity_id | sku | type_id|
+-----------+---------------+--------+
| 101 | TSHIRT-BLUE-L | simple |
| 102 | TSHIRT-BLUE-M | simple |
| 103 | TSHIRT-RED-L | simple |
| 104 | TSHIRT-RED-M | simple |
+-----------+---------------+--------+
Link Table
-- catalog_product_super_attribute (configurable attributes)
SELECT * FROM catalog_product_super_attribute WHERE product_id = 100;
+----------+------------+---------------+------------+
| product_id | attribute_id | position | label |
+----------+------------+---------------+------------+
| 100 | 92 | 1 | Color |
| 100 | 136 | 2 | Size |
+----------+------------+---------------+------------+
-- catalog_product_super_link (parent-child)
SELECT * FROM catalog_product_super_link WHERE parent_id = 100;
+----------+------------+
| parent_id | product_id |
+----------+------------+
| 100 | 101 |
| 100 | 102 |
| 100 | 103 |
| 100 | 104 |
+----------+------------+
Configurable Attributes
Creating Configurable Product
// Create configurable product
$configurableProduct = $objectManager->get(
\Magento\Catalog\Model\ProductFactory::class
)->create();
$configurableProduct->setName('T-Shirt')
->setSku('TSHIRT')
->setPrice(29.99)
->setStatus(1)
->setVisibility(4)
->setAttributeSetId(4)
->setTypeId('configurable')
->save();
// Create configurable attributes
$configurableProduct = $objectManager->get(
\Magento\Catalog\Model\Product\Configurable\Factory::class
)->create();
$configurableOptions = [
[
'attribute_id' => 92, // color attribute
'code' => 'color',
'label' => 'Color',
'position' => 1,
'values' => [
['value_index' => 10, 'label' => 'Blue'],
['value_index' => 14, 'label' => 'Red'],
]
],
[
'attribute_id' => 136, // size attribute
'code' => 'size',
'label' => 'Size',
'position' => 2,
'values' => [
['value_index' => 166, 'label' => 'L'],
['value_index' => 167, 'label' => 'M'],
]
]
];
$configurableProduct->setConfigurableOptions($configurableOptions);
$configurableProduct->save();
Add Child Products
// Create child products
$childProducts = [
['sku' => 'TSHIRT-BLUE-L', 'color' => 10, 'size' => 166],
['sku' => 'TSHIRT-BLUE-M', 'color' => 10, 'size' => 167],
['sku' => 'TSHIRT-RED-L', 'color' => 14, 'size' => 166],
['sku' => 'TSHIRT-RED-M', 'color' => 14, 'size' => 167],
];
foreach ($childProducts as $childData) {
$child = $objectManager->get(
\Magento\Catalog\Model\ProductFactory::class
)->create();
$child->setName('T-Shirt ' . $childData['color'] . ' ' . $childData['size'])
->setSku($childData['sku'])
->setPrice(29.99)
->setStatus(1)
->setVisibility(1) // Not visible individually
->setAttributeSetId(4)
->setTypeId('simple')
->setStockData(['qty' => 50, 'is_in_stock' => 1])
->save();
// Link to parent
$link = $objectManager->get(
\Magento\ConfigurableProduct\Model\LinkFactory::class
)->create();
$link->setProductId($child->getId())
->setParentId($configurableProduct->getId())
->setPosition(0)
->save();
}
Pricing for Configurables
Price Configuration
// Configurable product price (base)
$configurableProduct->setPrice(29.99);
// Child product prices (can differ)
$child->setPrice(29.99); // Same as parent
// Or different:
$child->setPrice(34.99); // Premium variant
// Special price on parent
$configurableProduct->setSpecialPrice(24.99);
// Special price on child
$child->setSpecialPrice(27.99);
Price Index
-- Price index includes all combinations
SELECT * FROM catalog_product_index_price
WHERE entity_id IN (100, 101, 102, 103, 104)
AND customer_group_id = 0 AND website_id = 1;
+-----------+-------------------+-----------+-------+-------+--------+
| entity_id | customer_group_id | website_id | price | final_price | min_price |
+-----------+-------------------+-----------+-------+-------+--------+
| 100 | 0 | 1 | 29.99 | 29.99 | 29.99 |
| 101 | 0 | 1 | 29.99 | 29.99 | 29.99 |
| 102 | 0 | 1 | 29.99 | 29.99 | 29.99 |
| 103 | 0 | 1 | 34.99 | 34.99 | 34.99 |
| 104 | 0 | 1 | 34.99 | 34.99 | 34.99 |
+-----------+-------------------+-----------+-------+-------+--------+
Price Display
// Get configurable product price range
$priceInfo = $configurableProduct->getPriceInfo();
$minPrice = $priceInfo->getPrice('final_price')->getMinimalPrice();
$maxPrice = $priceInfo->getPrice('final_price')->getMaximalPrice();
// Get price for specific option
$optionPrice = $priceInfo->getPrice('final_price')->getValue();
// Display price range on frontend
// $29.99 - $34.99
Stock Management
Stock Configuration
// Configurable product stock (not tracked)
$configurableProduct->setStockData([
'use_config_manage_stock' => 1,
'is_in_stock' => 1, // Based on children
'manage_stock' => 0, // Don't manage parent stock
]);
// Child product stock (tracked)
$child->setStockData([
'qty' => 50,
'is_in_stock' => 1,
'manage_stock' => 1,
]);
Stock Status Logic
Configurable product is in stock if:
✓ At least ONE child product is in stock
Configurable product is out of stock if:
✗ ALL child products are out of stock
Example:
TSHIRT-BLUE-L: qty=50 (in stock)
TSHIRT-BLUE-M: qty=0 (out of stock)
TSHIRT-RED-L: qty=0 (out of stock)
TSHIRT-RED-M: qty=25 (in stock)
→ TSHIRT (configurable) is IN STOCK
Stock Index
-- Check stock status for configurable
SELECT entity_id, is_salable
FROM cataloginventory_stock_status
WHERE product_id = 100;
+-----------+-----------+
| product_id | is_salable |
+-----------+-----------+
| 100 | 1 |
+-----------+-----------+
-- Check child stock
SELECT product_id, qty, is_salable
FROM cataloginventory_stock_status
WHERE product_id IN (101, 102, 103, 104);
+-----------+------+-----------+
| product_id | qty | is_salable |
+-----------+------+-----------+
| 101 | 50 | 1 |
| 102 | 0 | 0 |
| 103 | 0 | 0 |
| 104 | 25 | 1 |
+-----------+------+-----------+
Best Practices
1. Create simple products first, then configurable
2. Set child visibility to 1 (not visible individually)
3. Use meaningful SKUs for variants
4. Manage stock on child products
5. Set appropriate prices per variant
6. Test all option combinations
7. Use swatch attributes for visual selection
Quiz
1. What is a configurable product?
2. What visibility should child products have?
3. When is a configurable product in stock?
Flashcards
Question
What is a configurable product?
Click to reveal answer
Answer
Parent product with child simple products as variants (size, color, etc.)
Question
What is child product visibility?
Click to reveal answer
Answer
1 (Not Visible Individually) - only configurable shows
Question
How is stock managed?
Click to reveal answer
Answer
On child products - configurable is in stock if any child is in stock
Question
What are configurable attributes?
Click to reveal answer
Answer
Attributes defining variants (color, size, material)
Question
How to link children to parent?
Click to reveal answer
Answer
catalog_product_super_link table with parent_id and product_id
Revision Notes
Key Takeaways
- 1. Configurable products are parents with child simple products as variants
- 2. Child products have visibility=1 (not visible individually)
- 3. Stock managed on children - configurable in stock if any child is
- 4. Configurable attributes define variant options (color, size)
- 5. Price can differ between parent and children
Interview Tips
- • Explain the relationship between configurable and simple products
- • Discuss stock management logic for configurables
- • Describe how price ranges work for configurable products
Cheat Sheet
Configurable Product:
type_id = 'configurable'
Parent with child variants
Tables:
catalog_product_super_attribute → Configurable attributes
catalog_product_super_link → Parent-child links
Child Products:
type_id = 'simple'
visibility = 1 (not visible)
SKU = variant-specific
Stock:
Parent: manage_stock=0
Child: manage_stock=1, qty tracked
In stock if ANY child is in stock
Price:
Parent: base price
Child: can differ per variant
Display: price range