diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Sku.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Sku.php old mode 100644 new mode 100755 index 98738e055ca8f..44404710eb2ae --- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Sku.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Sku.php @@ -3,13 +3,14 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Catalog\Model\Product\Attribute\Backend; use Magento\Catalog\Model\Product; /** - * Catalog product SKU backend attribute model. + * Catalog product SKU backend attribute model + * + * @author Magento Core Team */ class Sku extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend { @@ -58,6 +59,15 @@ public function validate($object) __('SKU length should be %1 characters maximum.', self::SKU_MAX_LENGTH) ); } + + $attribute = $this->getAttribute(); + $entity = $attribute->getEntity(); + if (!$entity->checkAttributeUniqueValue($attribute, $object)) { + throw new \Magento\Framework\Exception\LocalizedException( + __('SKU is already in use.') + ); + } + return true; } @@ -94,8 +104,9 @@ protected function _generateUniqueSku($object) */ public function beforeSave($object) { - $this->_generateUniqueSku($object); - $this->trimValue($object); + if ($object->getIsDuplicate()) { + $this->_generateUniqueSku($object); + } return parent::beforeSave($object); } @@ -126,19 +137,4 @@ protected function _getLastSimilarAttributeValueIncrement($attribute, $object) $data = $connection->fetchOne($select, $bind); return abs((int)str_replace($value, '', $data)); } - - /** - * Remove extra spaces from attribute value before save. - * - * @param Product $object - * @return void - */ - private function trimValue($object) - { - $attrCode = $this->getAttribute()->getAttributeCode(); - $value = $object->getData($attrCode); - if ($value) { - $object->setData($attrCode, trim($value)); - } - } } diff --git a/dev/tests/functional/tests/app/Magento/CatalogUrlRewrite/Test/TestCase/CreateDuplicateUrlProductEntity.php b/dev/tests/functional/tests/app/Magento/CatalogUrlRewrite/Test/TestCase/CreateDuplicateUrlProductEntity.php index 2cfaecd8efe5d..591a0d8eded23 100644 --- a/dev/tests/functional/tests/app/Magento/CatalogUrlRewrite/Test/TestCase/CreateDuplicateUrlProductEntity.php +++ b/dev/tests/functional/tests/app/Magento/CatalogUrlRewrite/Test/TestCase/CreateDuplicateUrlProductEntity.php @@ -68,6 +68,7 @@ public function __prepare(Category $category) * Run create product simple entity test. * * @param CatalogProductSimple $product + * @param CatalogProductSimple $product2 * @param Category $category * @param CatalogProductIndex $productGrid * @param CatalogProductNew $newProductPage @@ -77,6 +78,7 @@ public function __prepare(Category $category) */ public function testCreate( CatalogProductSimple $product, + CatalogProductSimple $product2, Category $category, CatalogProductIndex $productGrid, CatalogProductNew $newProductPage, @@ -92,13 +94,15 @@ public function testCreate( ['configData' => $this->configData, 'flushCache' => $this->flushCache] )->run(); - for ($index = 0; $index < 2; $index++) { - // Duplicate product - $productGrid->open(); - $productGrid->getGridPageActionBlock()->addProduct('simple'); - $newProductPage->getProductForm()->fill($product, null, $category); - $newProductPage->getFormPageActions()->save(); - } + $productGrid->open(); + $productGrid->getGridPageActionBlock()->addProduct('simple'); + $newProductPage->getProductForm()->fill($product, null, $category); + $newProductPage->getFormPageActions()->save(); + + $productGrid->open(); + $productGrid->getGridPageActionBlock()->addProduct('simple'); + $newProductPage->getProductForm()->fill($product2, null, $category); + $newProductPage->getFormPageActions()->save(); return ['product' => $product]; } diff --git a/dev/tests/functional/tests/app/Magento/CatalogUrlRewrite/Test/TestCase/CreateDuplicateUrlProductEntity.xml b/dev/tests/functional/tests/app/Magento/CatalogUrlRewrite/Test/TestCase/CreateDuplicateUrlProductEntity.xml old mode 100644 new mode 100755 index 8110ed1ed00b1..17f3b75e70a70 --- a/dev/tests/functional/tests/app/Magento/CatalogUrlRewrite/Test/TestCase/CreateDuplicateUrlProductEntity.xml +++ b/dev/tests/functional/tests/app/Magento/CatalogUrlRewrite/Test/TestCase/CreateDuplicateUrlProductEntity.xml @@ -8,13 +8,19 @@ - test_type:acceptance_test, test_type:extended_acceptance_test, severity:S1, mftf_migrated:yes - simple-product-%isolation% + test_type:acceptance_test, test_type:extended_acceptance_test, severity:S1 + simple-product-samekey Simple Product %isolation% simple_sku_%isolation% 10000 50 657 + simple-product-samekey + Simple Product %isolation% + simple_sku_%isolation% + 10000 + 50 + 657 diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/SkuTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/SkuTest.php index f557919897869..63b64e102e585 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/SkuTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/SkuTest.php @@ -14,18 +14,34 @@ class SkuTest extends \PHPUnit\Framework\TestCase /** * @magentoDataFixture Magento/Catalog/_files/product_simple.php */ - public function testGenerateUniqueSkuExistingProduct() + public function testGenerateUniqueSkuExistingProductDuplication() { $repository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( \Magento\Catalog\Model\ProductRepository::class ); $product = $repository->get('simple'); $product->setId(null); + $product->setIsDuplicate(true); $this->assertEquals('simple', $product->getSku()); $product->getResource()->getAttribute('sku')->getBackend()->beforeSave($product); $this->assertEquals('simple-1', $product->getSku()); } + /** + * @magentoDataFixture Magento/Catalog/_files/product_simple.php + */ + public function testGenerateUniqueSkuExistingProductNoDuplication() + { + $repository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( + \Magento\Catalog\Model\ProductRepository::class + ); + $product = $repository->get('simple'); + $product->setId(null); + $this->assertEquals('simple', $product->getSku()); + $product->getResource()->getAttribute('sku')->getBackend()->beforeSave($product); + $this->assertEquals('simple', $product->getSku()); + } + /** * @param $product \Magento\Catalog\Model\Product * @dataProvider uniqueSkuDataProvider @@ -48,16 +64,15 @@ public function testGenerateUniqueLongSku() \Magento\Catalog\Model\ProductRepository::class ); $product = $repository->get('simple'); - $product->setSku('0123456789012345678901234567890123456789012345678901234567890123'); + $product->setSku('0123456789012345678901234567890123456789012345678901234567890123')->save(); /** @var \Magento\Catalog\Model\Product\Copier $copier */ $copier = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get( \Magento\Catalog\Model\Product\Copier::class ); - $copier->copy($product); + $copy = $copier->copy($product); $this->assertEquals('0123456789012345678901234567890123456789012345678901234567890123', $product->getSku()); - $product->getResource()->getAttribute('sku')->getBackend()->beforeSave($product); - $this->assertEquals('01234567890123456789012345678901234567890123456789012345678901-1', $product->getSku()); + $this->assertEquals('01234567890123456789012345678901234567890123456789012345678901-1', $copy->getSku()); } /** diff --git a/dev/tests/integration/testsuite/Magento/CatalogRule/Model/Indexer/IndexerBuilderTest.php b/dev/tests/integration/testsuite/Magento/CatalogRule/Model/Indexer/IndexerBuilderTest.php index 13f6e5ae0e8ed..a1b8e1662afeb 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogRule/Model/Indexer/IndexerBuilderTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogRule/Model/Indexer/IndexerBuilderTest.php @@ -137,10 +137,11 @@ protected function prepareProducts() $this->product->setStoreId(0)->setData('test_attribute', 'test_attribute_value')->save(); $this->productSecond = clone $this->product; - $this->productSecond->setId(null)->setUrlKey('product-second')->save(); + $this->productSecond->setId(null)->setUrlKey('product-second')->setIsDuplicate(true)->save(); $this->productThird = clone $this->product; $this->productThird->setId(null) ->setUrlKey('product-third') + ->setIsDuplicate(true) ->setData('test_attribute', 'NO_test_attribute_value') ->save(); }