From 15928fbd8c42590187f0613f889cc27d6afabe0d Mon Sep 17 00:00:00 2001
From: RomanKis <romaikiss@gmail.com>
Date: Mon, 11 Dec 2017 16:21:21 +0200
Subject: [PATCH] 8624: Stock status not coming back after qty update

---
 .../Model/Stock/StockItemRepository.php       | 30 +++++++++--
 .../Model/Stock/StockItemRepositoryTest.php   |  2 +-
 .../Magento/Catalog/Model/ProductTest.php     | 32 ++++++++++++
 .../_files/product_simple_out_of_stock.php    | 51 +++++++++++++++++++
 .../product_simple_out_of_stock_rollback.php  | 25 +++++++++
 .../ByStockItemRepositoryTest.php             |  2 +-
 .../ByQuantityAndStockStatusTest.php          |  2 +-
 .../ByProductModel/ByStockDataTest.php        |  2 +-
 .../ByProductModel/ByStockItemTest.php        |  2 +-
 .../ByQuantityAndStockStatusTest.php          |  2 +-
 .../ByProductRepository/ByStockDataTest.php   |  2 +-
 .../ByProductRepository/ByStockItemTest.php   |  2 +-
 .../ByProductModel/ByStockItemTest.php        |  2 +-
 .../ByProductRepository/ByStockItemTest.php   |  2 +-
 .../Framework/Data/AbstractSearchResult.php   |  1 +
 15 files changed, 144 insertions(+), 15 deletions(-)
 create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_out_of_stock.php
 create mode 100644 dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_out_of_stock_rollback.php

diff --git a/app/code/Magento/CatalogInventory/Model/Stock/StockItemRepository.php b/app/code/Magento/CatalogInventory/Model/Stock/StockItemRepository.php
index e5154a10f0a..a675709e504 100644
--- a/app/code/Magento/CatalogInventory/Model/Stock/StockItemRepository.php
+++ b/app/code/Magento/CatalogInventory/Model/Stock/StockItemRepository.php
@@ -145,7 +145,7 @@ class StockItemRepository implements StockItemRepositoryInterface
     /**
      * @inheritdoc
      */
-    public function save(\Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem)
+    public function save(StockItemInterface $stockItem)
     {
         try {
             /** @var \Magento\Catalog\Model\Product $product */
@@ -161,10 +161,7 @@ class StockItemRepository implements StockItemRepositoryInterface
             $typeId = $product->getTypeId() ?: $product->getTypeInstance()->getTypeId();
             $isQty = $this->stockConfiguration->isQty($typeId);
             if ($isQty) {
-                $isInStock = $this->stockStateProvider->verifyStock($stockItem);
-                if ($stockItem->getManageStock() && !$isInStock) {
-                    $stockItem->setIsInStock(false)->setStockStatusChangedAutomaticallyFlag(true);
-                }
+                $this->changeIsInStockIfNecessary($stockItem);
                 // if qty is below notify qty, update the low stock date to today date otherwise set null
                 $stockItem->setLowStockDate(null);
                 if ($this->stockStateProvider->verifyNotification($stockItem)) {
@@ -260,4 +257,27 @@ class StockItemRepository implements StockItemRepositoryInterface
         }
         return $this->stockRegistryStorage;
     }
+
+    /**
+     * Change is_in_stock value if necessary.
+     *
+     * @param StockItemInterface $stockItem
+     *
+     * @return void
+     */
+    private function changeIsInStockIfNecessary(StockItemInterface $stockItem)
+    {
+        $isInStock = $this->stockStateProvider->verifyStock($stockItem);
+        if ($stockItem->getManageStock() && !$isInStock) {
+            $stockItem->setIsInStock(false)->setStockStatusChangedAutomaticallyFlag(true);
+        }
+
+        if ($stockItem->getManageStock()
+            && $isInStock
+            && !$stockItem->getIsInStock()
+            && $stockItem->getOrigData(\Magento\CatalogInventory\Api\Data\StockItemInterface::QTY) == 0
+        ) {
+            $stockItem->setIsInStock(true)->setStockStatusChangedAutomaticallyFlag(true);
+        }
+    }
 }
diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/Stock/StockItemRepositoryTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/Stock/StockItemRepositoryTest.php
index 293874bb32b..6b1770ff7d4 100644
--- a/app/code/Magento/CatalogInventory/Test/Unit/Model/Stock/StockItemRepositoryTest.php
+++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/Stock/StockItemRepositoryTest.php
@@ -276,7 +276,7 @@ class StockItemRepositoryTest extends \PHPUnit\Framework\TestCase
             ->method('verifyStock')
             ->with($this->stockItemMock)
             ->willReturn(false);
-        $this->stockItemMock->expects($this->once())->method('getManageStock')->willReturn(true);
+        $this->stockItemMock->expects($this->exactly(2))->method('getManageStock')->willReturn(true);
         $this->stockItemMock->expects($this->once())->method('setIsInStock')->with(false)->willReturnSelf();
         $this->stockItemMock->expects($this->once())
             ->method('setStockStatusChangedAutomaticallyFlag')
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php
index 99a1e9309f6..078a83bcf63 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php
@@ -549,4 +549,36 @@ class ProductTest extends \PHPUnit\Framework\TestCase
             }
         }
     }
