Skip to content

Commit 2a66907

Browse files
author
Eric Bohanon
committed
MAGETWO-64996: Out of stock configurable product displays with zero price
1 parent 397f87b commit 2a66907

File tree

3 files changed

+93
-8
lines changed

3 files changed

+93
-8
lines changed

app/code/Magento/CatalogInventory/Model/ResourceModel/Product/StockStatusBaseSelectProcessor.php

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ class StockStatusBaseSelectProcessor implements BaseSelectProcessorInterface
2222
*/
2323
private $resource;
2424

25+
/**
26+
* @var \Magento\CatalogInventory\Api\StockConfigurationInterface
27+
*/
28+
private $stockConfig;
29+
2530
/**
2631
* @var \Magento\Indexer\Model\ResourceModel\FrontendResource
2732
*/
@@ -30,14 +35,18 @@ class StockStatusBaseSelectProcessor implements BaseSelectProcessorInterface
3035
/**
3136
* @param ResourceConnection $resource
3237
* @param null|\Magento\Indexer\Model\ResourceModel\FrontendResource $indexerStockFrontendResource
38+
* @param \Magento\CatalogInventory\Api\StockConfigurationInterface|null $stockConfig
3339
*/
3440
public function __construct(
3541
ResourceConnection $resource,
36-
\Magento\Indexer\Model\ResourceModel\FrontendResource $indexerStockFrontendResource = null
42+
\Magento\Indexer\Model\ResourceModel\FrontendResource $indexerStockFrontendResource = null,
43+
\Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfig = null
3744
) {
3845
$this->resource = $resource;
3946
$this->indexerStockFrontendResource = $indexerStockFrontendResource ?: ObjectManager::getInstance()
4047
->get(\Magento\CatalogInventory\Model\ResourceModel\Indexer\Stock\FrontendResource::class);
48+
$this->stockConfig = $stockConfig ?: ObjectManager::getInstance()
49+
->get(\Magento\CatalogInventory\Api\StockConfigurationInterface::class);
4150
}
4251

4352
/**
@@ -50,13 +59,15 @@ public function process(Select $select)
5059
{
5160
$stockStatusTable = $this->indexerStockFrontendResource->getMainTable();
5261

53-
/** @var Select $select */
54-
$select->join(
55-
['stock' => $stockStatusTable],
56-
sprintf('stock.product_id = %s.entity_id', BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS),
57-
[]
58-
)
59-
->where('stock.stock_status = ?', Stock::STOCK_IN_STOCK);
62+
if (!$this->stockConfig->isShowOutOfStock()) {
63+
/** @var Select $select */
64+
$select->join(
65+
['stock' => $stockStatusTable],
66+
sprintf('stock.product_id = %s.entity_id', BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS),
67+
[]
68+
)->where('stock.stock_status = ?', Stock::STOCK_IN_STOCK);
69+
}
70+
6071
return $select;
6172
}
6273
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\ConfigurableProduct\Test\Constraint;
8+
9+
use Magento\Catalog\Test\Constraint\AssertProductPage;
10+
11+
class AssertConfigurableProductOutOfStockPage extends AssertProductPage
12+
{
13+
/**
14+
* Verifies that all relevant product data will be shown for an out of stock configurable product.
15+
*
16+
* @return array
17+
*/
18+
protected function verify()
19+
{
20+
$errors = parent::verify();
21+
22+
return array_filter($errors);
23+
}
24+
25+
/**
26+
* Verify displayed product price on product page (front-end) equals passed from fixture
27+
*
28+
* @return string|null
29+
*/
30+
protected function verifyPrice()
31+
{
32+
$priceBlock = $this->productView->getPriceBlock();
33+
if (!$priceBlock->isVisible()) {
34+
return "Price block for '{$this->product->getName()}' product' is not visible.";
35+
}
36+
$formPrice = $priceBlock->isOldPriceVisible() ? $priceBlock->getOldPrice() : $priceBlock->getPrice();
37+
$fixturePrice = $this->getLowestConfigurablePrice();
38+
39+
if ($fixturePrice != $formPrice) {
40+
return "Displayed product price on product page (front-end) not equals passed from fixture. "
41+
. "Actual: {$formPrice}, expected: {$fixturePrice}.";
42+
}
43+
return null;
44+
}
45+
46+
/**
47+
* Returns lowest possible price of configurable product.
48+
*
49+
* @return string
50+
*/
51+
protected function getLowestConfigurablePrice()
52+
{
53+
$price = null;
54+
$priceDataConfig = $this->product->getDataFieldConfig('price');
55+
if (isset($priceDataConfig['source'])) {
56+
$priceData = $priceDataConfig['source']->getPriceData();
57+
if (isset($priceData['price_from'])) {
58+
$price = $priceData['price_from'];
59+
}
60+
}
61+
62+
if (null === $price) {
63+
$configurableOptions = $this->product->getConfigurableAttributesData();
64+
foreach ($configurableOptions['matrix'] as $option) {
65+
$price = $price === null ? $option['price'] : $price;
66+
if ($price > $option['price']) {
67+
$price = $option['price'];
68+
}
69+
}
70+
}
71+
return $price;
72+
}
73+
}

dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@
186186
<constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertConfigurableAttributesBlockIsAbsentOnProductPage" />
187187
<constraint name="Magento\Catalog\Test\Constraint\AssertProductOutOfStock" />
188188
<constraint name="Magento\Catalog\Test\Constraint\AssertProductVisibleInCategory" />
189+
<constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertConfigurableProductOutOfStockPage" />
189190
</variation>
190191
<variation name="CreateConfigurableProductEntityTestVariation12" summary="Create Configurable Product with disabled child" ticketId="MAGETWO-65661">
191192
<data name="tag" xsi:type="string">test_type:acceptance_test, test_type:extended_acceptance_test, stable:no</data>

0 commit comments

Comments
 (0)