Skip to content

Commit 4614d9e

Browse files
committed
MC-41911: Decimal quantity is converted to integer value when updated
1 parent f25fc03 commit 4614d9e

File tree

4 files changed

+75
-9
lines changed

4 files changed

+75
-9
lines changed

app/code/Magento/Checkout/Controller/Sidebar/UpdateItemQty.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
*/
66
namespace Magento\Checkout\Controller\Sidebar;
77

8+
use Magento\Checkout\Model\Cart\RequestQuantityProcessor;
89
use Magento\Checkout\Model\Sidebar;
910
use Magento\Framework\App\Action\Action;
1011
use Magento\Framework\App\Action\Context;
12+
use Magento\Framework\App\ObjectManager;
1113
use Magento\Framework\App\Response\Http;
1214
use Magento\Framework\Exception\LocalizedException;
1315
use Magento\Framework\Json\Helper\Data;
@@ -30,23 +32,32 @@ class UpdateItemQty extends Action
3032
*/
3133
protected $jsonHelper;
3234

35+
/**
36+
* @var RequestQuantityProcessor
37+
*/
38+
private $quantityProcessor;
39+
3340
/**
3441
* @param Context $context
3542
* @param Sidebar $sidebar
3643
* @param LoggerInterface $logger
3744
* @param Data $jsonHelper
45+
* @param RequestQuantityProcessor|null $quantityProcessor
3846
* @codeCoverageIgnore
3947
*/
4048
public function __construct(
4149
Context $context,
4250
Sidebar $sidebar,
4351
LoggerInterface $logger,
44-
Data $jsonHelper
52+
Data $jsonHelper,
53+
?RequestQuantityProcessor $quantityProcessor = null
4554
) {
4655
$this->sidebar = $sidebar;
4756
$this->logger = $logger;
4857
$this->jsonHelper = $jsonHelper;
4958
parent::__construct($context);
59+
$this->quantityProcessor = $quantityProcessor
60+
?? ObjectManager::getInstance()->get(RequestQuantityProcessor::class);
5061
}
5162

5263
/**
@@ -56,6 +67,7 @@ public function execute()
5667
{
5768
$itemId = (int)$this->getRequest()->getParam('item_id');
5869
$itemQty = $this->getRequest()->getParam('item_qty') * 1;
70+
$itemQty = $this->quantityProcessor->prepareQuantity($itemQty);
5971

6072
try {
6173
$this->sidebar->checkQuoteItem($itemId);

app/code/Magento/Checkout/Model/Cart/RequestQuantityProcessor.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
namespace Magento\Checkout\Model\Cart;
99

1010
use Magento\Framework\Locale\ResolverInterface;
11+
use Zend_Locale_Data;
1112

1213
/**
1314
* Cart request quantity processor
@@ -41,11 +42,38 @@ public function process(array $cartData): array
4142

4243
foreach ($cartData as $index => $data) {
4344
if (isset($data['qty'])) {
45+
$data['qty'] = $this->prepareQuantity($data['qty']);
4446
$data['qty'] = is_string($data['qty']) ? trim($data['qty']) : $data['qty'];
4547
$cartData[$index]['qty'] = $filter->filter($data['qty']);
4648
}
4749
}
4850

4951
return $cartData;
5052
}
53+
54+
/**
55+
* Prepare quantity with taking into account decimal separator by locale
56+
*
57+
* @param int|float|string|array $quantity
58+
* @return int|float|string|array
59+
* @throws \Zend_Locale_Exception
60+
*/
61+
public function prepareQuantity($quantity)
62+
{
63+
$symbols = Zend_Locale_Data::getList($this->localeResolver->getLocale(),'symbols');
64+
65+
if (is_array($quantity)) {
66+
foreach ($quantity as $key => $qty) {
67+
if (strpos((string)$qty, '.') !== false && $symbols['decimal'] !== '.') {
68+
$quantity[$key] = str_replace('.', $symbols['decimal'], $qty);
69+
}
70+
}
71+
} else {
72+
if (strpos((string)$quantity, '.') !== false && $symbols['decimal'] !== '.') {
73+
$quantity = str_replace('.', $symbols['decimal'], (string)$quantity);
74+
}
75+
}
76+
77+
return $quantity;
78+
}
5179
}

app/code/Magento/Checkout/Test/Unit/Controller/Sidebar/UpdateItemQtyTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
namespace Magento\Checkout\Test\Unit\Controller\Sidebar;
99

