Question

I want to display price range for configurable products instead of the minimal price in category listing. enter image description here

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top