diff --git a/app/code/Magento/CatalogInventory/Block/Plugin/ProductView.php b/app/code/Magento/CatalogInventory/Block/Plugin/ProductView.php index c8245a53c147c..7f809e07b4018 100644 --- a/app/code/Magento/CatalogInventory/Block/Plugin/ProductView.php +++ b/app/code/Magento/CatalogInventory/Block/Plugin/ProductView.php @@ -1,26 +1,29 @@ stockRegistry = $stockRegistry; + $this->productQuantityValidator = $productQuantityValidator ?: ObjectManager::getInstance()->get( + QuantityValidator::class + ); } /** @@ -34,20 +37,12 @@ public function afterGetQuantityValidators( \Magento\Catalog\Block\Product\View $block, array $validators ) { - $stockItem = $this->stockRegistry->getStockItem( - $block->getProduct()->getId(), - $block->getProduct()->getStore()->getWebsiteId() + return array_merge( + $validators, + $this->productQuantityValidator->getData( + $block->getProduct()->getId(), + $block->getProduct()->getStore()->getWebsiteId() + ) ); - - $params = []; - if ($stockItem->getMaxSaleQty()) { - $params['maxAllowed'] = (float)$stockItem->getMaxSaleQty(); - } - if ($stockItem->getQtyIncrements() > 0) { - $params['qtyIncrements'] = (float)$stockItem->getQtyIncrements(); - } - $validators['validate-item-quantity'] = $params; - - return $validators; } } diff --git a/app/code/Magento/CatalogInventory/Model/Product/QuantityValidator.php b/app/code/Magento/CatalogInventory/Model/Product/QuantityValidator.php new file mode 100644 index 0000000000000..1ad6d938d73d6 --- /dev/null +++ b/app/code/Magento/CatalogInventory/Model/Product/QuantityValidator.php @@ -0,0 +1,47 @@ +stockRegistry->getStockItem($productId, $websiteId); + + $params = []; + $validators = []; + $params['minAllowed'] = $stockItem->getMinSaleQty(); + if ($stockItem->getMaxSaleQty()) { + $params['maxAllowed'] = $stockItem->getMaxSaleQty(); + } + if ($stockItem->getQtyIncrements() > 0) { + $params['qtyIncrements'] = (float) $stockItem->getQtyIncrements(); + } + $validators['validate-item-quantity'] = $params; + + return $validators; + } +} diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Block/Plugin/ProductViewTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Block/Plugin/ProductViewTest.php index ad01936633a50..94d08027362e5 100644 --- a/app/code/Magento/CatalogInventory/Test/Unit/Block/Plugin/ProductViewTest.php +++ b/app/code/Magento/CatalogInventory/Test/Unit/Block/Plugin/ProductViewTest.php @@ -1,7 +1,7 @@ stockRegistry = $this->getMockBuilder(StockRegistryInterface::class) ->getMock(); + $this->productQuantityValidator = $objectManager->getObject( + QuantityValidator::class, + [ + 'stockRegistry' => $this->stockRegistry + ] + ); + $this->block = $objectManager->getObject( ProductView::class, [ - 'stockRegistry' => $this->stockRegistry + 'productQuantityValidator' => $this->productQuantityValidator ] ); } @@ -59,6 +72,7 @@ public function testAfterGetQuantityValidators() { $result = [ 'validate-item-quantity' => [ + 'minAllowed' => 1.0, 'maxAllowed' => 5.0, 'qtyIncrements' => 3.0 ] @@ -86,9 +100,9 @@ public function testAfterGetQuantityValidators() ->method('getStockItem') ->with('productId', 'websiteId') ->willReturn($this->stockItem); + $this->stockItem->expects($this->any())->method('getMinSaleQty')->willReturn(1); $this->stockItem->expects($this->any())->method('getMaxSaleQty')->willReturn(5); $this->stockItem->expects($this->any())->method('getQtyIncrements')->willReturn(3); - $this->assertEquals($result, $this->block->afterGetQuantityValidators($productViewBlock, $validators)); } } diff --git a/app/code/Magento/GroupedProduct/ViewModel/ValidateQuantity.php b/app/code/Magento/GroupedProduct/ViewModel/ValidateQuantity.php new file mode 100644 index 0000000000000..b8bf9bd6faad8 --- /dev/null +++ b/app/code/Magento/GroupedProduct/ViewModel/ValidateQuantity.php @@ -0,0 +1,46 @@ +serializer->serialize( + array_merge( + ['validate-grouped-qty' => '#super-product-table'], + $this->productQuantityValidator->getData($productId, $websiteId) + ) + ); + } +} diff --git a/app/code/Magento/GroupedProduct/view/frontend/layout/catalog_product_view_type_grouped.xml b/app/code/Magento/GroupedProduct/view/frontend/layout/catalog_product_view_type_grouped.xml index a774f384d947a..4a1f813484b3c 100644 --- a/app/code/Magento/GroupedProduct/view/frontend/layout/catalog_product_view_type_grouped.xml +++ b/app/code/Magento/GroupedProduct/view/frontend/layout/catalog_product_view_type_grouped.xml @@ -1,15 +1,19 @@ - + + + Magento\GroupedProduct\ViewModel\ValidateQuantity + + diff --git a/app/code/Magento/GroupedProduct/view/frontend/templates/product/view/type/grouped.phtml b/app/code/Magento/GroupedProduct/view/frontend/templates/product/view/type/grouped.phtml index 996c61571563a..3662149d75211 100644 --- a/app/code/Magento/GroupedProduct/view/frontend/templates/product/view/type/grouped.phtml +++ b/app/code/Magento/GroupedProduct/view/frontend/templates/product/view/type/grouped.phtml @@ -1,31 +1,34 @@ -setPreconfiguredValue(); ?> -getProduct(); ?> -getAssociatedProducts(); ?> - 0; ?> +setPreconfiguredValue(); + $_product = $block->getProduct(); + $_associatedProducts = $block->getAssociatedProducts(); + $_hasAssociatedProducts = count($_associatedProducts) > 0; + $viewModel = $block->getData('validateQuantityViewModel'); +?>
- + - + isSaleable()): ?> - + @@ -34,8 +37,8 @@ - isSaleable()): ?> - @@ -85,7 +92,7 @@ diff --git a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_grouped.xml b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_grouped.xml index 92bb55ebd0ee1..27d63bad57c08 100644 --- a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_grouped.xml +++ b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_grouped.xml @@ -1,15 +1,19 @@ - + + + Magento\GroupedProduct\ViewModel\ValidateQuantity + + diff --git a/lib/web/mage/validation.js b/lib/web/mage/validation.js index 72baf69740c9b..3f1df78dcfdee 100644 --- a/lib/web/mage/validation.js +++ b/lib/web/mage/validation.js @@ -1643,6 +1643,9 @@ define([ isQtyIncrementsValid = typeof params.qtyIncrements === 'undefined' || resolveModulo(qty, $.mage.parseNumber(params.qtyIncrements)) === 0.0; + if ($(element).data('no-validation-for-zero-qty') === true && qty === 0) { + return true; + } result = qty > 0; if (result === false) {
escapeHtml(__('Grouped product items')) ?>escapeHtml(__('Grouped product items')) ?>
escapeHtml(__('Product Name')) ?>escapeHtml(__('Product Name')) ?> escapeHtml(__('Qty')) ?>escapeHtml(__('Qty')) ?>
- escapeHtml($_item->getName()) ?> + + escapeHtml($_item->getName()) ?> getCanShowProductPrice($_product)): ?> getCanShowProductPrice($_item)): ?> getProductPrice($_item) ?> @@ -43,21 +46,25 @@ + isSaleable()): ?>
-
- escapeHtml(__('Out of stock')) ?> +
+ escapeHtml(__('Out of stock')) ?>
- escapeHtml(__('No options of this product are available.')) ?> + escapeHtml(__('No options of this product are available.')) ?>