1010
use Magento\Checkout\Controller\Sidebar\UpdateItemQty;
11+
use Magento\Checkout\Model\Cart\RequestQuantityProcessor;
1112
use Magento\Checkout\Model\Sidebar;
1213
use Magento\Framework\App\RequestInterface;
1314
use Magento\Framework\App\ResponseInterface;
@@ -41,11 +42,15 @@ class UpdateItemQtyTest extends TestCase
4142
/** @var ResponseInterface|MockObject */
4243
protected $responseMock;
4344

45+
/** @var RequestQuantityProcessor|MockObject */
46+
private $quantityProcessor;
47+
4448
protected function setUp(): void
4549
{
4650
$this->sidebarMock = $this->createMock(Sidebar::class);
4751
$this->loggerMock = $this->getMockForAbstractClass(LoggerInterface::class);
4852
$this->jsonHelperMock = $this->createMock(Data::class);
53+
$this->quantityProcessor = $this->createMock(RequestQuantityProcessor::class);
4954
$this->requestMock = $this->getMockForAbstractClass(RequestInterface::class);
5055
$this->responseMock = $this->getMockForAbstractClass(
5156
ResponseInterface::class,
@@ -64,6 +69,7 @@ protected function setUp(): void
6469
'sidebar' => $this->sidebarMock,
6570
'logger' => $this->loggerMock,
6671
'jsonHelper' => $this->jsonHelperMock,
72+
'quantityProcessor' => $this->quantityProcessor,
6773
'request' => $this->requestMock,
6874
'response' => $this->responseMock,
6975
]
@@ -115,6 +121,11 @@ public function testExecute()
115121
)
116122
->willReturn('json encoded');
117123

124+
$this->quantityProcessor->expects($this->once())
125+
->method('prepareQuantity')
126+
->with(2)
127+
->willReturn(2);
128+
118129
$this->responseMock->expects($this->once())
119130
->method('representJson')
120131
->with('json encoded')

app/code/Magento/Checkout/Test/Unit/Model/Cart/RequestQuantityProcessorTest.php

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,24 +28,24 @@ protected function setUp(): void
2828
{
2929
$this->localeResolver = $this->getMockBuilder(ResolverInterface::class)
3030
->getMockForAbstractClass();
31-
32-
$this->localeResolver->method('getLocale')
33-
->willReturn('en_US');
34-
35-
$this->requestProcessor = new RequestQuantityProcessor(
36-
$this->localeResolver
37-
);
3831
}
3932

4033
/**
4134
* Test of cart data processing.
4235
*
4336
* @param array $cartData
37+
* @param string $locale
4438
* @param array $expected
4539
* @dataProvider cartDataProvider
4640
*/
47-
public function testProcess($cartData, $expected)
41+
public function testProcess(array $cartData, string $locale, array $expected): void
4842
{
43+
$this->localeResolver->method('getLocale')
44+
->willReturn($locale);
45+
$this->requestProcessor = new RequestQuantityProcessor(
46+
$this->localeResolver
47+
);
48+
4949
$this->assertEquals($this->requestProcessor->process($cartData), $expected);
5050
}
5151

@@ -57,13 +57,15 @@ public function cartDataProvider()
5757
return [
5858
'empty_array' => [
5959
'cartData' => [],
60+
'locale' => 'en_US',
6061
'expected' => [],
6162
],
6263
'strings_array' => [
6364
'cartData' => [
6465
['qty' => ' 10 '],
6566
['qty' => ' 0.5 ']
6667
],
68+
'locale' => 'en_US',
6769
'expected' => [
6870
['qty' => 10],
6971
['qty' => 0.5]
@@ -74,6 +76,7 @@ public function cartDataProvider()
7476
['qty' => 1],
7577
['qty' => 0.002]
7678
],
79+
'locale' => 'en_US',
7780
'expected' => [
7881
['qty' => 1],
7982
['qty' => 0.002]
@@ -83,10 +86,22 @@ public function cartDataProvider()
8386
'cartData' => [
8487
['qty' => [1, 2 ,3]],
8588
],
89+
'locale' => 'en_US',
8690
'expected' => [
8791
['qty' => [1, 2, 3]],
8892
],
8993
],
94+
'strings_array_spain_locale' => [
95+
'cartData' => [
96+
['qty' => ' 10 '],
97+
['qty' => ' 0.5 ']
98+
],
99+
'locale' => 'es_CL',
100+
'expected' => [
101+
['qty' => 10],
102+
['qty' => 0.5]
103+
],
104+
],
90105
];
91106
}
92107
}

0 commit comments

Comments
 (0)