Skip to content

Commit 95891c8

Browse files
author
olysenko
committed
Merge remote-tracking branch 'origin/MAGETWO-82132' into chaika_pr
2 parents 711b4f9 + 7dee5fc commit 95891c8

File tree

5 files changed

+158
-9
lines changed

5 files changed

+158
-9
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: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
67
namespace Magento\SalesRule\Model\Rule\Condition;
78

89
/**
@@ -51,10 +52,17 @@ public function validate(\Magento\Framework\Model\AbstractModel $model)
5152

5253
$attrCode = $this->getAttribute();
5354

54-
if ('category_ids' == $attrCode) {
55+
if ($attrCode === 'category_ids') {
5556
return $this->validateAttribute($this->_getAvailableInCategories($product->getId()));
5657
}
5758

59+
if ($attrCode === 'quote_item_price') {
60+
$numericOperations = $this->getDefaultOperatorInputByType()['numeric'];
61+
if (in_array($this->getOperator(), $numericOperations)) {
62+
$this->setData('value', $this->getFormattedPrice($this->getValue()));
63+
}
64+
}
65+
5866
return parent::validate($product);
5967
}
6068

@@ -79,4 +87,23 @@ public function getValueElementChooserUrl()
7987
}
8088
return $url !== false ? $this->_backendData->getUrl($url) : '';
8189
}
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+
}
82109
}

app/code/Magento/SalesRule/Test/Unit/Model/Rule/Condition/ProductTest.php

Lines changed: 90 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
67
namespace Magento\SalesRule\Test\Unit\Model\Rule\Condition;
78

9+
use Magento\Directory\Model\CurrencyFactory;
10+
use Magento\Framework\App\ScopeResolverInterface;
811
use \Magento\Framework\DB\Adapter\AdapterInterface;
912
use \Magento\Framework\DB\Select;
10-
use \Magento\Framework\Model\AbstractModel;
13+
use Magento\Framework\Locale\Format;
14+
use Magento\Framework\Locale\ResolverInterface;
1115
use Magento\Quote\Model\Quote\Item\AbstractItem;
1216
use \Magento\Rule\Model\Condition\Context;
1317
use \Magento\Backend\Helper\Data;
@@ -130,8 +134,12 @@ protected function setUp()
130134
$this->collectionMock = $this->getMockBuilder(Collection::class)
131135
->disableOriginalConstructor()
132136
->getMock();
133-
$this->formatMock = $this->getMockBuilder(FormatInterface::class)
134-
->getMockForAbstractClass();
137+
$this->formatMock = new Format(
138+
$this->getMockBuilder(ScopeResolverInterface::class)->disableOriginalConstructor()->getMock(),
139+
$this->getMockBuilder(ResolverInterface::class)->disableOriginalConstructor()->getMock(),
140+
$this->getMockBuilder(CurrencyFactory::class)->disableOriginalConstructor()->getMock()
141+
);
142+
135143
$this->model = new SalesRuleProduct(
136144
$this->contextMock,
137145
$this->backendHelperMock,
@@ -231,4 +239,83 @@ public function testValidateCategoriesIgnoresVisibility()
231239

232240
$this->model->validate($item);
233241
}
242+
243+
/**
244+
* @param boolean $isValid
245+
* @param string $conditionValue
246+
* @param string $operator
247+
* @param double $productPrice
248+
* @dataProvider localisationProvider
249+
*/
250+
public function testQuoteLocaleFormatPrice($isValid, $conditionValue, $operator = '>=', $productPrice = 2000.00)
251+
{
252+
$attr = $this->getMockBuilder(\Magento\Framework\Model\ResourceModel\Db\AbstractDb::class)
253+
->disableOriginalConstructor()
254+
->setMethods(['getAttribute'])
255+
->getMockForAbstractClass();
256+
257+
$attr->expects($this->any())
258+
->method('getAttribute')
259+
->willReturn('');
260+
261+
/* @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject $product */
262+
$product = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
263+
->disableOriginalConstructor()
264+
->setMethods(['setQuoteItemPrice', 'getResource', 'hasData', 'getData',])
265+
->getMock();
266+
267+
$product->expects($this->any())
268+
->method('setQuoteItemPrice')
269+
->willReturnSelf();
270+
271+
$product->expects($this->any())
272+
->method('getResource')
273+
->willReturn($attr);
274+
275+
$product->expects($this->any())
276+
->method('hasData')
277+
->willReturn(true);
278+
279+
$product->expects($this->any())
280+
->method('getData')
281+
->with('quote_item_price')
282+
->willReturn($productPrice);
283+
284+
/* @var AbstractItem|\PHPUnit_Framework_MockObject_MockObject $item */
285+
$item = $this->getMockBuilder(AbstractItem::class)
286+
->disableOriginalConstructor()
287+
->setMethods(['getPrice', 'getProduct',])
288+
->getMockForAbstractClass();
289+
290+
$item->expects($this->any())
291+
->method('getPrice')
292+
->willReturn($productPrice);
293+
294+
$item->expects($this->any())
295+
->method('getProduct')
296+
->willReturn($product);
297+
298+
$this->model->setAttribute('quote_item_price')
299+
->setOperator($operator);
300+
301+
$this->assertEquals($isValid, $this->model->setValue($conditionValue)->validate($item));
302+
}
303+
304+
305+
/**
306+
* DataProvider for testQuoteLocaleFormatPrice
307+
*
308+
* @return array
309+
*/
310+
public function localisationProvider(): array
311+
{
312+
return [
313+
'number' => [true, 500.01],
314+
'locale' => [true, '1,500.03'],
315+
'operation' => [true, '1,500.03', '!='],
316+
'stringOperation' => [false, '1,500.03', '{}'],
317+
'smallPrice' => [false, '1,500.03', '>=', 1000],
318+
];
319+
}
320+
234321
}

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)