From e10aa1040791fffced799c2a207aa97f31703512 Mon Sep 17 00:00:00 2001 From: Sergey Kovalenko Date: Thu, 25 Aug 2016 16:06:15 +0300 Subject: [PATCH 1/8] MAGETWO-56859: Attribute for Send Welcome Email From shows wrong store ID --- .../Magento/Customer/view/base/ui_component/customer_form.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/code/Magento/Customer/view/base/ui_component/customer_form.xml b/app/code/Magento/Customer/view/base/ui_component/customer_form.xml index 829d792fdd8cb..3832d509fd913 100644 --- a/app/code/Magento/Customer/view/base/ui_component/customer_form.xml +++ b/app/code/Magento/Customer/view/base/ui_component/customer_form.xml @@ -250,6 +250,10 @@ Send Welcome Email From number select + customer + + ${ $.provider }:data.customer.store_id + From 2dd0ef25999b15f88935ef9e579a9562a61eb763 Mon Sep 17 00:00:00 2001 From: Sergii Kovalenko Date: Thu, 8 Sep 2016 04:46:48 -0700 Subject: [PATCH 2/8] MAGETWO-57491: [Backport] - Maximum error count when importing because issue URL key for specified store already exists - for 2.0 --- .../Model/Import/Product.php | 42 +++++++++++-- .../Model/Import/ProductTest.php | 61 ++++++++++++++++++- ...products_to_import_with_multiple_store.csv | 6 ++ 3 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_multiple_store.csv diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index c2fe86a8ec4c4..39b3c6ce471c6 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -1248,23 +1248,57 @@ protected function _saveProductEntity(array $entityRowsIn, array $entityRowsUp) if ($entityRowsIn) { $this->_connection->insertMultiple($entityTable, $entityRowsIn); - $newProducts = $this->_connection->fetchPairs( + $newProducts = $this->_connection->fetchAll( $this->_connection->select()->from( $entityTable, - ['sku', 'entity_id'] + array_merge(['sku', 'entity_id'], $this->getOldSkuFieldsForSelect()) )->where( 'sku IN (?)', array_keys($entityRowsIn) ) ); - foreach ($newProducts as $sku => $newId) { + foreach ($newProducts as $product) { // fill up entity_id for new products - $this->skuProcessor->setNewSkuData($sku, 'entity_id', $newId); + $this->skuProcessor->setNewSkuData($product['sku'], 'entity_id', $product['entity_id']); } + + $this->updateOldSku($newProducts); } return $this; } + /** + * Return additional data, needed to select. + * @return array + */ + private function getOldSkuFieldsForSelect() + { + return ['type_id', 'attribute_set_id']; + } + + /** + * Adds newly created products to _oldSku + * @param array $newProducts + * @return void + */ + private function updateOldSku(array $newProducts) + { + $oldSkus = []; + foreach ($newProducts as $info) { + $typeId = $info['type_id']; + $sku = $info['sku']; + $oldSkus[$sku] = [ + 'type_id' => $typeId, + 'attr_set_id' => $info['attribute_set_id'], + 'supported_type' => isset($this->_productTypeModels[$typeId]), + 'entity_id' => $info['entity_id'] + ]; + } + + $this->_oldSku = array_replace($this->_oldSku, $oldSkus); + } + + /** * Retrieving images from all columns and rows * diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php index 84023f86cbcd2..3fd3419b5554e 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php @@ -14,13 +14,14 @@ */ namespace Magento\CatalogImportExport\Model\Import; +use Magento\Catalog\Api\Data\ProductInterface; use Magento\Framework\App\Bootstrap; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\ImportExport\Model\Import; /** * Class ProductTest - * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * @magentoDataFixtureBeforeTransaction Magento/Catalog/_files/enable_reindex_schedule.php */ class ProductTest extends \PHPUnit_Framework_TestCase @@ -946,4 +947,62 @@ public function testValidateUrlKeysMultipleStores() $this->assertTrue($errors->getErrorsCount() == 0); } + + /** + * @magentoDataFixture Magento/Store/_files/website.php + * @magentoDataFixture Magento/Store/_files/core_fixturestore.php + * @magentoDbIsolation enabled + * @magentoAppIsolation enabled + */ + public function testProductWithMultipleStoresInDifferentBunches() + { + $products = [ + 'simple1', + 'simple2', + 'simple3' + ]; + + $importExportData = $this->getMockBuilder(\Magento\ImportExport\Helper\Data::class) + ->disableOriginalConstructor() + ->getMock(); + $importExportData->expects($this->atLeastOnce()) + ->method('getBunchSize') + ->willReturn(1); + $this->_model = $this->objectManager->create( + \Magento\CatalogImportExport\Model\Import\Product::class, + ['importExportData' => $importExportData] + ); + + $filesystem = $this->objectManager->create(\Magento\Framework\Filesystem::class); + $directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT); + $source = $this->objectManager->create( + \Magento\ImportExport\Model\Import\Source\Csv::class, + [ + 'file' => __DIR__ . '/_files/products_to_import_with_multiple_store.csv', + 'directory' => $directory + ] + ); + $errors = $this->_model->setParameters( + ['behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_APPEND, 'entity' => 'catalog_product'] + )->setSource( + $source + )->validateData(); + + $this->assertTrue($errors->getErrorsCount() == 0); + + $this->_model->importData(); + $productCollection = $this->objectManager + ->create(\Magento\Catalog\Model\ResourceModel\Product\Collection::class); + $this->assertCount(3, $productCollection->getItems()); + $actualProductSkus = array_map( + function(ProductInterface $item) { + return $item->getSku(); + }, + $productCollection->getItems() + ); + $this->assertEquals( + $products, + array_values($actualProductSkus) + ); + } } diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_multiple_store.csv b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_multiple_store.csv new file mode 100644 index 0000000000000..a4ad5adb7b0f4 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_multiple_store.csv @@ -0,0 +1,6 @@ +sku,product_type,store_view_code,name,price,attribute_set_code,categories +simple1,simple,fixturestore,"simple 1",25,Default,"Default Category/Category 1" +simple1,simple,,"simple 1",25,Default,"Default Category/Category 1" +simple2,simple,fixturestore,"simple 2",34,Default,"Default Category/Category 1" +simple2,simple,,"simple 2",34,Default,"Default Category/Category 1" +simple3,simple,,"simple 3",58,Default,"Default Category/Category 1" From ff52db44785cd52fcaa37c918c3cad1539a1075e Mon Sep 17 00:00:00 2001 From: Sergey Semenov Date: Thu, 8 Sep 2016 15:18:07 +0300 Subject: [PATCH 3/8] MAGETWO-57000: [Backport] Simple child product without a special price still shown as "was (original price)" #4442 #5097 - for 2.0 --- .../Pricing/Render/FinalPriceBox.php | 60 ++++++++ .../Unit/Pricing/Render/FinalPriceBoxTest.php | 137 ++++++++++++++++++ .../base/layout/catalog_product_prices.xml | 21 +++ .../templates/product/price/final_price.phtml | 60 ++++++++ .../view/frontend/web/js/configurable.js | 23 ++- 5 files changed, 299 insertions(+), 2 deletions(-) create mode 100644 app/code/Magento/ConfigurableProduct/Pricing/Render/FinalPriceBox.php create mode 100644 app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Render/FinalPriceBoxTest.php create mode 100644 app/code/Magento/ConfigurableProduct/view/base/layout/catalog_product_prices.xml create mode 100644 app/code/Magento/ConfigurableProduct/view/base/templates/product/price/final_price.phtml diff --git a/app/code/Magento/ConfigurableProduct/Pricing/Render/FinalPriceBox.php b/app/code/Magento/ConfigurableProduct/Pricing/Render/FinalPriceBox.php new file mode 100644 index 0000000000000..16a296a355454 --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Pricing/Render/FinalPriceBox.php @@ -0,0 +1,60 @@ +configurableOptionsProvider = $configurableOptionsProvider; + parent::__construct($context, $saleableItem, $price, $rendererPool, $data); + } + + /** + * Define if the special price should be shown + * + * @return bool + */ + public function hasSpecialPrice() + { + $product = $this->getSaleableItem(); + foreach ($this->configurableOptionsProvider->getProducts($product) as $subProduct) { + $regularPrice = $subProduct->getPriceInfo()->getPrice(RegularPrice::PRICE_CODE)->getValue(); + $finalPrice = $subProduct->getPriceInfo()->getPrice(FinalPrice::PRICE_CODE)->getValue(); + if ($finalPrice < $regularPrice) { + return true; + } + } + return false; + } +} diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Render/FinalPriceBoxTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Render/FinalPriceBoxTest.php new file mode 100644 index 0000000000000..4dbcfed531525 --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Render/FinalPriceBoxTest.php @@ -0,0 +1,137 @@ +context = $this->getMockBuilder(\Magento\Framework\View\Element\Template\Context::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->saleableItem = $this->getMockBuilder(\Magento\Catalog\Model\Product::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->price = $this->getMockBuilder(\Magento\Framework\Pricing\Price\PriceInterface::class) + ->getMockForAbstractClass(); + + $this->rendererPool = $this->getMockBuilder(\Magento\Framework\Pricing\Render\RendererPool::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->configurableOptionsProvider = $this->getMockBuilder(ConfigurableOptionsProviderInterface::class) + ->getMockForAbstractClass(); + + $this->model = new FinalPriceBox( + $this->context, + $this->saleableItem, + $this->price, + $this->rendererPool, + $this->configurableOptionsProvider + ); + } + + /** + * @param float $regularPrice + * @param float $finalPrice + * @param bool $expected + * @dataProvider hasSpecialPriceDataProvider + */ + public function testHasSpecialPrice( + $regularPrice, + $finalPrice, + $expected + ) { + $priceMockOne = $this->getMockBuilder(\Magento\Framework\Pricing\Price\PriceInterface::class) + ->getMockForAbstractClass(); + + $priceMockOne->expects($this->once()) + ->method('getValue') + ->willReturn($regularPrice); + + $priceMockTwo = $this->getMockBuilder(\Magento\Framework\Pricing\Price\PriceInterface::class) + ->getMockForAbstractClass(); + + $priceMockTwo->expects($this->once()) + ->method('getValue') + ->willReturn($finalPrice); + + $priceInfoMock = $this->getMockBuilder(\Magento\Framework\Pricing\PriceInfo\Base::class) + ->disableOriginalConstructor() + ->getMock(); + + $priceInfoMock->expects($this->exactly(2)) + ->method('getPrice') + ->willReturnMap([ + [RegularPrice::PRICE_CODE, $priceMockOne], + [FinalPrice::PRICE_CODE, $priceMockTwo], + ]); + + $productMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductInterface::class) + ->setMethods(['getPriceInfo']) + ->getMockForAbstractClass(); + + $productMock->expects($this->exactly(2)) + ->method('getPriceInfo') + ->willReturn($priceInfoMock); + + $this->configurableOptionsProvider->expects($this->once()) + ->method('getProducts') + ->with($this->saleableItem) + ->willReturn([$productMock]); + + $this->assertEquals($expected, $this->model->hasSpecialPrice()); + } + + /** + * @return array + */ + public function hasSpecialPriceDataProvider() + { + return [ + [10., 20., false], + [10., 10., false], + [20., 10., true], + ]; + } +} diff --git a/app/code/Magento/ConfigurableProduct/view/base/layout/catalog_product_prices.xml b/app/code/Magento/ConfigurableProduct/view/base/layout/catalog_product_prices.xml new file mode 100644 index 0000000000000..47fe31681b5bf --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/view/base/layout/catalog_product_prices.xml @@ -0,0 +1,21 @@ + + + + + + + + + Magento\ConfigurableProduct\Pricing\Render\FinalPriceBox + Magento_ConfigurableProduct::product/price/final_price.phtml + + + + + + diff --git a/app/code/Magento/ConfigurableProduct/view/base/templates/product/price/final_price.phtml b/app/code/Magento/ConfigurableProduct/view/base/templates/product/price/final_price.phtml new file mode 100644 index 0000000000000..5943b1ea2af5b --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/view/base/templates/product/price/final_price.phtml @@ -0,0 +1,60 @@ + + +getPriceType('regular_price'); + +/** @var \Magento\Framework\Pricing\Price\PriceInterface $finalPriceModel */ +$finalPriceModel = $block->getPriceType('final_price'); +$idSuffix = $block->getIdSuffix() ? $block->getIdSuffix() : ''; +$schema = ($block->getZone() == 'item_view') ? true : false; +?> +hasSpecialPrice()): ?> + + renderAmount($finalPriceModel->getAmount(), [ + 'display_label' => __('Special Price'), + 'price_id' => $block->getPriceId('product-price-' . $idSuffix), + 'price_type' => 'finalPrice', + 'include_container' => true, + 'schema' => $schema + ]); ?> + + + renderAmount($priceModel->getAmount(), [ + 'display_label' => __('Regular Price'), + 'price_id' => $block->getPriceId('old-price-' . $idSuffix), + 'price_type' => 'oldPrice', + 'include_container' => true, + 'skip_adjustments' => true + ]); ?> + + + renderAmount($finalPriceModel->getAmount(), [ + 'price_id' => $block->getPriceId('product-price-' . $idSuffix), + 'price_type' => 'finalPrice', + 'include_container' => true, + 'schema' => $schema + ]); ?> + + +showMinimalPrice()): ?> + getUseLinkForAsLowAs()):?> + + renderAmountMinimal(); ?> + + + + renderAmountMinimal(); ?> + + + diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js index 52ce31415d255..aa98309b2f244 100644 --- a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js +++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js @@ -27,7 +27,8 @@ define([ ' <%- data.finalPrice.formatted %>' + '<% } %>', mediaGallerySelector: '[data-gallery-role=gallery-placeholder]', - mediaGalleryInitial: null + mediaGalleryInitial: null, + slyOldPriceSelector: '.sly-old-price' }, /** @@ -245,6 +246,7 @@ define([ this._resetChildren(element); } this._reloadPrice(); + this._displayRegularPriceBlock(this.simpleProduct); this._changeProductImage(); }, @@ -410,7 +412,7 @@ define([ }, /** - * Returns pracies for configured products + * Returns prices for configured products * * @param {*} config - Products configuration * @returns {*} @@ -453,6 +455,23 @@ define([ undefined : _.first(config.allowedProducts); + }, + + /** + * Show or hide regular price block + * + * @param {*} optionId + * @private + */ + _displayRegularPriceBlock: function (optionId) { + if (typeof optionId != 'undefined' + && this.options.spConfig.optionPrices[optionId].oldPrice.amount + != this.options.spConfig.optionPrices[optionId].finalPrice.amount + ) { + $(this.options.slyOldPriceSelector).show(); + } else { + $(this.options.slyOldPriceSelector).hide(); + } } }); From 36e84bdecb56ec6b380d91da33375f84ad191504 Mon Sep 17 00:00:00 2001 From: Sergey Semenov Date: Thu, 8 Sep 2016 15:23:06 +0300 Subject: [PATCH 4/8] MAGETWO-58058: [Backport] - [GitHub] Unable to add more than 1 product to a cart from Wishlist #5282 - for 2.0 --- app/code/Magento/Wishlist/Helper/Data.php | 8 ++++- .../Wishlist/Test/Unit/Helper/DataTest.php | 32 +++++++++++++++++-- .../Wishlist/view/frontend/web/wishlist.js | 22 +++++++++++++ 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/app/code/Magento/Wishlist/Helper/Data.php b/app/code/Magento/Wishlist/Helper/Data.php index d64d1a185f0a2..736786e6e30b3 100644 --- a/app/code/Magento/Wishlist/Helper/Data.php +++ b/app/code/Magento/Wishlist/Helper/Data.php @@ -446,7 +446,13 @@ public function getSharedAddAllToCartUrl() */ protected function _getCartUrlParameters($item) { - return ['item' => is_string($item) ? $item : $item->getWishlistItemId()]; + $params = [ + 'item' => is_string($item) ? $item : $item->getWishlistItemId(), + ]; + if ($item instanceof \Magento\Wishlist\Model\Item) { + $params['qty'] = $item->getQty(); + } + return $params; } /** diff --git a/app/code/Magento/Wishlist/Test/Unit/Helper/DataTest.php b/app/code/Magento/Wishlist/Test/Unit/Helper/DataTest.php index 079aa695b8abb..f2bb346cca407 100644 --- a/app/code/Magento/Wishlist/Test/Unit/Helper/DataTest.php +++ b/app/code/Magento/Wishlist/Test/Unit/Helper/DataTest.php @@ -124,6 +124,7 @@ public function setUp() ->setMethods([ 'getProduct', 'getWishlistItemId', + 'getQty', ]) ->getMock(); @@ -217,6 +218,7 @@ public function testGetAddToCartParams() $url = 'result url'; $storeId = 1; $wishlistItemId = 1; + $wishlistItemQty = 1; $this->wishlistItem->expects($this->once()) ->method('getProduct') @@ -224,6 +226,9 @@ public function testGetAddToCartParams() $this->wishlistItem->expects($this->once()) ->method('getWishlistItemId') ->willReturn($wishlistItemId); + $this->wishlistItem->expects($this->once()) + ->method('getQty') + ->willReturn($wishlistItemQty); $this->product->expects($this->once()) ->method('isVisibleInSiteVisibility') @@ -243,9 +248,13 @@ public function testGetAddToCartParams() ->with('wishlist/index/cart') ->willReturn($url); + $expected = [ + 'item' => $wishlistItemId, + 'qty' => $wishlistItemQty, + ]; $this->postDataHelper->expects($this->once()) ->method('getPostData') - ->with($url, ['item' => $wishlistItemId]) + ->with($url, $expected) ->willReturn($url); $this->assertEquals($url, $this->model->getAddToCartParams($this->wishlistItem)); @@ -256,6 +265,7 @@ public function testGetAddToCartParamsWithReferer() $url = 'result url'; $storeId = 1; $wishlistItemId = 1; + $wishlistItemQty = 1; $referer = 'referer'; $refererEncoded = 'referer_encoded'; @@ -265,6 +275,9 @@ public function testGetAddToCartParamsWithReferer() $this->wishlistItem->expects($this->once()) ->method('getWishlistItemId') ->willReturn($wishlistItemId); + $this->wishlistItem->expects($this->once()) + ->method('getQty') + ->willReturn($wishlistItemQty); $this->product->expects($this->once()) ->method('isVisibleInSiteVisibility') @@ -288,9 +301,14 @@ public function testGetAddToCartParamsWithReferer() ->with('wishlist/index/cart') ->willReturn($url); + $expected = [ + 'item' => $wishlistItemId, + ActionInterface::PARAM_NAME_URL_ENCODED => $refererEncoded, + 'qty' => $wishlistItemQty, + ]; $this->postDataHelper->expects($this->once()) ->method('getPostData') - ->with($url, ['item' => $wishlistItemId, ActionInterface::PARAM_NAME_URL_ENCODED => $refererEncoded]) + ->with($url, $expected) ->willReturn($url); $this->assertEquals($url, $this->model->getAddToCartParams($this->wishlistItem, true)); @@ -363,6 +381,7 @@ public function testGetSharedAddToCartUrl() $url = 'result url'; $storeId = 1; $wishlistItemId = 1; + $wishlistItemQty = 1; $this->wishlistItem->expects($this->once()) ->method('getProduct') @@ -370,6 +389,9 @@ public function testGetSharedAddToCartUrl() $this->wishlistItem->expects($this->once()) ->method('getWishlistItemId') ->willReturn($wishlistItemId); + $this->wishlistItem->expects($this->once()) + ->method('getQty') + ->willReturn($wishlistItemQty); $this->product->expects($this->once()) ->method('isVisibleInSiteVisibility') @@ -383,9 +405,13 @@ public function testGetSharedAddToCartUrl() ->with('wishlist/shared/cart') ->willReturn($url); + $exptected = [ + 'item' => $wishlistItemId, + 'qty' => $wishlistItemQty, + ]; $this->postDataHelper->expects($this->once()) ->method('getPostData') - ->with($url, ['item' => $wishlistItemId]) + ->with($url, $exptected) ->willReturn($url); $this->assertEquals($url, $this->model->getSharedAddToCartUrl($this->wishlistItem)); diff --git a/app/code/Magento/Wishlist/view/frontend/web/wishlist.js b/app/code/Magento/Wishlist/view/frontend/web/wishlist.js index a4fdc178c704f..0d6e510e5f5e9 100644 --- a/app/code/Magento/Wishlist/view/frontend/web/wishlist.js +++ b/app/code/Magento/Wishlist/view/frontend/web/wishlist.js @@ -47,6 +47,7 @@ define([ event.preventDefault(); $.mage.dataPost().postData($(event.currentTarget).data('post-remove')); }, this)) + .on('click', this.options.addToCartSelector, $.proxy(this._beforeAddToCart, this)) .on('click', this.options.addAllToCartSelector, $.proxy(this._addAllWItemsToCart, this)) .on('focusin focusout', this.options.commentInputType, $.proxy(this._focusComment, this)); } @@ -59,6 +60,27 @@ define([ }); }, + /** + * Process data before add to cart + * + * - update item's qty value. + * + * @param {Event} event + * @private + */ + _beforeAddToCart: function(event) { + var elem = $(event.currentTarget), + itemId = elem.data(this.options.dataAttribute), + qtyName = $.validator.format(this.options.nameFormat, itemId), + qtyValue = elem.parents().find('[name="' + qtyName + '"]').val(), + params = elem.data('post'); + + if (params) { + params.data = $.extend({}, params.data, {'qty': qtyValue}); + elem.data('post', params); + } + }, + /** * Add wish list items to cart. * @private From d40cc3073c1e028461b6f35c36845b558dc35166 Mon Sep 17 00:00:00 2001 From: Sergey Semenov Date: Thu, 8 Sep 2016 17:44:23 +0300 Subject: [PATCH 5/8] MAGETWO-58192: [Backport] - [GITHUB] Prices of related products on PDP changes according to product custom options. #4588 - for 2.0 --- .../Catalog/view/frontend/templates/product/view/form.phtml | 6 ++++-- .../view/frontend/templates/product/view/options.phtml | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml index f6dd2a0033fd4..41f0684a43126 100644 --- a/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml +++ b/app/code/Magento/Catalog/view/frontend/templates/product/view/form.phtml @@ -40,9 +40,11 @@