Skip to content

Commit 7dee5fc

Browse files
author
Sergey Shvets
committed
MAGETWO-82132: Comma special character in cart price rule condition value results in incorrect rule
1 parent f35a963 commit 7dee5fc

File tree

4 files changed

+60
-6
lines changed

4 files changed

+60
-6
lines changed

app/code/Magento/Rule/Model/Condition/AbstractCondition.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ public function isArrayOperatorType()
380380
}
381381

382382
/**
383-
* @return array
383+
* @return mixed
384384
*/
385385
public function getValue()
386386
{

app/code/Magento/SalesRule/Model/Rule/Condition/Product.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public function validate(\Magento\Framework\Model\AbstractModel $model)
5959
if ($attrCode === 'quote_item_price') {
6060
$numericOperations = $this->getDefaultOperatorInputByType()['numeric'];
6161
if (in_array($this->getOperator(), $numericOperations)) {
62-
$this->setData('value', $this->_localeFormat->getNumber($this->getValue()));
62+
$this->setData('value', $this->getFormattedPrice($this->getValue()));
6363
}
6464
}
6565

@@ -87,4 +87,23 @@ public function getValueElementChooserUrl()
8787
}
8888
return $url !== false ? $this->_backendData->getUrl($url) : '';
8989
}
90+
91+
/**
92+
* @param string $value
93+
* @return float|null
94+
*/
95+
private function getFormattedPrice($value)
96+
{
97+
$value = preg_replace('/[^0-9^\^.,-]/m', '', $value);
98+
99+
/**
100+
* If the comma is the third symbol in the number, we consider it to be a decimal separator
101+
*/
102+
$separatorComa = strpos($value, ',');
103+
$separatorDot = strpos($value, '.');
104+
if ($separatorComa !== false && $separatorDot === false && preg_match('/,\d{3}$/m', $value) === 1) {
105+
$value .= '.00';
106+
}
107+
return $this->_localeFormat->getNumber($value);
108+
}
90109
}

lib/internal/Magento/Framework/Locale/Format.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public function getNumber($value)
6565
}
6666

6767
//trim spaces and apostrophes
68-
$value = str_replace(['\'', ' '], '', $value);
68+
$value = preg_replace('/[^0-9^\^.,-]/m', '', $value);
6969

7070
$separatorComa = strpos($value, ',');
7171
$separatorDot = strpos($value, '.');

lib/internal/Magento/Framework/Locale/Test/Unit/FormatTest.php

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,7 @@ protected function setUp()
4141
$this->scope = $this->getMockBuilder(\Magento\Framework\App\ScopeInterface::class)
4242
->setMethods(['getCurrentCurrency'])
4343
->getMockForAbstractClass();
44-
$this->scope->expects($this->once())
45-
->method('getCurrentCurrency')
46-
->willReturn($this->currency);
44+
4745
$this->scopeResolver = $this->getMockBuilder(\Magento\Framework\App\ScopeResolverInterface::class)
4846
->setMethods(['getScope'])
4947
->getMockForAbstractClass();
@@ -52,6 +50,8 @@ protected function setUp()
5250
->willReturn($this->scope);
5351
$this->localeResolver = $this->getMockBuilder(\Magento\Framework\Locale\ResolverInterface::class)
5452
->getMock();
53+
54+
/** @var \Magento\Directory\Model\CurrencyFactory|\PHPUnit_Framework_MockObject_MockObject $currencyFactory */
5555
$currencyFactory = $this->getMockBuilder(\Magento\Directory\Model\CurrencyFactory::class)
5656
->getMock();
5757

@@ -69,6 +69,10 @@ protected function setUp()
6969
*/
7070
public function testGetPriceFormat($localeCode, $expectedResult)
7171
{
72+
$this->scope->expects($this->once())
73+
->method('getCurrentCurrency')
74+
->willReturn($this->currency);
75+
7276
$result = $this->formatModel->getPriceFormat($localeCode);
7377
$intersection = array_intersect_assoc($result, $expectedResult);
7478
$this->assertCount(count($expectedResult), $intersection);
@@ -86,4 +90,35 @@ public function getPriceFormatDataProvider()
8690
['uk_UA', ['decimalSymbol' => ',', 'groupSymbol' => ' ']]
8791
];
8892
}
93+
94+
95+
/**
96+
* @param float | null $expected
97+
* @param string|float|int $value
98+
* @dataProvider provideNumbers
99+
*/
100+
public function testGetNumber($value, $expected)
101+
{
102+
$this->assertEquals($expected, $this->formatModel->getNumber($value));
103+
}
104+
105+
106+
/**
107+
* @return array
108+
*/
109+
public function provideNumbers(): array
110+
{
111+
return [
112+
[' 2345.4356,1234', 23454356.1234],
113+
['+23,3452.123', 233452.123],
114+
['12343', 12343],
115+
['-9456km', -9456],
116+
['0', 0],
117+
['2 054,10', 2054.1],
118+
['2046,45', 2046.45],
119+
['2 054.52', 2054.52],
120+
['2,46 GB', 2.46],
121+
['2,054.00', 2054],
122+
];
123+
}
89124
}

0 commit comments

Comments
 (0)