Skip to content
intermediate Phase 45 · Checkout Fundamentals

Quote Items

Working with Quote items - adding products, quantity, options, customizable options, and bundle options

45m
0 problems
Topic Progress 0%

Adding Products to Quote

Quote::addProduct Method

The primary way to add items to a quote:

// Adding a simple product
$quote->addProduct(
    $product,
    new \Magento\Framework\DataObject([
        'product' => $product->getId(),
        'qty' => 2,
    ])
);

// Adding a configurable product
$quote->addProduct(
    $product,
    new \Magento\Framework\DataObject([
        'product' => $product->getId(),
        'qty' => 1,
        'super_attribute' => [
            92 => '53',  // attribute_id => option_id
            136 => '167',
        ],
    ])
);

// Adding a bundle product
$quote->addProduct(
    $product,
    new \Magento\Framework\DataObject([
        'product' => $product->getId(),
        'qty' => 1,
        'bundle_option' => [
            1 => [2, 3],  // option_id => [selection_ids]
        ],
    ])
);

BuyRequest Processing

namespace Magento\Quote\Model\Quote\Item;

class Resolver
{
    public function resolve(\Magento\Catalog\Model\Product $product, $requestInfo): mixed
    {
        $buyRequest = new \Magento\Framework\DataObject($requestInfo);

        $productType = $product->getTypeId();

        switch ($productType) {
            case 'configurable':
                return $buyRequest->getData('super_attribute');
            case 'bundle':
                return $buyRequest->getData('bundle_option');
            case 'grouped':
                return $buyRequest->getData('super_group');
            default:
                return $buyRequest->getData('options');
        }
    }
}

Product Type Handling

Simple Products

$quote->addProduct($product, [
    'product' => $product->getId(),
    'qty' => 1,
]);

Configurable Products

// Must specify which options (super attributes) are selected
$quote->addProduct($product, [
    'product' => $product->getId(),
    'qty' => 1,
    'super_attribute' => [
        // attribute_id => option_id
        92 => '53',   // Color: Blue
        136 => '167', // Size: Large
    ],
]);

// The simple product matching those options is resolved automatically

Bundle Products

// Must specify which selections are included
$quote->addProduct($product, [
    'product' => $product->getId(),
    'qty' => 1,
    'bundle_option' => [
        // option_id => selection_id(s)
        1 => [2],      // RAM: 8GB (single selection)
        2 => [4, 5],   // Storage: 256GB + 512GB (multiple selections)
    ],
]);

Grouped Products

// Specify quantity for each associated simple product
$quote->addProduct($product, [
    'product' => $product->getId(),
    'super_group' => [
        // associated_product_id => qty
        101 => 2,  // Simple Product A: qty 2
        102 => 1,  // Simple Product B: qty 1
    ],
]);

Custom Options

Product Custom Options

// Products can have custom options defined in admin
$quote->addProduct($product, [
    'product' => $product->getId(),
    'qty' => 1,
    'options' => [
        // option_id => value
        1 => 'Engrave text here',       // Text field
        2 => 'Gift wrapping',           // Dropdown selection
        3 => '2024-12-25',              // Date field
    ],
]);

Reading Custom Options from Quote Item

// After adding to quote, options are stored on the item
$items = $quote->getItems();

foreach ($items as $item) {
    $options = $item->getOptions();

    foreach ($options as $option) {
        if ($option->getCode() === 'info_buyRequest') {
            $buyRequest = $option->getValue();
            // Contains the original request data including options
        }

        if ($option->getCode() === 'additional_options') {
            $additionalOptions = $option->getValue();
        }
    }
}

Customizing Quote Item Options

// Add additional options to an existing quote item
$item->addOption(
    new \Magento\Quote\Model\Quote\Item\Option([
        'code' => 'additional_options',
        'value' => json_encode([
            ['label' => 'Gift Wrapping', 'value' => 'Yes'],
        ]),
    ])
);

Item Quantities and Updates

Updating Quantities

// Update quantity for specific item
$quote->updateItem($itemId, ['qty' => 5]);

// Remove an item
$quote->removeItem($itemId);

// Recalculate after changes
$quote->collectTotals()->save();

Quantity Validation

namespace Magento\Quote\Model\Quote\Item;

class QtyValidator
{
    public function validate(
        \Magento\Catalog\Model\Product $product,
        float $qty
    ): bool {
        // Check minimum qty
        if ($qty < $product->getQtyMin()) {
            return false;
        }

        // Check maximum qty
        if ($product->getQtyMax() && $qty > $product->getQtyMax()) {
            return false;
        }

        // Check stock availability
        $stockItem = $this->stockRegistry->getStockItem($product->getId());
        if ($qty > $stockItem->getQty()) {
            return false;
        }

        return true;
    }
}

Quiz

1. How do you add a configurable product to a quote?

Question 1 options

2. What data structure does bundle_option use?

Question 2 options

3. Where are custom options stored on a quote item?

Question 3 options

Flashcards

Question

How to add a simple product to quote?

Answer

$quote->addProduct($product, ['product' => $id, 'qty' => 1])

Question

Configurable product data key?

Answer

super_attribute: [attribute_id => option_id]

Question

Bundle product data key?

Answer

bundle_option: [option_id => [selection_ids]]

Question

Grouped product data key?

Answer

super_group: [associated_product_id => qty]

Revision Notes

Key Takeaways

  • 1. Quote::addProduct() is the primary method for adding items
  • 2. Each product type requires different buy request data (super_attribute, bundle_option, super_group)
  • 3. Custom options are stored as quote item options with code 'info_buyRequest'
  • 4. Item quantities can be updated via updateItem() or removeItem()
  • 5. Always call collectTotals() after modifying items

Interview Tips

  • Explain how different product types affect the addProduct call
  • Describe the flow from addProduct() to quote item creation
  • Discuss how custom options are persisted in the database

Cheat Sheet

Quote Items:
  Simple:    ['product' => id, 'qty' => n]
  Config:     ['super_attribute' => [attr_id => opt_id]]
  Bundle:     ['bundle_option' => [opt_id => [sel_ids]]]
  Grouped:    ['super_group' => [prod_id => qty]]
  Custom:     ['options' => [opt_id => value]]

Options stored as Item\Option:
  code: 'info_buyRequest' → original request
  code: 'additional_options' → extra customizations