Skip to content

Fix #21725 - Render price on category list with correct precision for current locale #31661

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: 2.5-develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public function build(PriceInfoInterface $priceInfo, $storeId, $currencyCode)
->format(
$value,
true,
PriceCurrencyInterface::DEFAULT_PRECISION,
null,
$storeId,
$currencyCode
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->

<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
<test name="StoreFrontProductsDisplayCorrectPricePrecisionTest">
<annotations>
<stories value="Check the price"/>
<title value="Storefront products display correct price precision test"/>
<description value="Check if price renders with correct precision on category and product pages"/>
<severity value="MAJOR"/>
<group value="Catalog"/>
</annotations>

<before>
<createData entity="_defaultCategory" stepKey="createCategory"/>
<createData entity="_defaultProduct" stepKey="createProduct">
<requiredEntity createDataKey="createCategory"/>
</createData>
<magentoCLI command="config:set general/locale/code ar_KW" stepKey="setLocaleKw"/>
<magentoCLI command="config:set currency/options/allow USD,KWD" stepKey="setCurrencyAllowKwd"/>
<magentoCLI command="config:set currency/options/base KWD" stepKey="setCurrencyBaseKwd"/>
<magentoCLI command="config:set currency/options/default KWD" stepKey="setCurrencyDefaultKwd"/>
<actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCacheBefore">
<argument name="tags" value="config"/>
</actionGroup>
</before>

<after>
<deleteData createDataKey="createCategory" stepKey="deleteCategory"/>
<deleteData createDataKey="createProduct" stepKey="deleteProduct"/>
<magentoCLI command="config:set general/locale/code en_US" stepKey="setLocaleUS"/>
<magentoCLI command="config:set currency/options/base USD" stepKey="setCurrencyBaseUsd"/>
<magentoCLI command="config:set currency/options/default USD" stepKey="setCurrencyDefaultUsd"/>
<magentoCLI command="config:set currency/options/allow USD" stepKey="setCurrencyAllowUsd"/>
<actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCacheAfter">
<argument name="tags" value="config"/>
</actionGroup>
</after>

<!-- Check Product price precision on the Category page -->
<actionGroup ref="AssertStorefrontProductPriceInCategoryPageActionGroup" stepKey="assertProductPriceOnCategoryPage">
<argument name="categoryUrl" value="$createCategory.custom_attributes[url_key]$"/>
<argument name="productName" value="$createProduct.name$"/>
<argument name="productPrice" value="$createProduct.price$٫000"/>
</actionGroup>

<!-- Check Product price precision on the Product page -->
<actionGroup ref="OpenStoreFrontProductPageActionGroup" stepKey="openProductPage">
<argument name="productUrlKey" value="$$createProduct.custom_attributes[url_key]$$"/>
</actionGroup>
<actionGroup ref="AssertStorefrontProductPricesActionGroup" stepKey="assertProductPriceOnProductPage">
<argument name="productPrice" value="$createProduct.price$٫000"/>
<argument name="productFinalPrice" value="$createProduct.price$٫000"/>
</actionGroup>
</test>
</tests>
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@
class FormattedPriceInfoBuilderTest extends TestCase
{
/**
* @var PriceCurrencyInterface|MockObject ;
* @var PriceCurrencyInterface|MockObject;
*/
private $priceCurrencyMock;

/**
* @var FormattedPriceInfoInterfaceFactory|MockObject ;
* @var FormattedPriceInfoInterfaceFactory|MockObject;
*/
private $formattedPriceInfoFactoryMock;

Expand Down Expand Up @@ -69,7 +69,7 @@ public function testBuild()
->with(
'1233123',
true,
PriceCurrencyInterface::DEFAULT_PRECISION,
null,
$storeId,
$storeCurrencyCode
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ protected function getGroupCodeByField(array $meta, $field)
*/
protected function formatPrice($value)
{
return $value !== null ? number_format((float)$value, PriceCurrencyInterface::DEFAULT_PRECISION, '.', '') : '';
return $value !== null ? number_format((float)$value, 2, '.', '') : '';
}

/**
Expand Down
2 changes: 1 addition & 1 deletion app/code/Magento/Checkout/Helper/Data.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ public function formatPrice($price)
return $this->priceCurrency->format(
$price,
true,
PriceCurrencyInterface::DEFAULT_PRECISION,
null,
$this->getQuote()->getStore()
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public function testGetShippingPrice()

$this->priceCurrency->expects($this->once())
->method('convertAndFormat')
->with($shippingPrice, true, true)
->with($shippingPrice, true, null)
->willReturn($convertedPrice);

$this->priceObj->setShippingRate($shippingRateMock);
Expand Down
27 changes: 21 additions & 6 deletions app/code/Magento/Directory/Model/Currency.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@

namespace Magento\Directory\Model;

use Magento\Directory\Model\Currency\Filter;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Exception\InputException;
use Magento\Directory\Model\Currency\Filter;
use Magento\Framework\Pricing\Price\PricePrecisionInterface;

/**
* Currency model
Expand Down Expand Up @@ -71,6 +72,11 @@ class Currency extends \Magento\Framework\Model\AbstractModel
*/
private $currencyConfig;

/**
* @var PricePrecisionInterface|null
*/
private $pricePrecision;

/**
* @param \Magento\Framework\Model\Context $context
* @param \Magento\Framework\Registry $registry
Expand All @@ -79,10 +85,11 @@ class Currency extends \Magento\Framework\Model\AbstractModel
* @param \Magento\Directory\Helper\Data $directoryHelper
* @param Currency\FilterFactory $currencyFilterFactory
* @param \Magento\Framework\Locale\CurrencyInterface $localeCurrency
* @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
* @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
* @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource
* @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection
* @param array $data
* @param CurrencyConfig $currencyConfig
* @param CurrencyConfig|null $currencyConfig
* @param PricePrecisionInterface|null $pricePrecision
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
Expand All @@ -96,7 +103,8 @@ public function __construct(
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
array $data = [],
CurrencyConfig $currencyConfig = null
CurrencyConfig $currencyConfig = null,
?PricePrecisionInterface $pricePrecision = null
) {
parent::__construct(
$context,
Expand All @@ -111,6 +119,7 @@ public function __construct(
$this->_currencyFilterFactory = $currencyFilterFactory;
$this->_localeCurrency = $localeCurrency;
$this->currencyConfig = $currencyConfig ?: ObjectManager::getInstance()->get(CurrencyConfig::class);
$this->pricePrecision = $pricePrecision ?? ObjectManager::getInstance()->get(PricePrecisionInterface::class);
}

/**
Expand Down Expand Up @@ -277,7 +286,13 @@ public function getFilter()
*/
public function format($price, $options = [], $includeContainer = true, $addBrackets = false)
{
return $this->formatPrecision($price, 2, $options, $includeContainer, $addBrackets);
return $this->formatPrecision(
$price,
$this->pricePrecision->getPrecision(),
$options,
$includeContainer,
$addBrackets
);
}

/**
Expand Down
44 changes: 36 additions & 8 deletions app/code/Magento/Directory/Model/PriceCurrency.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,24 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\Directory\Model;

use Magento\Framework\App\ScopeInterface;
use Magento\Framework\Pricing\Price\PricePrecisionInterface;
use Magento\Framework\Pricing\PriceCurrencyInterface;
use Magento\Store\Model\StoreManagerInterface;
use Psr\Log\LoggerInterface as Logger;
use Magento\Store\Model\Store;

/**
* Class PriceCurrency model for convert and format price value
*/
class PriceCurrency implements \Magento\Framework\Pricing\PriceCurrencyInterface
class PriceCurrency implements PriceCurrencyInterface
{
/**
* @var \Magento\Store\Model\StoreManagerInterface
* @var StoreManagerInterface
*/
protected $storeManager;

Expand All @@ -31,18 +35,26 @@ class PriceCurrency implements \Magento\Framework\Pricing\PriceCurrencyInterface
protected $logger;

/**
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @var PricePrecisionInterface
*/
private $pricePrecision;

/**
* @param StoreManagerInterface $storeManager
* @param CurrencyFactory $currencyFactory
* @param Logger $logger
* @param PricePrecisionInterface $pricePrecision
*/
public function __construct(
StoreManagerInterface $storeManager,
CurrencyFactory $currencyFactory,
Logger $logger
Logger $logger,
PricePrecisionInterface $pricePrecision
) {
$this->storeManager = $storeManager;
$this->currencyFactory = $currencyFactory;
$this->logger = $logger;
$this->pricePrecision = $pricePrecision;
}

/**
Expand All @@ -60,8 +72,12 @@ public function convert($amount, $scope = null, $currency = null)
/**
* @inheritdoc
*/
public function convertAndRound($amount, $scope = null, $currency = null, $precision = self::DEFAULT_PRECISION)
public function convertAndRound($amount, $scope = null, $currency = null, $precision = null)
{
if ($precision === null) {
$precision = $this->pricePrecision->getPrecision();
}

return $this->roundPrice($this->convert($amount, $scope, $currency), $precision);
}

Expand All @@ -71,10 +87,14 @@ public function convertAndRound($amount, $scope = null, $currency = null, $preci
public function format(
$amount,
$includeContainer = true,
$precision = self::DEFAULT_PRECISION,
$precision = null,
$scope = null,
$currency = null
) {
if ($precision === null) {
$precision = $this->pricePrecision->getPrecision();
}

return $this->getCurrency($scope, $currency)
->formatPrecision($amount, $precision, [], $includeContainer);
}
Expand All @@ -85,10 +105,14 @@ public function format(
public function convertAndFormat(
$amount,
$includeContainer = true,
$precision = self::DEFAULT_PRECISION,
$precision = null,
$scope = null,
$currency = null
) {
if ($precision === null) {
$precision = $this->pricePrecision->getPrecision();
}

$amount = $this->convert($amount, $scope, $currency);

return $this->format($amount, $includeContainer, $precision, $scope, $currency);
Expand Down Expand Up @@ -162,8 +186,12 @@ public function round($price)
* @param int $precision
* @return float
*/
public function roundPrice($price, $precision = self::DEFAULT_PRECISION)
public function roundPrice($price, $precision = null)
{
if ($precision === null) {
$precision = $this->pricePrecision->getPrecision();
}

return round($price, $precision);
}
}
Loading