1

Magento 2 returns regular price differently from special and final price. Expected result:

$product->getPrice(); // 89,95
$product->getPriceInfo()->getPrice('regular_price')->getAmount()->getValue(); // 89,95
$product->getSpecialPrice(); // 49,95
$product->getPriceInfo()->getPrice('special_price')->getAmount()->getValue(); // 49,95
$product->getFinalPrice(); // 49,95
$product->getPriceInfo()->getPrice('final_price')->getAmount()->getValue(); // 49,95

Given result:

$product->getPrice(); // 89,95
$product->getPriceInfo()->getPrice('regular_price')->getAmount()->getValue(); // 89,95
$product->getSpecialPrice(); // 49
$product->getPriceInfo()->getPrice('special_price')->getAmount()->getValue(); // 49
$product->getFinalPrice(); // 49
$product->getPriceInfo()->getPrice('final_price')->getAmount()->getValue(); // 49

Somehow the special and final prices get returned without decimals. I tried al kind of things with different helpers (like the taxhelper etc.), but no success. Why does Magento 2.3 keep returning the special price without decimals?

EDIT: And if this is normal behaviour, what would be the proper way to get the special and final price in my module without currency symbols etc. but including tax?

1 Answer 1

1

If you look following class:

vendor/magento/module-catalog/Pricing/Price/SpecialPrice.php

/**
 * Returns special price
 *
 * @return float
 */
public function getSpecialPrice()
{
    $specialPrice = $this->product->getSpecialPrice();
    if ($specialPrice !== null && $specialPrice !== false && !$this->isPercentageDiscount()) {
        $specialPrice = $this->priceCurrency->convertAndRound($specialPrice);
    }
    return $specialPrice;
}

Actually following line format price:

$this->priceCurrency->convertAndRound($specialPrice)

Now go to the following class:

vendor/magento/module-directory/Model/PriceCurrency.php

And check the following code

/**
 * Round price with precision
 *
 * @param float $price
 * @param int $precision
 * @return float
 */
public function roundPrice($price, $precision = self::DEFAULT_PRECISION)
{
    return round($price, $precision);
}

Check documentation for round as well

Here is the sample example:

<?php

echo round(3.4);         // 3
echo round(3.5);         // 4
echo round(3.6);         // 4
echo round(3.6, 0);      // 4
echo round(1.95583, 2);  // 1.96
echo round(1241757, -3); // 1242000
echo round(5.045, 2);    // 5.05
echo round(5.055, 2);    // 5.06
4
  • Thank you for your answer! However, the self::DEFAULT_PRECISION seems not to be set or 0. How do I change this to 2? vendor/magento/framework/Pricing/PriceCurrencyInterface.php has: const DEFAULT_PRECISION = 2;
    – Tober
    Commented Apr 16, 2019 at 10:10
  • But the strange thing is that it looks like it has nothing to do with the 'round' function. As you suggest 49,95 would become 50. However, the value that I get returned is 49. Maybe it has something to do with the comma? In the frontend it does show the price as € 49,95. I'm completely lost here.
    – Tober
    Commented Apr 16, 2019 at 13:42
  • Hey, did you debug here? What value return round($price, $precision)?
    – Sohel Rana
    Commented Apr 16, 2019 at 15:37
  • Thank you for your answer. This is the right answer to my question. However, it turns out that my problem came from how the product was loaded. The product returned to the observer in a "product before save" listner seems to work differently: $observer->getProduct();. Now I load the product using the ProductRepositoryInterface and everything works as expected. For someone else with this problem: get the product ID using: $observer->getProduct()->getId(); and than use the magento 2.1 version of this answer: link
    – Tober
    Commented Apr 25, 2019 at 13:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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