The Quote Model
What is a Quote?
The Quote is the central object in Magento's checkout process. It represents a shopping cart and holds all the information needed to create an order.
Quote Entity Structure
// Magento\Quote\Model\Quote
namespace Magento\Quote\Model;
class Quote extends \Magento\Framework\DataObject implements
\Magento\Quote\Api\CartInterface,
\Magento\Quote\Api\CartRepositoryInterface
{
/**
* Get quote ID
*/
public function getId(): ?int
{
return $this->getData('entity_id');
}
/**
* Get store ID
*/
public function getStoreId(): int
{
return (int) $this->getData('store_id');
}
/**
* Get customer ID (0 for guest)
*/
public function getCustomerId(): int
{
return (int) $this->getData('customer_id');
}
/**
* Get quote items
*/
public function getItemsCollection(): \Magento\Quote\Model\Resource\Model\Quote\Item\Collection
{
if (!$this->hasItemsCollection()) {
$this->setItemsCollection(
$this->itemsCollectionFactory->create()->setQuoteFilter($this)
);
}
return $this->getData('items_collection');
}
}
Quote Data Fields
| Field | Description |
|---|---|
| entity_id | Primary key |
| store_id | Store the quote belongs to |
| customer_id | Customer ID (0 for guest) |
| customer_email | Customer email address |
| customer_group_id | Customer group for pricing |
| reserved_order_id | Reserved order ID |
| coupon_code | Applied coupon code |
| subtotal | Subtotal before discounts |
| grand_total | Final total |
| items_qty | Total quantity of items |
| is_active | Whether quote is active |
Quote Items
Quote Item Structure
Each product in the cart is represented by a Quote Item:
// Magento\Quote\Model\Quote\Item
namespace Magento\Quote\Model\Quote;
class Item extends \Magento\Framework\DataObject implements
\Magento\Quote\Api\CartItemInterface
{
/**
* Get product ID
*/
public function getProduct(): \Magento\Catalog\Api\Data\ProductInterface
{
return $this->getData('product');
}
/**
* Get quantity
*/
public function getQty(): float
{
return (float) $this->getData('qty');
}
/**
* Get row total
*/
public function getRowTotal(): float
{
return (float) $this->getData('row_total');
}
/**
* Get custom options
*/
public function getOptionsByCode(): array
{
return $this->getData('options_by_code') ?? [];
}
}
Adding Items to Quote
namespace Vendor\Checkout\Service;
class CartManager
{
public function __construct(
private \Magento\Quote\Api\CartRepositoryInterface $cartRepository,
private \Magento\Quote\Api\ProductRepositoryInterface $productRepository
) {}
public function addProductToCart(
int $quoteId,
int $productId,
float $qty = 1.0
): \Magento\Quote\Api\Data\CartInterface {
$quote = $this->cartRepository->get($quoteId);
$product = $this->productRepository->getById($productId);
$request = new \Magento\Framework\DataObject([
'product' => $productId,
'qty' => $qty,
]);
$quote->addProduct($product, $request);
$quote->save();
return $quote;
}
}
Cart Persistence
Quote Storage Architecture
Magento stores quotes in the quote and quote_item database tables:
-- Quote table
CREATE TABLE quote (
entity_id INT AUTO_INCREMENT PRIMARY KEY,
store_id SMALLINT UNSIGNED NOT NULL,
customer_id INT UNSIGNED DEFAULT 0,
customer_email VARCHAR(255),
customer_group_id SMALLINT UNSIGNED DEFAULT 0,
reserved_order_id VARCHAR(64),
coupon_code VARCHAR(255),
subtotal DECIMAL(12,4) DEFAULT 0,
grand_total DECIMAL(12,4) DEFAULT 0,
items_qty DECIMAL(12,4) DEFAULT 0,
is_active TINYINT(1) DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- Quote item table
CREATE TABLE quote_item (
item_id INT AUTO_INCREMENT PRIMARY KEY,
quote_id INT UNSIGNED NOT NULL,
product_id INT UNSIGNED NOT NULL,
qty DECIMAL(12,4) NOT NULL DEFAULT 1,
price DECIMAL(12,4) NOT NULL,
discount_amount DECIMAL(12,4) DEFAULT 0,
row_total DECIMAL(12,4) NOT NULL DEFAULT 0,
options TEXT,
FOREIGN KEY (quote_id) REFERENCES quote(entity_id)
);
Guest vs Customer Quotes
// Guest quote - stored with session ID
$quote->setCustomerId(0);
$quote->setCustomerEmail('guest@example.com');
$quote->setReservedOrderId('100000001');
// Customer quote - linked to customer account
$quote->setCustomerId($customer->getId());
$quote->setCustomerGroupId($customer->getGroupId());
Quote Merging
// When guest logs in, merge guest quote with customer quote
namespace Magento\Quote\Model\QuoteMerge;
class Merge implements \Magento\Quote\Model\QuoteMerge\MergeInterface
{
public function merge(
\Magento\Quote\Model\Quote $source,
\Magento\Quote\Model\Quote $destination
): \Magento\Quote\Model\Quote {
foreach ($source->getItems() as $item) {
try {
$destination->addProduct(
$item->getProduct(),
$item->getBuyRequest()
);
} catch (\Exception $e) {
// Skip items that can't be added
$this->logger->critical($e);
}
}
$source->setIsActive(0)->save();
$destination->save();
return $destination;
}
}
Quote Management API
Cart Repository API
// Magento\Quote\Api\CartRepositoryInterface
namespace Magento\Quote\Api;
interface CartRepositoryInterface
{
/**
* Get quote by ID
*/
public function get(int $cartId): \Magento\Quote\Api\Data\CartInterface;
/**
* Get active customer quote
*/
public function getActiveForCustomer(int $customerId): \Magento\Quote\Api\Data\CartInterface;
/**
* Save quote
*/
public function save(\Magento\Quote\Api\Data\CartInterface $quote);
/**
* Delete quote
*/
public function delete(\Magento\Quote\Api\Data\CartInterface $quote);
}
Creating Quotes Programmatically
namespace Vendor\Checkout\Service;
class QuoteManager
{
public function __construct(
private \Magento\Quote\Model\QuoteFactory $quoteFactory,
private \Magento\Quote\Api\CartRepositoryInterface $cartRepository
) {}
public function createEmptyQuote(int $storeId, int $customerId = 0): \Magento\Quote\Api\Data\CartInterface
{
$quote = $this->quoteFactory->create();
$quote->setStoreId($storeId);
$quote->setCustomerId($customerId);
$quote->setIsActive(1);
$quote->save();
return $quote;
}
public function getOrCreateQuote(int $storeId, int $customerId): \Magento\Quote\Api\Data\CartInterface
{
try {
$quote = $this->cartRepository->getActiveForCustomer($customerId);
} catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
$quote = $this->createEmptyQuote($storeId, $customerId);
}
return $quote;
}
}
Quiz
1. What does the Quote model represent in Magento?
2. How are guest quotes identified?
3. What happens when a guest customer logs in with an existing cart?
Flashcards
Question
What is a Quote in Magento?
Click to reveal answer
Answer
The central checkout object representing a shopping cart with items, customer data, and totals
Question
Quote vs Order?
Click to reveal answer
Answer
Quote is the cart (mutable), Order is the placed purchase (immutable)
Question
How are quote items stored?
Click to reveal answer
Answer
In quote_item table linked to quote by quote_id foreign key
Question
Guest quote identification?
Click to reveal answer
Answer
customer_id = 0, identified by session ID and email
Revision Notes
Key Takeaways
- 1. Quote is Magento's shopping cart model, central to checkout
- 2. Quote items store product references, quantities, options, and row totals
- 3. Quotes persist in quote and quote_item database tables
- 4. Guest quotes (customer_id=0) are merged with customer quotes on login
- 5. Quote management APIs allow programmatic cart creation and manipulation
Interview Tips
- • Explain the Quote lifecycle: create → add items → shipping → payment → place order
- • Describe how guest and customer quotes differ in storage and identification
- • Discuss quote merging logic when a guest converts to a registered customer
Cheat Sheet
Quote System:
Quote = Shopping Cart (mutable)
Quote Items = Products in cart
Guest: customer_id = 0
Customer: customer_id > 0
Tables:
quote (entity_id, store_id, customer_id, grand_total)
quote_item (item_id, quote_id, product_id, qty, price)
Merge Flow:
Guest Login → Merge guest quote → Customer quote → Guest quote deactivated