I want to display price range for configurable products instead of the minimal price in category listing.
1 Answer
You need to pluginize getProductPrice method.
SR/Stackexchange/etc/frontend/di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Catalog\Block\Product\ListProduct">
<plugin name="SR_Stackexchange:price_range" type="SR\Stackexchange\Plugin\Block\Product\ListProduct" sortOrder="1"/>
</type>
</config>
SR/Stackexchange/Plugin/Block/Product/ListProduct.php
namespace SR\Stackexchange\Plugin\Block\Product;
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
class ListProduct
{
/**
* @var \Magento\Catalog\Block\Product\ListProduct
*/
protected $listProductBlock;
/**
* @var Configurable
*/
protected $configurableProduct;
/**
* @var \Magento\Framework\Pricing\Helper\Data
*/
protected $pricingHelper;
/**
* @var \Psr\Log\LoggerInterface
*/
protected $logger;
/**
* ListProduct constructor.
*
* @param Configurable $configurableProduct
* @param \Magento\Framework\Pricing\Helper\Data $pricingHelper
*/
public function __construct(
Configurable $configurableProduct,
\Magento\Framework\Pricing\Helper\Data $pricingHelper,
\Psr\Log\LoggerInterface $logger
) {
$this->configurableProduct = $configurableProduct;
$this->pricingHelper = $pricingHelper;
$this->logger = $logger;
}
/**
* @param \Magento\Catalog\Block\Product\ListProduct $subject
* @param \Closure $proceed
* @param \Magento\Catalog\Model\Product $product
* @return string
*/
public function aroundGetProductPrice(
\Magento\Catalog\Block\Product\ListProduct $subject,
\Closure $proceed,
\Magento\Catalog\Model\Product $product
) {
if (Configurable::TYPE_CODE !== $product->getTypeId()) {
return $proceed($product);
}
$this->listProductBlock = $subject;
$priceText = $this->getPriceRange($product);
return $priceText;
}
/**
* Get configurable product price range
*
* @param $product
* @return string
*/
public function getPriceRange($product)
{
$childProductPrice = [];
$childProducts = $this->configurableProduct->getUsedProducts($product);
foreach($childProducts as $child) {
$price = number_format($child->getPrice(), 2, '.', '');
$finalPrice = number_format($child->getFinalPrice(), 2, '.', '');
if($price == $finalPrice) {
$childProductPrice[] = $price;
} else if($finalPrice < $price) {
$childProductPrice[] = $finalPrice;
}
}
$max = $this->pricingHelper->currencyByStore(max($childProductPrice));
$min = $this->pricingHelper->currencyByStore(min($childProductPrice));
if($min==$max){
return $this->getPriceRender($product, "$min", '');
} else {
return $this->getPriceRender($product, "$min-$max", '');
}
}
/**
* Price renderer
*
* @param $product
* @param $price
* @return mixed
*/
protected function getPriceRender($product, $price, $text='')
{
return $this->listProductBlock->getLayout()->createBlock('Magento\Framework\View\Element\Template')
->setTemplate('SR_Stackexchange::product/price/range/price.phtml')
->setData('price_id', 'product-price-'.$product->getId())
->setData('display_label', $text)
->setData('product_id', $product->getId())
->setData('display_value', $price)->toHtml();
}
}
SR/Stackexchange/view/frontend/templates/product/price/range/price.phtml
<?php /** @var \Magento\Framework\Pricing\Render\Amount $block */ ?>
<div class="price-box range second price-final_price" data-role="priceBox" data-product-id="<?php /* @escapeNotVerified */ echo $block->getProductId() ?>">
<span class="special-price">
<span class="price-container price-final_price">
<?php if ($block->getDisplayLabel()): ?>
<span class="price-label"><?php /* @escapeNotVerified */ echo $block->getDisplayLabel(); ?></span>
<?php endif; ?>
<span <?php if ($block->getPriceId()): ?> id="<?php /* @escapeNotVerified */ echo $block->getPriceId() ?>"<?php endif;?>
data-price-amount=""
data-price-type="finalPrice1"
class="price-wrapper">
<span class="price"><?php /* @escapeNotVerified */ echo $block->getDisplayValue();?></span>
</span>
</span>
</span>
</div>
Clear Cache.
-
Shows some error in this area else if($finalPrice pricingHelper->currencyByStore(max($childProductPrice)); $min = $this->pricingHelper->currencyByStore(min($childProductPrice)); Oct 13, 2017 at 6:50
-
-
-
Check updated code for SR/Stackexchange/view/frontend/templates/product/price/range/price.phtml Oct 13, 2017 at 7:02
-
1SR/Stackexchange = VendorName/ModuleName, Location should be app/code/ @MarioM. Dec 16, 2017 at 14:59