4

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

11

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)); – Jancy Abraham Oct 13 '17 at 6:50
  • Also some error in the phtml file. – Jancy Abraham Oct 13 '17 at 6:57
  • Show your error. It's tested code and working fine. – Sohel Rana Oct 13 '17 at 7:00
  • Check updated code for SR/Stackexchange/view/frontend/templates/product/price/range/price.phtml – Sohel Rana Oct 13 '17 at 7:02
  • 1
    SR/Stackexchange = VendorName/ModuleName, Location should be app/code/ @MarioM. – Sohel Rana Dec 16 '17 at 14:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.