2

How to add a string like "Price from" next to configurable product prices on Category, Search and Product pages, but only if the configurable product has simple products with different prices in it?

  • 1
    Not trying to be harsh but there is a very similar example in Magento 2 Developer documentation devdocs.magento.com/guides/v2.0/extension-dev-guide/… I strongly recommend you having a go with this. – Alvin Nguyen Jan 30 '18 at 22:28
  • 1
    Not sure what the down votes or close votes are about, it's a legitimate question on how to improve configurable products in Magento 2. @AlvinNguyen I haven't done enough research yet, but it doesn't seem to be that simple to target only configurable products... – Lez Jan 30 '18 at 22:55
  • I've dowvoted too. You say "I haven't done enough research" and tooltips for up/downvotes says "This questions shows research effort ...." or not. So please spent your time first, before asking others. If not possible add a "better" description, that would help too. (and finally it was reopened after description edits) – sv3n Feb 3 '18 at 21:04
  • 1
    I disagree that you need to research thoroughly before asking. Stackexchange is about sharing knowledge and expertise. My question was simple and to the point (in it's original form) and it's definitely useful to improve configurable products. Also it was reopened because I flaged it for a mod (because it was closed as "off topic"). I made the edits afterwards when I figured out all the stuff that needed to be adjusted to make this more customer-friendly. – Lez Feb 4 '18 at 11:43
  • 3
    I have UPvoted the question because it actually made sense, and if someone is not able to understand the question they should comment rather than downvoting. Plus the comment from sv3n is not justified. The community is just being a market to gain reputation by up/down voting rather than sharing knowledge. – LAW May 2 '18 at 4:39
2

I did this by extending Magento\ConfigurableProduct\Pricing\Price\FinalPrice with functions for getting min/max final price of configurable products and inserting the label only when needed (when there are simple products with different prices inside the configurable).

Gonna post my solution for others that might need help with this:

{Vendor}/{Module}/etc/di.xml

<preference for="Magento\ConfigurableProduct\Pricing\Price\FinalPrice" type="{Vendor}\{Module}\Pricing\Price\FinalPrice"/>

{Vendor}/{Module}/Pricing/Price/FinalPrice

<?php
namespace Vendor\Module\Pricing\Price;

use Magento\Framework\App\ObjectManager;

class FinalPrice extends \Magento\ConfigurableProduct\Pricing\Price\FinalPrice
{

    protected $priceResolver;

    protected $maxFinalAmount;

    protected $minFinalAmount;

    protected $lowestPriceOptionsProvider;

    protected $configurableType;

    public function __construct(
        \Magento\Framework\Pricing\SaleableInterface $saleableItem,
        $quantity,
        \Magento\Framework\Pricing\Adjustment\CalculatorInterface $calculator,
        \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
        \Magento\ConfigurableProduct\Pricing\Price\PriceResolverInterface $priceResolver,
        \Magento\ConfigurableProduct\Pricing\Price\LowestPriceOptionsProviderInterface $lowestPriceOptionsProvider = null,
        \Magento\ConfigurableProduct\Model\Product\Type\Configurable $configurableType
    ) {
        parent::__construct($saleableItem, $quantity, $calculator, $priceCurrency, $priceResolver);
        $this->priceResolver = $priceResolver;
        $this->lowestPriceOptionsProvider = $lowestPriceOptionsProvider ?:
        ObjectManager::getInstance()->get(\Magento\ConfigurableProduct\Pricing\Price\LowestPriceOptionsProviderInterface::class);
        $this->configurableType = $configurableType ?:
        ObjectManager::getInstance()->get(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::class);
    }

    public function getMaxFinalAmount()
    {
        if (null === $this->maxFinalAmount) {
            $this->maxFinalAmount = $this->doGetMaxFinalAmount() ?: false;
        }
        return $this->maxFinalAmount;
    }

    protected function doGetMaxFinalAmount()
    {
        $maxAmount = null;
        $usedProducts = $this->configurableType->getUsedProducts($this->product);

        foreach ($usedProducts as $product) {
            $childPriceAmount = $product->getPriceInfo()->getPrice('final_price')->getAmount();
            if (!$maxAmount || ($childPriceAmount->getValue() > $maxAmount->getValue())) {
                $maxAmount = $childPriceAmount;
            }
        }
        return $maxAmount;
    }

    public function getMinFinalAmount()
    {
        if (null === $this->minFinalAmount) {
            $this->minFinalAmount = $this->doGetMinFinalAmount() ?: parent::getAmount();
        }
        return $this->minFinalAmount;
    }

    protected function doGetMinFinalAmount()
    {
        $minAmount = null;
        $usedProducts = $this->lowestPriceOptionsProvider->getProducts($this->product);

        foreach ($usedProducts as $product) {
            $childPriceAmount = $product->getPriceInfo()->getPrice('final_price')->getAmount();
            if (!$minAmount || ($childPriceAmount->getValue() < $minAmount->getValue())) {
                $minAmount = $childPriceAmount;
            }
        }
        return $minAmount;
    }
}

Then you can call the new function getMinFinalAmount and getMaxFinalAmount from your custom:

.../Magento_ConfigurableProduct/templates/product/price/final_price.phtml

$minAmount = $finalPriceModel->getMinFinalAmount();
$maxAmount = $finalPriceModel->getMaxFinalAmount();

And display the label where you want like this:

<?php if ($minAmount < $maxAmount) { ?>
    <span class="price-label"><?php echo __('Price from:') ?></span>
<?php } ?>

All that's left is to use JS to hide the Price from label when a simple configuration is selected.

That depends on if you're using swatches or not.

To remove the label by using swatches, you need to edit Magento_Swatches/web/js/swatch-renderer.js.

I added this code to the _UpdatePrice function which is executed when a swatch is clicked.

$product.find('.price-label').hide(0);

To remove the label by using ordinary configurable options, you need to edit Magento_ConfigurableProduct/web/js/configurable.js.

I added this code to the _calculatePrice function which is executed when a configurable option is selected from the dropdown.

$(this.options.priceHolderSelector).find('.price-label').hide(0);

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.