Base Price and Special Price
Price Types
-- Base price (stored in EAV)
SELECT value AS price FROM catalog_product_entity_decimal
WHERE entity_id = 123 AND attribute_id = 75 AND store_id = 0;
+--------+
| price |
+--------+
| 29.9900|
+--------+
-- Special price (discounted)
SELECT value AS special_price FROM catalog_product_entity_decimal
WHERE entity_id = 123 AND attribute_id = 76 AND store_id = 0;
+---------------+
| special_price |
+---------------+
| 24.9900 |
+---------------+
-- Special price dates
SELECT value AS special_from FROM catalog_product_entity_datetime
WHERE entity_id = 123 AND attribute_id = 101 AND store_id = 0;
+---------------------+
| special_from |
+---------------------+
| 2024-01-01 00:00:00 |
+---------------------+
Price Attributes
| Attribute | Code | Type | Description |
|---|---|---|---|
| Price | price | decimal | Base price |
| Special Price | special_price | decimal | Discounted price |
| Special From | special_from_date | datetime | Discount start |
| Special To | special_to_date | datetime | Discount end |
| Tax Class | tax_class_id | int | Tax classification |
Price Configuration
// Set base price
$product->setPrice(29.99);
// Set special price
$product->setSpecialPrice(24.99);
// Set special price dates
$product->setSpecialFromDate('2024-01-01');
$product->setSpecialToDate('2024-12-31');
// Get final price (considers special price)
$finalPrice = $product->getFinalPrice();
// Get price without tax
$price = $product->getPrice();
Tier Price and Group Price
Tier Pricing (Quantity Discounts)
// Set tier prices
$tierPrices = [
[
'website_id' => 0,
'cust_group' => 1, // General group
'price_qty' => 10,
'price' => 25.00,
],
[
'website_id' => 0,
'cust_group' => 1,
'price_qty' => 50,
'price' => 20.00,
],
];
$product->setData('tier_price', $tierPrices);
$product->save();
Tier Price Calculation
Product price: $29.99
Tier 1: 10+ qty → $25.00 (17% off)
Tier 2: 50+ qty → $20.00 (33% off)
Example: Customer buys 25 units
Base: 25 × $29.99 = $749.75
Tier 1: 25 × $25.00 = $625.00
Savings: $124.75 (17%)
Group Price
// Set group prices
$groupPrices = [
[
'cust_group' => 1, // General
'price' => 27.00,
],
[
'cust_group' => 2, // Wholesale
'price' => 22.00,
],
];
$product->setData('group_price', $groupPrices);
$product->save();
Price Hierarchy
Final Price Calculation:
1. Base price
2. Special price (if active)
3. Group price (if applicable)
4. Tier price (if quantity qualifies)
5. Catalog price rules (if applicable)
6. Cart price rules (coupons)
Priority: Special → Group → Tier → Rules
Price Index
Price Index Structure
-- catalog_product_index_price
SELECT * FROM catalog_product_index_price
WHERE entity_id = 123 AND customer_group_id = 0 AND website_id = 1;
+-----------+-------------------+-----------+-------+-------+--------+
| entity_id | customer_group_id | website_id | price | final_price | min_price |
+-----------+-------------------+-----------+-------+-------+--------+
| 123 | 0 | 1 | 29.99 | 29.99 | 29.99 |
+-----------+-------------------+-----------+-------+-------+--------+
-- With special price
+-----------+-------------------+-----------+-------+-------+--------+
| entity_id | customer_group_id | website_id | price | final_price | min_price |
+-----------+-------------------+-----------+-------+-------+--------+
| 123 | 0 | 1 | 29.99 | 24.99 | 24.99 |
+-----------+-------------------+-----------+-------+-------+--------+
-- With tier price
+-----------+-------------------+-----------+-------+-------+--------+
| entity_id | customer_group_id | website_id | price | final_price | min_price |
+-----------+-------------------+-----------+-------+-------+--------+
| 123 | 0 | 1 | 29.99 | 24.99 | 20.00 |
+-----------+-------------------+-----------+-------+-------+--------+
Index Columns
| Column | Description |
|---|---|
| entity_id | Product ID |
| customer_group_id | Customer group |
| website_id | Website ID |
| tax_class_id | Tax class |
| orig_price | Original price |
| price | Current price |
| min_price | Minimum price (tier) |
| max_price | Maximum price |
| tier_price | Tier price |
| tier_price_incl_tax | Tier price with tax |
Reindex Prices
# Reindex product prices
bin/magento indexer:reindex catalog_product_price
# Check status
bin/magento indexer:status catalog_product_price
# Set mode
bin/magento indexer:set-mode realtime catalog_product_price
bin/magento indexer:set-mode schedule catalog_product_price
Price Query with Index
// Use index for fast price access
$collection = $productCollection->create();
$collection->addAttributeToSelect(['name', 'sku'])
->joinPriceIndex() // Joins index table
->addFieldToFilter('price', ['gteq' => 10])
->addFieldToFilter('price', ['lteq' => 50]);
// Without index: multiple EAV JOINs
// With index: single JOIN on flat price table
Price Display and Currency
Price Display
// Get formatted price
$formattedPrice = $priceCurrency->format($product->getFinalPrice());
// Returns: $29.99
// Get price range (configurable)
$minPrice = $product->getPriceInfo()->getPrice('final_price')->getMinimalPrice();
$maxPrice = $product->getPriceInfo()->getPrice('final_price')->getMaximalPrice();
// Returns: $24.99 - $29.99
// Check if price includes tax
$priceIncludesTax = $taxHelper->priceIncludesTax();
Currency Configuration
// Get current currency
$currency = $storeManager->getStore()->getCurrentCurrencyCode();
// Returns: USD
// Convert price
$basePrice = 29.99;
$convertedPrice = $currency->convert($basePrice);
// Get currency symbol
$symbol = $currency->getCurrencySymbol();
// Returns: $
Price Rules
// Catalog price rules
// Admin > Marketing > Catalog Price Rules
// Cart price rules (coupons)
// Admin > Marketing > Cart Price Rules
// Apply rule
$rule = $objectManager->get(
\Magento\SalesRule\Model\RuleFactory::class
)->create();
$rule->setName('10% Off')
->setDiscountAmount(10)
->setDiscountType('by_percent')
->save();
Price Configuration
<!-- Price display settings -->
<config>
<default>
<catalog>
<price>
<tax>inc</tax> <!-- inc, exc, both -->
</price>
</catalog>
<tax>
<defaults>
<tax_display_type>3</tax_display_type>
<!-- 1=excl, 2=incl, 3=both -->
</defaults>
</tax>
</default>
</config>
Best Practices
1. Use price indices for fast reads
2. Set appropriate customer group prices
3. Use tier pricing for bulk discounts
4. Configure tax display correctly
5. Test special price date ranges
6. Monitor price index freshness
7. Use catalog price rules for promotions
Quiz
1. What is the price hierarchy?
2. What does min_price represent in the price index?
3. How do you reindex prices?
Flashcards
Question
What is base price?
Click to reveal answer
Answer
The standard product price before discounts
Question
What is special price?
Click to reveal answer
Answer
Discounted price with from/to date range
Question
What is tier price?
Click to reveal answer
Answer
Quantity-based discounts (10+ = $25, 50+ = $20)
Question
What is group price?
Click to reveal answer
Answer
Price per customer group (General, Wholesale, etc.)
Question
What is the price index?
Click to reveal answer
Answer
Pre-computed table with final prices per customer group/website
Revision Notes
Key Takeaways
- 1. Base price: standard product price
- 2. Special price: discounted price with date range
- 3. Tier price: quantity-based discounts
- 4. Group price: price per customer group
- 5. Price index: pre-computed final prices for fast reads
- 6. Price hierarchy: Base → Special → Group → Tier
Interview Tips
- • Explain the price calculation hierarchy
- • Discuss how price indices improve performance
- • Describe tier pricing use cases
Cheat Sheet
Price Types:
Base Price → $29.99 (standard)
Special Price → $24.99 (with dates)
Tier Price → $25.00 (qty 10+)
Group Price → $27.00 (customer group)
Price Index:
catalog_product_index_price
entity_id, customer_group_id, website_id
price, final_price, min_price, max_price
Hierarchy:
Base → Special → Group → Tier → Rules
Commands:
bin/magento indexer:reindex catalog_product_price
bin/magento indexer:set-mode realtime|schedule