Skip to content

Commit f4f8a54

Browse files
authored
Merge branch 'magento-commerce:2.4-develop' into B2B-1875
2 parents a8033fd + 63100b3 commit f4f8a54

File tree

17 files changed

+645
-10
lines changed

17 files changed

+645
-10
lines changed

app/code/Magento/CatalogInventory/Model/StockManagement.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ public function registerProductsSale($items, $websiteId = null)
119119
) {
120120
$this->getResource()->commit();
121121
throw new \Magento\Framework\Exception\LocalizedException(
122-
__('Not all of your products are available in the requested quantity.')
122+
__('Some of the products are out of stock.')
123123
);
124124
}
125125
if ($this->canSubtractQty($stockItem)) {
@@ -137,7 +137,7 @@ public function registerProductsSale($items, $websiteId = null)
137137
}
138138
$this->qtyCounter->correctItemsQty($registeredItems, $websiteId, '-');
139139
$this->getResource()->commit();
140-
140+
141141
return $fullSaveItems;
142142
}
143143

app/code/Magento/CatalogInventory/Model/StockStateProvider.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,9 @@ public function checkQty(StockItemInterface $stockItem, $qty)
249249
if (!$stockItem->getManageStock()) {
250250
return true;
251251
}
252+
if (!$stockItem->getIsInStock()) {
253+
return false;
254+
}
252255
if ($stockItem->getQty() - $stockItem->getMinQty() - $qty < 0) {
253256
switch ($stockItem->getBackorders()) {
254257
case \Magento\CatalogInventory\Model\Stock::BACKORDERS_YES_NONOTIFY:

app/code/Magento/CatalogInventory/Test/Unit/Model/Spi/StockStateProviderTest.php

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,21 @@ public function testCheckQty(StockItemInterface $stockItem, $expectedResult)
200200
);
201201
}
202202

203+
/**
204+
* Check quantity with out-of-stock status but positive or 0 quantity.
205+
*
206+
* @param StockItemInterface $stockItem
207+
* @param mixed $expectedResult
208+
* @dataProvider checkQtyWithStockStatusDataProvider
209+
*/
210+
public function testCheckQtyWithPositiveQtyAndOutOfStockstatus(StockItemInterface $stockItem, $expectedResult)
211+
{
212+
$this->assertEquals(
213+
$expectedResult,
214+
$this->stockStateProvider->checkQty($stockItem, $this->qty)
215+
);
216+
}
217+
203218
/**
204219
* @param StockItemInterface $stockItem
205220
* @param mixed $expectedResult
@@ -281,6 +296,14 @@ public function checkQtyDataProvider()
281296
return $this->prepareDataForMethod('checkQty');
282297
}
283298

299+
/**
300+
* @return array
301+
*/
302+
public function checkQtyWithStockStatusDataProvider()
303+
{
304+
return $this->prepareDataForMethod('checkQty', $this->getVariationsForQtyAndStock());
305+
}
306+
284307
/**
285308
* @return array
286309
*/
@@ -315,12 +338,16 @@ public function checkQuoteItemQtyDataProvider()
315338