+
+    /**
+     * @magentoDataFixture Magento/Catalog/_files/product_simple_out_of_stock.php
+     */
+    public function testSaveWithDifferentQty()
+    {
+        //if save (out of stock product with qty 0) with new qty > 0 it should become in stock.
+        //if set out of stock for product with qty > 0 it should become out of stock
+        $product = $this->productRepository->get('simple-out-of-stock');
+        $stockItem = $product->getExtensionAttributes()->getStockItem();
+        $this->assertEquals(false, $stockItem->getIsInStock());
+        $stockData = [
+            'qty'                       => 5,
+            'is_in_stock'               => 0,
+        ];
+        $product->setStockData($stockData);
+        $product->save();
+
+        $product = $this->productRepository->get('simple-out-of-stock');
+        $stockItem = $product->getExtensionAttributes()->getStockItem();
+        $this->assertEquals(true, $stockItem->getIsInStock());
+        $stockData = [
+            'qty'                       => 3,
+            'is_in_stock'               => 0,
+        ];
+        $product->setStockData($stockData);
+        $product->save();
+
+        $product = $this->productRepository->get('simple-out-of-stock');
+        $stockItem = $product->getExtensionAttributes()->getStockItem();
+        $this->assertEquals(false, $stockItem->getIsInStock());
+    }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_out_of_stock.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_out_of_stock.php
new file mode 100644
index 00000000000..729ea2ab982
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_out_of_stock.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+\Magento\TestFramework\Helper\Bootstrap::getInstance()->reinitialize();
+
+/** @var \Magento\TestFramework\ObjectManager $objectManager */
+$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
+/** @var \Magento\Catalog\Api\CategoryLinkManagementInterface $categoryLinkManagement */
+$categoryLinkManagement = $objectManager->get(\Magento\Catalog\Api\CategoryLinkManagementInterface::class);
+
+/** @var $product \Magento\Catalog\Model\Product */
+$product = $objectManager->create(\Magento\Catalog\Model\Product::class);
+$product->isObjectNew(true);
+$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE)
+    ->setId(1)
+    ->setAttributeSetId(4)
+    ->setWebsiteIds([1])
+    ->setName('Simple Product')
+    ->setSku('simple-out-of-stock')
+    ->setPrice(10)
+    ->setWeight(1)
+    ->setShortDescription("Short description")
+    ->setTaxClassId(0)
+    ->setDescription('Description with <b>html tag</b>')
+    ->setMetaTitle('meta title')
+    ->setMetaKeyword('meta keyword')
+    ->setMetaDescription('meta description')
+    ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
+    ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
+    ->setStockData(
+        [
+            'use_config_manage_stock'   => 1,
+            'qty'                       => 0,
+            'is_qty_decimal'            => 0,
+            'is_in_stock'               => 0,
+        ]
+    )->setCanSaveCustomOptions(true)
+    ->setHasOptions(true);
+
+/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepositoryFactory */
+$productRepository = $objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class);
+$productRepository->save($product);
+
+$categoryLinkManagement->assignProductToCategories(
+    $product->getSku(),
+    [2]
+);
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_out_of_stock_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_out_of_stock_rollback.php
new file mode 100644
index 00000000000..2bb2858687f
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_out_of_stock_rollback.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Copyright © Magento, Inc. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+use Magento\Framework\Exception\NoSuchEntityException;
+
+\Magento\TestFramework\Helper\Bootstrap::getInstance()->getInstance()->reinitialize();
+
+/** @var \Magento\Framework\Registry $registry */
+$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class);
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', true);
+
+/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */
+$productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
+    ->get(\Magento\Catalog\Api\ProductRepositoryInterface::class);
+try {
+    $product = $productRepository->get('simple-out-of-stock', false, null, true);
+    $productRepository->delete($product);
+} catch (NoSuchEntityException $e) {
+}
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', false);
diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/ByStockItemRepositoryTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/ByStockItemRepositoryTest.php
index ae67d3fa1ed..dfe21a61c86 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/ByStockItemRepositoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/ByStockItemRepositoryTest.php
@@ -40,7 +40,7 @@ class ByStockItemRepositoryTest extends \PHPUnit\Framework\TestCase
     private $stockItemData = [
         StockItemInterface::QTY => 555,
         StockItemInterface::MANAGE_STOCK => true,
-        StockItemInterface::IS_IN_STOCK => false,
+        StockItemInterface::IS_IN_STOCK => true,
     ];
 
     public function setUp()
diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductCreate/ByProductModel/ByQuantityAndStockStatusTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductCreate/ByProductModel/ByQuantityAndStockStatusTest.php
index 6864b9a3456..ec5dc7c5b0c 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductCreate/ByProductModel/ByQuantityAndStockStatusTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductCreate/ByProductModel/ByQuantityAndStockStatusTest.php
@@ -53,7 +53,7 @@ class ByQuantityAndStockStatusTest extends \PHPUnit\Framework\TestCase
     private $stockItemData = [
         StockItemInterface::QTY => 555,
         StockItemInterface::MANAGE_STOCK => true,
-        StockItemInterface::IS_IN_STOCK => false,
+        StockItemInterface::IS_IN_STOCK => true,
     ];
 
     public function setUp()
diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductCreate/ByProductModel/ByStockDataTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductCreate/ByProductModel/ByStockDataTest.php
index eae20bda1a9..7638936c34a 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductCreate/ByProductModel/ByStockDataTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductCreate/ByProductModel/ByStockDataTest.php
@@ -53,7 +53,7 @@ class ByStockDataTest extends \PHPUnit\Framework\TestCase
     private $stockItemData = [
         StockItemInterface::QTY => 555,
         StockItemInterface::MANAGE_STOCK => true,
-        StockItemInterface::IS_IN_STOCK => false,
+        StockItemInterface::IS_IN_STOCK => true,
     ];
 
     public function setUp()
diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductCreate/ByProductModel/ByStockItemTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductCreate/ByProductModel/ByStockItemTest.php
index 25b9817bcf5..d5dae31b891 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductCreate/ByProductModel/ByStockItemTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductCreate/ByProductModel/ByStockItemTest.php
@@ -59,7 +59,7 @@ class ByStockItemTest extends \PHPUnit\Framework\TestCase
     private $stockItemData = [
         StockItemInterface::QTY => 555,
         StockItemInterface::MANAGE_STOCK => true,
-        StockItemInterface::IS_IN_STOCK => false,
+        StockItemInterface::IS_IN_STOCK => true,
     ];
 
     public function setUp()
diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductCreate/ByProductRepository/ByQuantityAndStockStatusTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductCreate/ByProductRepository/ByQuantityAndStockStatusTest.php
index 6269d7a20f4..fc1d787df53 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductCreate/ByProductRepository/ByQuantityAndStockStatusTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductCreate/ByProductRepository/ByQuantityAndStockStatusTest.php
@@ -59,7 +59,7 @@ class ByQuantityAndStockStatusTest extends \PHPUnit\Framework\TestCase
     private $stockItemData = [
         StockItemInterface::QTY => 555,
         StockItemInterface::MANAGE_STOCK => true,
-        StockItemInterface::IS_IN_STOCK => false,
+        StockItemInterface::IS_IN_STOCK => true,
     ];
 
     public function setUp()
diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductCreate/ByProductRepository/ByStockDataTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductCreate/ByProductRepository/ByStockDataTest.php
index fa7cc39f758..9050aaf6c88 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductCreate/ByProductRepository/ByStockDataTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductCreate/ByProductRepository/ByStockDataTest.php
@@ -59,7 +59,7 @@ class ByStockDataTest extends \PHPUnit\Framework\TestCase
     private $stockItemData = [
         StockItemInterface::QTY => 555,
         StockItemInterface::MANAGE_STOCK => true,
-        StockItemInterface::IS_IN_STOCK => false,
+        StockItemInterface::IS_IN_STOCK => true,
     ];
 
     public function setUp()
diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductCreate/ByProductRepository/ByStockItemTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductCreate/ByProductRepository/ByStockItemTest.php
index 857457325c7..1884a46e216 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductCreate/ByProductRepository/ByStockItemTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductCreate/ByProductRepository/ByStockItemTest.php
@@ -70,7 +70,7 @@ class ByStockItemTest extends \PHPUnit\Framework\TestCase
     private $stockItemData = [
         StockItemInterface::QTY => 555,
         StockItemInterface::MANAGE_STOCK => true,
-        StockItemInterface::IS_IN_STOCK => false,
+        StockItemInterface::IS_IN_STOCK => true,
     ];
 
     public function setUp()
diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductUpdate/ByProductModel/ByStockItemTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductUpdate/ByProductModel/ByStockItemTest.php
index 2a4b7937f71..5a726170a01 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductUpdate/ByProductModel/ByStockItemTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductUpdate/ByProductModel/ByStockItemTest.php
@@ -42,7 +42,7 @@ class ByStockItemTest extends \PHPUnit\Framework\TestCase
     private $stockItemData = [
         StockItemInterface::QTY => 555,
         StockItemInterface::MANAGE_STOCK => true,
-        StockItemInterface::IS_IN_STOCK => false,
+        StockItemInterface::IS_IN_STOCK => true,
     ];
 
     public function setUp()
diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductUpdate/ByProductRepository/ByStockItemTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductUpdate/ByProductRepository/ByStockItemTest.php
index 81871d3398c..3053b8d6acf 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductUpdate/ByProductRepository/ByStockItemTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/StockItemSave/OnProductUpdate/ByProductRepository/ByStockItemTest.php
@@ -48,7 +48,7 @@ class ByStockItemTest extends \PHPUnit\Framework\TestCase
     private $stockItemData = [
         StockItemInterface::QTY => 555,
         StockItemInterface::MANAGE_STOCK => true,
-        StockItemInterface::IS_IN_STOCK => false,
+        StockItemInterface::IS_IN_STOCK => true,
     ];
 
     public function setUp()
diff --git a/lib/internal/Magento/Framework/Data/AbstractSearchResult.php b/lib/internal/Magento/Framework/Data/AbstractSearchResult.php
index f9272683005..bcedf16e3f5 100644
--- a/lib/internal/Magento/Framework/Data/AbstractSearchResult.php
+++ b/lib/internal/Magento/Framework/Data/AbstractSearchResult.php
@@ -235,6 +235,7 @@ abstract class AbstractSearchResult extends AbstractDataObject implements Search
             if (is_array($data)) {
                 foreach ($data as $row) {
                     $item = $this->createDataObject(['data' => $row]);
+                    $item->setOrigData();
                     $this->addItem($item);
                 }
             }
-- 
GitLab