diff --git a/app/code/Magento/Backend/etc/adminhtml/system.xml b/app/code/Magento/Backend/etc/adminhtml/system.xml index 04bfe76bce9e7..6d950ae2c91ba 100644 --- a/app/code/Magento/Backend/etc/adminhtml/system.xml +++ b/app/code/Magento/Backend/etc/adminhtml/system.xml @@ -425,7 +425,7 @@ general Magento_Config::web - + @@ -435,7 +435,7 @@ Warning! When using Store Code in URLs, in some cases system may not work properly if URLs without Store Codes are specified in the third party services (e.g. PayPal etc.).]]> - + Magento\Config\Model\Config\Source\Web\Redirect I.e. redirect from http://example.com/store/ to http://www.example.com/store/ diff --git a/app/code/Magento/CatalogInventory/Model/ResourceModel/Product/StockStatusBaseSelectProcessor.php b/app/code/Magento/CatalogInventory/Model/ResourceModel/Product/StockStatusBaseSelectProcessor.php index 9f89d380a8f96..b80c26c53a76e 100644 --- a/app/code/Magento/CatalogInventory/Model/ResourceModel/Product/StockStatusBaseSelectProcessor.php +++ b/app/code/Magento/CatalogInventory/Model/ResourceModel/Product/StockStatusBaseSelectProcessor.php @@ -56,7 +56,9 @@ public function process(Select $select) ['stock' => $stockStatusTable], sprintf('stock.product_id = %s.entity_id', BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS), [] - )->where('stock.stock_status = ?', Stock::STOCK_IN_STOCK); + ) + ->where('stock.stock_status = ?', Stock::STOCK_IN_STOCK) + ->where('stock.website_id = ?', 0); } return $select; diff --git a/app/code/Magento/CatalogInventory/Observer/ProcessInventoryDataObserver.php b/app/code/Magento/CatalogInventory/Observer/ProcessInventoryDataObserver.php index e473f714bd21d..cea19c098b928 100644 --- a/app/code/Magento/CatalogInventory/Observer/ProcessInventoryDataObserver.php +++ b/app/code/Magento/CatalogInventory/Observer/ProcessInventoryDataObserver.php @@ -97,7 +97,7 @@ private function prepareQuantityAndStockStatus(StockItemInterface $stockItem, ar ) { unset($quantityAndStockStatus['is_in_stock']); } - if (isset($quantityAndStockStatus['qty']) + if (array_key_exists('qty', $quantityAndStockStatus) && $stockItem->getQty() == $quantityAndStockStatus['qty'] ) { unset($quantityAndStockStatus['qty']); diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/ResourceModel/Product/StockStatusBaseSelectProcessorTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/ResourceModel/Product/StockStatusBaseSelectProcessorTest.php index 9a46dc99ee008..0598fe7e9fe71 100644 --- a/app/code/Magento/CatalogInventory/Test/Unit/Model/ResourceModel/Product/StockStatusBaseSelectProcessorTest.php +++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/ResourceModel/Product/StockStatusBaseSelectProcessorTest.php @@ -56,9 +56,13 @@ public function testProcess() [] ) ->willReturnSelf(); - $this->select->expects($this->once()) + + $this->select->expects($this->exactly(2)) ->method('where') - ->with('stock.stock_status = ?', Stock::STOCK_IN_STOCK) + ->withConsecutive( + ['stock.stock_status = ?', Stock::STOCK_IN_STOCK, null], + ['stock.website_id = ?', 0, null] + ) ->willReturnSelf(); $this->stockStatusBaseSelectProcessor->process($this->select); diff --git a/app/code/Magento/SampleData/Model/Dependency.php b/app/code/Magento/SampleData/Model/Dependency.php index e3949a6bd502e..a475560dd6089 100644 --- a/app/code/Magento/SampleData/Model/Dependency.php +++ b/app/code/Magento/SampleData/Model/Dependency.php @@ -12,7 +12,7 @@ use Magento\Framework\Config\Composer\Package; use Magento\Framework\Config\Composer\PackageFactory; use Magento\Framework\Filesystem; -use Magento\Framework\Filesystem\Directory\ReadInterfaceFactory; +use Magento\Framework\Filesystem\Directory\ReadFactory; /** * Sample Data dependency @@ -40,7 +40,7 @@ class Dependency private $componentRegistrar; /** - * @var ReadInterfaceFactory + * @var ReadFactory */ private $directoryReadFactory; @@ -51,7 +51,7 @@ class Dependency * @param Filesystem $filesystem @deprecated 2.3.0 $directoryReadFactory is used instead * @param PackageFactory $packageFactory * @param ComponentRegistrarInterface $componentRegistrar - * @param Filesystem\Directory\ReadInterfaceFactory|null $directoryReadFactory + * @param Filesystem\Directory\ReadFactory|null $directoryReadFactory * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function __construct( @@ -59,13 +59,13 @@ public function __construct( Filesystem $filesystem, PackageFactory $packageFactory, ComponentRegistrarInterface $componentRegistrar, - \Magento\Framework\Filesystem\Directory\ReadInterfaceFactory $directoryReadFactory = null + \Magento\Framework\Filesystem\Directory\ReadFactory $directoryReadFactory = null ) { $this->composerInformation = $composerInformation; $this->packageFactory = $packageFactory; $this->componentRegistrar = $componentRegistrar; $this->directoryReadFactory = $directoryReadFactory ?: - ObjectManager::getInstance()->get(ReadInterfaceFactory::class); + ObjectManager::getInstance()->get(ReadFactory::class); } /** @@ -123,7 +123,7 @@ private function getModuleComposerPackage($moduleDir) */ foreach ([$moduleDir, $moduleDir . DIRECTORY_SEPARATOR . '..'] as $dir) { /** @var Filesystem\Directory\ReadInterface $directory */ - $directory = $this->directoryReadFactory->create(['path' => $dir]); + $directory = $this->directoryReadFactory->create($dir); if ($directory->isExist('composer.json') && $directory->isReadable('composer.json')) { /** @var Package $package */ return $this->packageFactory->create(['json' => json_decode($directory->readFile('composer.json'))]); diff --git a/app/code/Magento/SampleData/Test/Unit/Model/DependencyTest.php b/app/code/Magento/SampleData/Test/Unit/Model/DependencyTest.php index f7dc46d1128ad..adf5a9eb6ebe4 100644 --- a/app/code/Magento/SampleData/Test/Unit/Model/DependencyTest.php +++ b/app/code/Magento/SampleData/Test/Unit/Model/DependencyTest.php @@ -14,6 +14,7 @@ use Magento\Framework\Filesystem; use Magento\Framework\Phrase; use Magento\SampleData\Model\Dependency; +use Magento\Framework\Filesystem\DriverPool; class DependencyTest extends \PHPUnit\Framework\TestCase { @@ -59,7 +60,7 @@ public function testPackagesFromComposerSuggest( $moduleDirectories ); - $directoryReadFactory = $this->getMockBuilder(Filesystem\Directory\ReadInterfaceFactory::class) + $directoryReadFactory = $this->getMockBuilder(Filesystem\Directory\ReadFactory::class) ->disableOriginalConstructor() ->setMethods(['create']) ->getMock(); @@ -88,7 +89,8 @@ public static function dataPackagesFromComposerSuggest() 'composerJsonGenerator' => function (DependencyTest $test) { return [ [ - ['path' => 'app/code/LocalModule'], + 'app/code/LocalModule', + DriverPool::FILE, $test->stubComposerJsonReader( [ 'name' => 'local/module', @@ -99,11 +101,13 @@ public static function dataPackagesFromComposerSuggest() ) ], [ - ['path' => 'app/code/LocalModuleWithoutComposerJson'], + 'app/code/LocalModuleWithoutComposerJson', + DriverPool::FILE, $test->stubFileNotFoundReader() ], [ - ['path' => 'vendor/company/module'], + 'vendor/company/module', + DriverPool::FILE, $test->stubComposerJsonReader( [ 'name' => 'company/module', @@ -114,7 +118,8 @@ public static function dataPackagesFromComposerSuggest() ) ], [ - ['path' => 'vendor/company2/module/src/..'], + 'vendor/company2/module/src/..', + DriverPool::FILE, $test->stubComposerJsonReader( [ 'name' => 'company2/module', @@ -125,19 +130,23 @@ public static function dataPackagesFromComposerSuggest() ) ], [ - ['path' => 'vendor/company2/module/src'], + 'vendor/company2/module/src', + DriverPool::FILE, $test->stubFileNotFoundReader() ], [ - ['path' => 'vendor/company/module/..'], + 'vendor/company/module/..', + DriverPool::FILE, $test->stubFileNotFoundReader() ], [ - ['path' => 'app/code/LocalModuleWithoutComposerJson/..'], + 'app/code/LocalModuleWithoutComposerJson/..', + DriverPool::FILE, $test->stubFileNotFoundReader() ], [ - ['path' => 'app/code/LocalModule/..'], + 'app/code/LocalModule/..', + DriverPool::FILE, $test->stubFileNotFoundReader() ], ]; diff --git a/app/code/Magento/SampleData/etc/di.xml b/app/code/Magento/SampleData/etc/di.xml index 93cf98a41150c..412e86c150f52 100644 --- a/app/code/Magento/SampleData/etc/di.xml +++ b/app/code/Magento/SampleData/etc/di.xml @@ -15,10 +15,4 @@ - - - Magento\Framework\Filesystem\Driver\File - - - diff --git a/dev/tests/api-functional/testsuite/Magento/CatalogInventory/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/CatalogInventory/Api/ProductRepositoryInterfaceTest.php index 9478eca88a3fa..5422362afd73c 100644 --- a/dev/tests/api-functional/testsuite/Magento/CatalogInventory/Api/ProductRepositoryInterfaceTest.php +++ b/dev/tests/api-functional/testsuite/Magento/CatalogInventory/Api/ProductRepositoryInterfaceTest.php @@ -23,8 +23,9 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract const KEY_PRODUCT_ID = StockStatusInterface::PRODUCT_ID; const KEY_CUSTOM_ATTRIBUTES = 'custom_attributes'; const KEY_ATTRIBUTE_CODE = \Magento\Eav\Api\Data\AttributeInterface::ATTRIBUTE_CODE; - const CODE_QUANTITY_AND_STOCK_STATUS = 'quantity_and_stock_status'; + const KEY_IS_IN_STOCK = 'is_in_stock'; + const CODE_QUANTITY_AND_STOCK_STATUS = 'quantity_and_stock_status'; const PRODUCT_SKU = 'sku-test-catalog-inventory'; /** @@ -159,6 +160,36 @@ public function testSimpleProductCreationWithoutSpecifyingCatalogInventory() $this->assertTrue($response); } + /** + * Tests updating product stock item data when previously product was created without specified stock_item + */ + public function testUpdatingQuantity() + { + // create a simple product with catalog inventory + $qty = null; + $productData = $this->getSimpleProductData($qty); + $response = $this->saveProduct($productData); + $stockItemData = $response[self::KEY_EXTENSION_ATTRIBUTES][self::KEY_STOCK_ITEM]; + + $this->assertEquals($qty, $stockItemData[self::KEY_QTY]); + $this->assertEquals(false, $stockItemData[self::KEY_IS_IN_STOCK]); + + // update a created product with catalog inventory + $qty = 1; + $inStock = true; + $response[self::KEY_EXTENSION_ATTRIBUTES][self::KEY_STOCK_ITEM][self::KEY_QTY] = $qty; + $response[self::KEY_EXTENSION_ATTRIBUTES][self::KEY_STOCK_ITEM][self::KEY_IS_IN_STOCK] = $inStock; + $responseUpdated = $this->updateProduct($response); + $stockItemDataUpdated = $responseUpdated[self::KEY_EXTENSION_ATTRIBUTES][self::KEY_STOCK_ITEM]; + + $this->assertEquals($qty, $stockItemDataUpdated[self::KEY_QTY]); + $this->assertEquals($inStock, $stockItemDataUpdated[self::KEY_IS_IN_STOCK]); + + // delete the product; expect that all goes well + $response = $this->deleteProduct($productData[ProductInterface::SKU]); + $this->assertTrue($response); + } + // --- my helpers ----------------------------------------------------------------------------- /** @@ -195,7 +226,7 @@ protected function getSimpleProductData($qty = 1000) [self::KEY_ATTRIBUTE_CODE => 'description', 'value' => 'My Product Description'], [ self::KEY_ATTRIBUTE_CODE => self::CODE_QUANTITY_AND_STOCK_STATUS, - 'value' => ['is_in_stock' => true, 'qty' => $qty] + 'value' => [self::KEY_IS_IN_STOCK => true, 'qty' => $qty] ], ]; } @@ -214,7 +245,7 @@ protected function getStockItemData($qty = 1000) return [ self::KEY_STOCK_ITEM => [ self::KEY_QTY => $qty, - 'is_in_stock' => true, + self::KEY_IS_IN_STOCK => true, 'is_qty_decimal' => false, 'show_default_notification_message' => false, 'use_config_min_qty' => true,