Skip to content

Commit af72789

Browse files
author
Spandana Chittimala
committed
Merge branch 'MC-18810' of https://github.com/magento-mpi/magento2ce into PR-16-08-2019
2 parents e6132df + dd761d0 commit af72789

File tree

8 files changed

+99
-56
lines changed

8 files changed

+99
-56
lines changed

app/code/Magento/Bundle/Model/ResourceModel/Option/Collection.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
*/
66
namespace Magento\Bundle\Model\ResourceModel\Option;
77

8+
use Magento\Catalog\Model\Product\Attribute\Source\Status;
9+
810
/**
911
* Bundle Options Resource Collection
1012
* @api
@@ -138,12 +140,10 @@ public function setPositionOrder()
138140

139141
/**
140142
* Append selection to options
141-
* stripBefore - indicates to reload
142-
* appendAll - indicates do we need to filter by saleable and required custom options
143143
*
144144
* @param \Magento\Bundle\Model\ResourceModel\Selection\Collection $selectionsCollection
145-
* @param bool $stripBefore
146-
* @param bool $appendAll
145+
* @param bool $stripBefore indicates to reload
146+
* @param bool $appendAll indicates do we need to filter by saleable and required custom options
147147
* @return \Magento\Framework\DataObject[]
148148
*/
149149
public function appendSelections($selectionsCollection, $stripBefore = false, $appendAll = true)
@@ -156,7 +156,9 @@ public function appendSelections($selectionsCollection, $stripBefore = false, $a
156156
foreach ($selectionsCollection->getItems() as $key => $selection) {
157157
$option = $this->getItemById($selection->getOptionId());
158158
if ($option) {
159-
if ($appendAll || $selection->isSalable() && !$selection->getRequiredOptions()) {
159+
if ($appendAll ||
160+
((int) $selection->getStatus()) === Status::STATUS_ENABLED && !$selection->getRequiredOptions()
161+
) {
160162
$selection->setOption($option);
161163
$option->addSelection($selection);
162164
} else {

app/code/Magento/ConfigurableProduct/Block/Product/View/Type/Configurable.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88
namespace Magento\ConfigurableProduct\Block\Product\View\Type;
99

10+
use Magento\Catalog\Model\Product\Attribute\Source\Status;
1011
use Magento\ConfigurableProduct\Model\ConfigurableAttributeData;
1112
use Magento\Customer\Helper\Session\CurrentCustomer;
1213
use Magento\Customer\Model\Session;
@@ -183,8 +184,9 @@ public function getAllowProducts()
183184
$products = [];
184185
$skipSaleableCheck = $this->catalogProduct->getSkipSaleableCheck();
185186
$allProducts = $this->getProduct()->getTypeInstance()->getUsedProducts($this->getProduct(), null);
187+
/** @var $product \Magento\Catalog\Model\Product */
186188
foreach ($allProducts as $product) {
187-
if ($product->isSaleable() || $skipSaleableCheck) {
189+
if ($skipSaleableCheck || ((int) $product->getStatus()) === Status::STATUS_ENABLED) {
188190
$products[] = $product;
189191
}
190192
}

app/code/Magento/ConfigurableProduct/Helper/Data.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
/**
1616
* Class Data
17+
*
1718
* Helper class for getting options
1819
* @api
1920
* @since 100.0.2
@@ -87,8 +88,9 @@ public function getOptions($currentProduct, $allowedProducts)
8788
$productAttribute = $attribute->getProductAttribute();
8889
$productAttributeId = $productAttribute->getId();
8990
$attributeValue = $product->getData($productAttribute->getAttributeCode());
90-
91-
$options[$productAttributeId][$attributeValue][] = $productId;
91+
if ($product->isSalable()) {
92+
$options[$productAttributeId][$attributeValue][] = $productId;
93+
}
9294
$options['index'][$productId][$productAttributeId] = $attributeValue;
9395
}
9496
}

app/code/Magento/ConfigurableProduct/Plugin/Model/ResourceModel/Attribute/InStockOptionSelectBuilder.php

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
namespace Magento\ConfigurableProduct\Plugin\Model\ResourceModel\Attribute;
77

8+
use Magento\CatalogInventory\Api\StockConfigurationInterface;
89
use Magento\CatalogInventory\Model\ResourceModel\Stock\Status;
910
use Magento\ConfigurableProduct\Model\ResourceModel\Attribute\OptionSelectBuilderInterface;
1011
use Magento\Framework\DB\Select;
@@ -20,13 +21,21 @@ class InStockOptionSelectBuilder
2021
* @var Status
2122
*/
2223
private $stockStatusResource;
23-
24+
/**
25+
* @var StockConfigurationInterface
26+
*/
27+
private $stockConfig;
28+
2429
/**
2530
* @param Status $stockStatusResource
31+
* @param StockConfigurationInterface $stockConfig
2632
*/
27-
public function __construct(Status $stockStatusResource)
28-
{
33+
public function __construct(
34+
Status $stockStatusResource,
35+
StockConfigurationInterface $stockConfig
36+
) {
2937
$this->stockStatusResource = $stockStatusResource;
38+
$this->stockConfig = $stockConfig;
3039
}
3140

3241
/**
@@ -40,14 +49,16 @@ public function __construct(Status $stockStatusResource)
4049
*/
4150
public function afterGetSelect(OptionSelectBuilderInterface $subject, Select $select)
4251
{
43-
$select->joinInner(
44-
['stock' => $this->stockStatusResource->getMainTable()],
45-
'stock.product_id = entity.entity_id',
46-
[]
47-
)->where(
48-
'stock.stock_status = ?',
49-
\Magento\CatalogInventory\Model\Stock\Status::STATUS_IN_STOCK
50-
);
52+
if (!$this->stockConfig->isShowOutOfStock()) {
53+
$select->joinInner(
54+
['stock' => $this->stockStatusResource->getMainTable()],
55+
'stock.product_id = entity.entity_id',
56+
[]
57+
)->where(
58+
'stock.stock_status = ?',
59+
\Magento\CatalogInventory\Model\Stock\Status::STATUS_IN_STOCK
60+
);
61+
}
5162

5263
return $select;
5364
}

app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCreateConfigurableProductWithThreeProductDisplayOutOfStockProductsTest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,6 @@
135135
<!-- Assert out of stock option is absent on product page -->
136136
<amOnPage url="{{ApiConfigurableProduct.urlKey}}.html" stepKey="amOnProductPage"/>
137137
<waitForPageLoad stepKey="waitForProductPageLoad"/>
138-
<dontSee userInput="$$createConfigProductAttributeOptionThree.option[store_labels][1][label]$$" selector="{{StorefrontProductInfoMainSection.optionByAttributeId($$createConfigProductAttribute.attribute_id$$)}}" stepKey="assertOptionNotAvailable" />
138+
<see userInput="$$createConfigProductAttributeOptionThree.option[store_labels][1][label]$$" selector="{{StorefrontProductInfoMainSection.optionByAttributeId($$createConfigProductAttribute.attribute_id$$)}}" stepKey="assertOptionNotAvailable" />
139139
</test>
140140
</tests>

app/code/Magento/ConfigurableProduct/Test/Unit/Helper/DataTest.php

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,13 @@ public function testGetOptions(array $expected, array $data)
8787

8888
$this->_imageHelperMock->expects($this->any())
8989
->method('init')
90-
->willReturnMap([
91-
[$data['current_product_mock'], 'product_page_image_large', [], $imageHelper1],
92-
[$data['allowed_products'][0], 'product_page_image_large', [], $imageHelper1],
93-
[$data['allowed_products'][1], 'product_page_image_large', [], $imageHelper2],
94-
]);
90+
->willReturnMap(
91+
[
92+
[$data['current_product_mock'], 'product_page_image_large', [], $imageHelper1],
93+
[$data['allowed_products'][0], 'product_page_image_large', [], $imageHelper1],
94+
[$data['allowed_products'][1], 'product_page_image_large', [], $imageHelper2],
95+
]
96+
);
9597
}
9698

9799
$this->assertEquals(
@@ -148,14 +150,18 @@ public function getOptionsDataProvider()
148150
for ($i = 1; $i <= 2; $i++) {
149151
$productMock = $this->createPartialMock(
150152
\Magento\Catalog\Model\Product::class,
151-
['getData', 'getImage', 'getId', '__wakeup', 'getMediaGalleryImages']
153+
['getData', 'getImage', 'getId', '__wakeup', 'getMediaGalleryImages', 'isSalable']
152154
);
153155
$productMock->expects($this->any())
154156
->method('getData')
155157
->will($this->returnCallback([$this, 'getDataCallback']));
156158
$productMock->expects($this->any())
157159
->method('getId')
158160
->will($this->returnValue('product_id_' . $i));
161+
$productMock
162+
->expects($this->any())
163+
->method('isSalable')
164+
->will($this->returnValue(true));
159165
if ($i == 2) {
160166
$productMock->expects($this->any())
161167
->method('getImage')
@@ -230,11 +236,13 @@ public function testGetGalleryImages()
230236
self::identicalTo('product_page_image_large')
231237
]
232238
)
233-
->will(self::onConsecutiveCalls(
234-
'testSmallImageUrl',
235-
'testMediumImageUrl',
236-
'testLargeImageUrl'
237-
));
239+
->will(
240+
self::onConsecutiveCalls(
241+
'testSmallImageUrl',
242+
'testMediumImageUrl',
243+
'testLargeImageUrl'
244+
)
245+
);
238246
$this->_imageHelperMock->expects(self::never())
239247
->method('setImageFile')
240248
->with('test_file')
@@ -265,9 +273,9 @@ private function getImagesCollection()
265273
->getMock();
266274

267275
$items = [
268-
new \Magento\Framework\DataObject([
269-
'file' => 'test_file'
270-
]),
276+
new \Magento\Framework\DataObject(
277+
['file' => 'test_file']
278+
),
271279
];
272280

273281
$collectionMock->expects($this->any())

app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,8 @@ define([
377377
optionFinalPrice,
378378
optionPriceDiff,
379379
optionPrices = this.options.spConfig.optionPrices,
380+
allowedOptions = [],
381+
indexKey,
380382
allowedProductMinPrice;
381383

382384
this._clearSelect(element);
@@ -389,6 +391,13 @@ define([
389391
}
390392

391393
if (options) {
394+
for (indexKey in this.options.spConfig.index) {
395+
/* eslint-disable max-depth */
396+
if (this.options.spConfig.index.hasOwnProperty(indexKey)) {
397+
allowedOptions = allowedOptions.concat(_.values(this.options.spConfig.index[indexKey]));
398+
}
399+
}
400+
392401
for (i = 0; i < options.length; i++) {
393402
allowedProducts = [];
394403
optionPriceDiff = 0;
@@ -421,14 +430,18 @@ define([
421430
}
422431
}
423432

424-
if (allowedProducts.length > 0) {
433+
if (allowedProducts.length > 0 || _.include(allowedOptions, options[i].id)) {
425434
options[i].allowedProducts = allowedProducts;
426435
element.options[index] = new Option(this._getOptionLabel(options[i]), options[i].id);
427436

428437
if (typeof options[i].price !== 'undefined') {
429438
element.options[index].setAttribute('price', options[i].price);
430439
}
431440

441+
if (allowedProducts.length === 0) {
442+
element.options[index].disabled = true;
443+
}
444+
432445
element.options[index].config = options[i];
433446
index++;
434447
}

app/code/Magento/Swatches/Test/Unit/Block/Product/Renderer/Listing/ConfigurableTest.php

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
namespace Magento\Swatches\Test\Unit\Block\Product\Renderer\Listing;
77

8+
use Magento\Catalog\Model\Product\Attribute\Source\Status;
89
use Magento\Swatches\Block\Product\Renderer\Configurable;
910

1011
/**
@@ -130,14 +131,16 @@ public function testGetJsonSwatchNotUsedInProductListing()
130131
$this->configurable->setProduct($this->product);
131132
$this->swatchHelper->expects($this->once())->method('getSwatchAttributesAsArray')
132133
->with($this->product)
133-
->willReturn([
134-
1 => [
135-
'options' => [1 => 'testA', 3 => 'testB'],
136-
'use_product_image_for_swatch' => true,
137-
'used_in_product_listing' => false,
138-
'attribute_code' => 'code',
139-
],
140-
]);
134+
->willReturn(
135+
[
136+
1 => [
137+
'options' => [1 => 'testA', 3 => 'testB'],
138+
'use_product_image_for_swatch' => true,
139+
'used_in_product_listing' => false,
140+
'attribute_code' => 'code',
141+
],
142+
]
143+
);
141144
$this->swatchHelper->expects($this->once())->method('getSwatchesByOptionsId')
142145
->willReturn([]);
143146
$this->jsonEncoder->expects($this->once())->method('encode')->with([]);
@@ -163,31 +166,33 @@ public function testGetJsonSwatchUsedInProductListing()
163166
$this->configurable->setProduct($this->product);
164167
$this->swatchHelper->expects($this->once())->method('getSwatchAttributesAsArray')
165168
->with($this->product)
166-
->willReturn([
167-
1 => [
168-
'options' => $products,
169-
'use_product_image_for_swatch' => true,
170-
'used_in_product_listing' => true,
171-
'attribute_code' => 'code',
172-
],
173-
]);
169+
->willReturn(
170+
[
171+
1 => [
172+
'options' => $products,
173+
'use_product_image_for_swatch' => true,
174+
'used_in_product_listing' => true,
175+
'attribute_code' => 'code',
176+
],
177+
]
178+
);
174179
$this->swatchHelper->expects($this->once())->method('getSwatchesByOptionsId')
175180
->with([1, 3])
176-
->willReturn([
177-
3 => ['type' => $expected['type'], 'value' => $expected['value']]
178-
]);
181+
->willReturn([3 => ['type' => $expected['type'], 'value' => $expected['value']]]);
179182
$this->jsonEncoder->expects($this->once())->method('encode');
180183
$this->configurable->getJsonSwatchConfig();
181184
}
182185

183186
private function prepareGetJsonSwatchConfig()
184187
{
185188
$product1 = $this->createMock(\Magento\Catalog\Model\Product::class);
186-
$product1->expects($this->atLeastOnce())->method('isSaleable')->willReturn(true);
189+
$product1->expects($this->any())->method('isSaleable')->willReturn(true);
190+
$product1->expects($this->atLeastOnce())->method('getStatus')->willReturn(Status::STATUS_ENABLED);
187191
$product1->expects($this->any())->method('getData')->with('code')->willReturn(1);
188192

189193
$product2 = $this->createMock(\Magento\Catalog\Model\Product::class);
190-
$product2->expects($this->atLeastOnce())->method('isSaleable')->willReturn(true);
194+
$product2->expects($this->any())->method('isSaleable')->willReturn(true);
195+
$product2->expects($this->atLeastOnce())->method('getStatus')->willReturn(Status::STATUS_ENABLED);
191196
$product2->expects($this->any())->method('getData')->with('code')->willReturn(3);
192197

193198
$simpleProducts = [$product1, $product2];

0 commit comments

Comments
 (0)