Skip to content

Commit e0ccf4c

Browse files
committed
MAGETWO-61159: Configurable Product visible on the Category when options are Out of Stock and Disabled
1 parent 0a03f01 commit e0ccf4c

File tree

6 files changed

+72
-31
lines changed

6 files changed

+72
-31
lines changed

app/code/Magento/ConfigurableProduct/Model/ResourceModel/Indexer/Stock/Configurable.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,25 @@ protected function _getStockStatusSelect($entityIds = null, $usePrimaryTable = f
2929
$connection = $this->getConnection();
3030
$idxTable = $usePrimaryTable ? $this->getMainTable() : $this->getIdxTable();
3131
$select = parent::_getStockStatusSelect($entityIds, $usePrimaryTable);
32+
$linkField = $metadata->getLinkField();
3233
$select->reset(
3334
\Magento\Framework\DB\Select::COLUMNS
3435
)->columns(
3536
['e.entity_id', 'cis.website_id', 'cis.stock_id']
3637
)->joinLeft(
3738
['l' => $this->getTable('catalog_product_super_link')],
38-
'l.parent_id = e.' . $metadata->getLinkField(),
39+
'l.parent_id = e.' . $linkField,
3940
[]
4041
)->join(
4142
['le' => $this->getTable('catalog_product_entity')],
4243
'le.entity_id = l.product_id',
4344
[]
45+
)->joinInner(
46+
['cpei' => $this->getTable('catalog_product_entity_int')],
47+
'le.' . $linkField . ' = cpei.' . $linkField
48+
. ' AND cpei.attribute_id = ' . $this->_getAttribute('status')->getId()
49+
. ' AND cpei.value = ' . ProductStatus::STATUS_ENABLED,
50+
[]
4451
)->joinLeft(
4552
['i' => $idxTable],
4653
'i.product_id = l.product_id AND cis.website_id = i.website_id AND cis.stock_id = i.stock_id',

dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,10 @@ public function testBoolFilterWithNestedRangeInNegativeBoolFilter()
331331
*
332332
* @magentoConfigFixture current_store catalog/search/engine mysql
333333
* @dataProvider advancedSearchDataProvider
334+
* @param string $nameQuery
335+
* @param string $descriptionQuery
336+
* @param array $rangeFilter
337+
* @param int $expectedRecordsCount
334338
*/
335339
public function testSimpleAdvancedSearch(
336340
$nameQuery,
@@ -445,6 +449,37 @@ public function testAdvancedSearchCompositeProductWithOutOfStockOption()
445449
$this->assertEquals(1, $queryResponse->count());
446450
}
447451

452+
/**
453+
* @magentoDataFixture Magento/Framework/Search/_files/product_configurable_with_disabled_child.php
454+
* @magentoConfigFixture current_store catalog/search/engine mysql
455+
*/
456+
public function testAdvancedSearchCompositeProductWithDisabledChild()
457+
{
458+
/** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute */
459+
$attribute = $this->objectManager->get(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class)
460+
->loadByCode(\Magento\Catalog\Model\Product::ENTITY, 'test_configurable');
461+
/** @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\Collection $selectOptions */
462+
$selectOptions = $this->objectManager
463+
->create(\Magento\Eav\Model\ResourceModel\Entity\Attribute\Option\Collection::class)
464+
->setAttributeFilter($attribute->getId());
465+
466+
$firstOption = $selectOptions->getFirstItem();
467+
$firstOptionId = $firstOption->getId();
468+
$this->requestBuilder->bind('test_configurable', $firstOptionId);
469+
$this->requestBuilder->setRequestName('filter_out_of_stock_child');
470+
471+
$queryResponse = $this->executeQuery();
472+
$this->assertEquals(0, $queryResponse->count());
473+
474+
$secondOption = $selectOptions->getLastItem();
475+
$secondOptionId = $secondOption->getId();
476+
$this->requestBuilder->bind('test_configurable', $secondOptionId);
477+
$this->requestBuilder->setRequestName('filter_out_of_stock_child');
478+
479+
$queryResponse = $this->executeQuery();
480+
$this->assertEquals(0, $queryResponse->count());
481+
}
482+
448483
public function dateDataProvider()
449484
{
450485
return [

dev/tests/integration/testsuite/Magento/Framework/Search/_files/product_configurable.php

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
use Magento\Eav\Api\Data\AttributeOptionInterface;
1616
use Magento\TestFramework\Helper\Bootstrap;
1717

18-
\Magento\TestFramework\Helper\Bootstrap::getInstance()->reinitialize();
18+
Bootstrap::getInstance()->reinitialize();
1919

2020
require __DIR__ . '/configurable_attribute.php';
2121

@@ -33,7 +33,7 @@
3333
$attributeValues = [];
3434
$attributeSetId = $installer->getAttributeSetId('catalog_product', 'Default');
3535
$associatedProductIds = [];
36-
$productIds = [10, 20];
36+
$productIds = [1010, 1020];
3737
array_shift($options); //remove the first option which is empty
3838

3939
$isFirstOption = true;
@@ -108,29 +108,8 @@
108108

109109
$product->setExtensionAttributes($extensionConfigurableAttributes);
110110

111-
// Remove any previously created product with the same id.
112-
/** @var \Magento\Framework\Registry $registry */
113-
$registry = Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class);
114-
$registry->unregister('isSecureArea');
115-
$registry->register('isSecureArea', true);
116-
try {
117-
$productToDelete = $productRepository->getById(1);
118-
$productRepository->delete($productToDelete);
119-
120-
/** @var \Magento\Quote\Model\ResourceModel\Quote\Item $itemResource */
121-
$itemResource = Bootstrap::getObjectManager()->get(\Magento\Quote\Model\ResourceModel\Quote\Item::class);
122-
$itemResource->getConnection()->delete(
123-
$itemResource->getMainTable(),
124-
'product_id = ' . $productToDelete->getId()
125-
);
126-
} catch (\Exception $e) {
127-
// Nothing to remove
128-
}
129-
$registry->unregister('isSecureArea');
130-
$registry->register('isSecureArea', false);
131-
132111
$product->setTypeId(Configurable::TYPE_CODE)
133-
->setId(1)
112+
->setId(1001)
134113
->setAttributeSetId($attributeSetId)
135114
->setWebsiteIds([1])
136115
->setName('Configurable Product')
@@ -140,8 +119,3 @@
140119
->setStockData(['use_config_manage_stock' => 1, 'is_in_stock' => 1]);
141120

142121
$productRepository->save($product);
143-
//
144-
///** @var \Magento\Catalog\Model\Indexer\Product\Eav\Processor $eavIndexer */
145-
//$eavIndexer = Bootstrap::getObjectManager()
146-
// ->get(\Magento\Catalog\Model\Indexer\Product\Eav\Processor::class);
147-
//$eavIndexer->reindexAll();

dev/tests/integration/testsuite/Magento/Framework/Search/_files/product_configurable_rollback.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
$productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
1717
->get(\Magento\Catalog\Api\ProductRepositoryInterface::class);
1818

19-
foreach (['simple_10', 'simple_20', 'configurable'] as $sku) {
19+
foreach (['simple_1010', 'simple_1020', 'configurable'] as $sku) {
2020
try {
2121
$product = $productRepository->get($sku, false, null, true);
2222

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
use Magento\Catalog\Api\ProductRepositoryInterface;
8+
use Magento\TestFramework\Helper\Bootstrap;
9+
10+
require __DIR__ . '/product_configurable.php';
11+
12+
/** @var ProductRepositoryInterface $productRepository */
13+
$productRepository = Bootstrap::getObjectManager()
14+
->create(ProductRepositoryInterface::class);
15+
16+
$product = $productRepository->get('simple_1020');
17+
$product->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_DISABLED);
18+
$productRepository->save($product);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
/**
3+
* Copyright © 2016 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
require __DIR__ . '/product_configurable_rollback.php';

0 commit comments

Comments
 (0)