316339
/**
317340
* @param $methodName
341+
* @param array|null $options
318342
* @return array
319343
*/
320-
protected function prepareDataForMethod($methodName)
344+
protected function prepareDataForMethod($methodName, array $options = null)
321345
{
322346
$variations = [];
323-
foreach ($this->getVariations() as $variation) {
347+
if ($options === null) {
348+
$options = $this->getVariations();
349+
}
350+
foreach ($options as $variation) {
324351
$stockItem = $this->getMockBuilder(StockItemInterface::class)
325352
->disableOriginalConstructor()
326353
->setMethods($this->stockItemMethods)
@@ -360,7 +387,7 @@ protected function prepareDataForMethod($methodName)
360387
/**
361388
* @return array
362389
*/
363-
protected function getVariations()
390+
private function getVariations()
364391
{
365392
$stockQty = 100;
366393
return [
@@ -448,6 +475,58 @@ protected function getVariations()
448475
];
449476
}
450477

478+
/**
479+
* @return array
480+
*/
481+
private function getVariationsForQtyAndStock()
482+
{
483+
$stockQty = 100;
484+
return [
485+
[
486+
'values' => [
487+
'getIsInStock' => false,
488+
'getQty' => $stockQty,
489+
'getMinQty' => 60,
490+
'getMinSaleQty' => 1,
491+
'getMaxSaleQty' => 99,
492+
'getNotifyStockQty' => 101,
493+
'getManageStock' => true,
494+
'getBackorders' => 0,
495+
'getQtyIncrements' => 1,
496+
'_stock_qty_' => null,
497+
'_suppress_check_qty_increments_' => false,
498+
'_is_saleable_' => true,
499+
'_ordered_items_' => 0,
500+
'_product_' => 'Test product Name',
501+
],
502+
'results' => [
503+
'checkQty' => false
504+
]
505+
],
506+
[
507+
'values' => [
508+
'getIsInStock' => false,
509+
'getQty' => 0,
510+
'getMinQty' => 60,
511+
'getMinSaleQty' => 1,
512+
'getMaxSaleQty' => 99,
513+
'getNotifyStockQty' => 101,
514+
'getManageStock' => true,
515+
'getBackorders' => 0,
516+
'getQtyIncrements' => 1,
517+
'_stock_qty_' => null,
518+
'_suppress_check_qty_increments_' => false,
519+
'_is_saleable_' => true,
520+
'_ordered_items_' => 0,
521+
'_product_' => 'Test product Name',
522+
],
523+
'results' => [
524+
'checkQty' => false
525+
]
526+
]
527+
];
528+
}
529+
451530
/**
452531
* @param bool $isChildItem
453532
* @param string $expectedMsg

app/code/Magento/CatalogInventory/Test/Unit/Model/StockManagementTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ public function testRegisterProductsSale(
204204
public function testRegisterProductsSaleException(array $items, array $lockedItems)
205205
{
206206
$this->expectException('Magento\Framework\Exception\LocalizedException');
207-
$this->expectExceptionMessage('Not all of your products are available in the requested quantity.');
207+
$this->expectExceptionMessage('Some of the products are out of stock.');
208208
$this->stockResourceMock
209209
->expects($this->once())
210210
->method('beginTransaction');
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Quote\Model;
9+
10+
use Magento\Framework\App\Config\ScopeConfigInterface;
11+
12+
/**
13+
* Config for inventory check on quote items load
14+
* @package Magento\Quote\Model
15+
*/
16+
class Config
17+
{
18+
const XML_PATH_INVENTORY_CHECK_ENABLED = 'cataloginventory/options/enable_inventory_check';
19+
20+
/** @var ScopeConfigInterface */
21+
private $config;
22+
23+
/**
24+
* Config constructor.
25+
* @param ScopeConfigInterface $config
26+
*/
27+
public function __construct(ScopeConfigInterface $config)
28+
{
29+
$this->config = $config;
30+
}
31+
32+
/**
33+
* Check if Inventory check is enabled
34+
* @return bool
35+
*/
36+
public function isEnabled(): bool
37+
{
38+
return (bool)$this->config->getValue(self::XML_PATH_INVENTORY_CHECK_ENABLED);
39+
}
40+
}

app/code/Magento/Quote/Model/Quote/Item/AbstractItem.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,6 @@ public function checkData()
326326
{
327327
$this->setHasError(false);
328328
$this->clearMessage();
329-
330329
$qty = $this->_getData('qty');
331330

332331
try {

app/code/Magento/Quote/Model/ResourceModel/Quote/Item/Collection.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\VersionContro
6363
*/
6464
private $recollectQuote = false;
6565

66+
/**
67+
* @var \Magento\Quote\Model\Config
68+
*/
69+
private $config;
70+
6671
/**
6772
* @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory
6873
* @param \Psr\Log\LoggerInterface $logger
@@ -75,6 +80,7 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\VersionContro
7580
* @param \Magento\Framework\DB\Adapter\AdapterInterface $connection
7681
* @param \Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource
7782
* @param \Magento\Store\Model\StoreManagerInterface|null $storeManager
83+
* @param \Magento\Quote\Model\Config|null $config
7884
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
7985
*/
8086
public function __construct(
@@ -88,7 +94,8 @@ public function __construct(
8894
\Magento\Quote\Model\Quote\Config $quoteConfig,
8995
\Magento\Framework\DB\Adapter\AdapterInterface $connection = null,
9096
\Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource = null,
91-
\Magento\Store\Model\StoreManagerInterface $storeManager = null
97+
\Magento\Store\Model\StoreManagerInterface $storeManager = null,
98+
\Magento\Quote\Model\Config $config = null
9299
) {
93100
parent::__construct(
94101
$entityFactory,
@@ -102,6 +109,8 @@ public function __construct(
102109
$this->_itemOptionCollectionFactory = $itemOptionCollectionFactory;
103110
$this->_productCollectionFactory = $productCollectionFactory;
104111
$this->_quoteConfig = $quoteConfig;
112+
$this->config = $config ?:
113+
\Magento\Framework\App\ObjectManager::getInstance()->get(\Magento\Quote\Model\Config::class);
105114

106115
// Backward compatibility constructor parameters
107116
$this->storeManager = $storeManager ?:
@@ -282,7 +291,10 @@ protected function _assignProducts(): self
282291
}
283292
if (!$item->isDeleted()) {
284293
$item->setQtyOptions($qtyOptions)->setProduct($product);
285-
$item->checkData();
294+
if ($this->config->isEnabled()) {
295+
$item->checkData();
296+
}
297+
286298
}
287299
}
288300
if ($this->recollectQuote && $this->_quote) {
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Quote\Test\Unit\Model\ResourceModel\Quote\Item;
9+
10+
use Magento\Framework\App\Config\ScopeConfigInterface;
11+
use Magento\Quote\Model\Config;
12+
use PHPUnit\Framework\TestCase;
13+
14+
class ConfigTest extends TestCase
15+
{
16+
/**
17+
* @var Config
18+
*/
19+
private $config;
20+
21+
/**
22+
* @var \PHPUnit\Framework\MockObject\MockObject
23+
*/
24+
private $configMock;
25+
26+
/**
27+
* @inheritDoc
28+
*/
29+
protected function setUp(): void
30+
{
31+
$this->configMock = $this->getMockForAbstractClass(ScopeConfigInterface::class);
32+
$this->configMock->method('getValue')->willReturn('1');
33+
$this->config = new Config($this->configMock);
34+
}
35+
36+
/**
37+
* @return void
38+
*/
39+
public function testIsEnabled()
40+
{
41+
$this->assertEquals(true, $this->config->isEnabled());
42+
}
43+
44+
/**
45+
* @return void
46+
*/
47+
public function testIsDisabled()
48+
{
49+
$this->setUpForDisabled();
50+
$this->assertEquals(false, $this->config->isEnabled());
51+
}
52+
53+
/**
54+
* @return void
55+
*/
56+
private function setUpForDisabled()
57+
{
58+
$this->configMock = $this->getMockForAbstractClass(ScopeConfigInterface::class);
59+
$this->configMock->method('getValue')->willReturn('0');
60+
$this->config = new Config($this->configMock);
61+
}
62+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
9+
<system>
10+
<section id="cataloginventory">
11+
<tab>catalog</tab>
12+
<group id="options">
13+
<field id="enable_inventory_check" translate="label" type="select" sortOrder="60" showInDefault="1" canRestore="1">
14+
<label>Enable Inventory Check On Cart Load</label>
15+
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
16+
<comment>Disabling inventory check skips pre validation of cart item data.</comment>
17+
</field>
18+
</group>
19+
</section>
20+
</system>
21+
</config>

app/code/Magento/Quote/etc/config.xml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
9+
<default>
10+
<cataloginventory>
11+
<options>
12+
<enable_inventory_check>1</enable_inventory_check>
13+
</options>
14+
</cataloginventory>
15+
</default>
16+
</config>

0 commit comments

Comments
 (0)