Skip to content

Commit 3376129

Browse files
author
Oleksii Korshenko
authored
Merge pull request #480 from magento-fearless-kiwis/pull_request_2.0.11
Fixed issues: - MAGETWO-59102 Bundle Products - The options you selected are not available - MAGETWO-58035 [Backport] - Configurable product options not saved when editing
2 parents 048569a + 4f71645 commit 3376129

File tree

18 files changed

+349
-164
lines changed

18 files changed

+349
-164
lines changed

app/code/Magento/Bundle/Model/Product/Type.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,12 @@ protected function _prepareProduct(\Magento\Framework\DataObject $buyRequest, $p
716716
if (!empty($selectionIds)) {
717717
$selections = $this->getSelectionsByIds($selectionIds, $product);
718718

719+
if (count($selections->getItems()) !== count($selectionIds)) {
720+
throw new \Magento\Framework\Exception\LocalizedException(
721+
__('The options you selected are not available.')
722+
);
723+
}
724+
719725
// Check if added selections are still on sale
720726
$this->checkSelectionsIsSale(
721727
$selections,
@@ -888,12 +894,6 @@ public function getSelectionsByIds($selectionIds, $product)
888894
->addFilterByRequiredOptions()
889895
->setSelectionIdsFilter($selectionIds);
890896

891-
if (count($usedSelections->getItems()) !== count($selectionIds)) {
892-
throw new \Magento\Framework\Exception\LocalizedException(
893-
__('The options you selected are not available.')
894-
);
895-
}
896-
897897
if (!$this->_catalogData->isPriceGlobal() && $storeId) {
898898
$websiteId = $this->_storeManager->getStore($storeId)
899899
->getWebsiteId();

app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php

Lines changed: 21 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ function ($key) use ($optionCollection, $selectionCollection) {
377377
$resultValue = $selectionCollection;
378378
break;
379379
case '_cache_instance_used_selections_ids':
380-
$resultValue = [2, 5, 14];
380+
$resultValue = [5];
381381
break;
382382
}
383383

@@ -402,7 +402,7 @@ function ($key) use ($optionCollection, $selectionCollection) {
402402
->method('setStoreFilter');
403403
$buyRequest->expects($this->once())
404404
->method('getBundleOption')
405-
->willReturn([3 => 5, 10 => [7 => 2, 11 => 14]]);
405+
->willReturn([3 => 5]);
406406
$selectionCollection->expects($this->any())
407407
->method('getItems')
408408
->willReturn([$selection]);
@@ -431,13 +431,13 @@ function ($key) use ($optionCollection, $selectionCollection) {
431431
->willReturn($productType);
432432
$option->expects($this->at(3))
433433
->method('getId')
434-
->willReturn(10);
434+
->willReturn(3);
435435
$option->expects($this->at(9))
436436
->method('getId')
437-
->willReturn(10);
437+
->willReturn(3);
438438
$option->expects($this->once())
439439
->method('getRequired')
440-
->willReturn(true);
440+
->willReturn(false);
441441
$option->expects($this->once())
442442
->method('isMultiSelection')
443443
->willReturn(true);
@@ -608,7 +608,7 @@ function ($key) use ($optionCollection, $selectionCollection) {
608608
$resultValue = $selectionCollection;
609609
break;
610610
case '_cache_instance_used_selections_ids':
611-
$resultValue = [2, 5, 14];
611+
$resultValue = [5];
612612
break;
613613
}
614614

@@ -633,7 +633,7 @@ function ($key) use ($optionCollection, $selectionCollection) {
633633
->method('setStoreFilter');
634634
$buyRequest->expects($this->once())
635635
->method('getBundleOption')
636-
->willReturn([3 => 5, 10 => [7 => 2, 11 => 14]]);
636+
->willReturn([3 => 5]);
637637
$selectionCollection->expects($this->any())
638638
->method('getItems')
639639
->willReturn([$selection]);
@@ -662,13 +662,13 @@ function ($key) use ($optionCollection, $selectionCollection) {
662662
->willReturn($productType);
663663
$option->expects($this->at(3))
664664
->method('getId')
665-
->willReturn(10);
665+
->willReturn(3);
666666
$option->expects($this->at(9))
667667
->method('getId')
668-
->willReturn(10);
668+
->willReturn(3);
669669
$option->expects($this->once())
670670
->method('getRequired')
671-
->willReturn(true);
671+
->willReturn(false);
672672
$option->expects($this->once())
673673
->method('isMultiSelection')
674674
->willReturn(true);
@@ -827,7 +827,7 @@ function ($key) use ($optionCollection, $selectionCollection) {
827827
$resultValue = $selectionCollection;
828828
break;
829829
case '_cache_instance_used_selections_ids':
830-
$resultValue = [2, 5, 14];
830+
$resultValue = [5];
831831
break;
832832
}
833833

@@ -852,7 +852,7 @@ function ($key) use ($optionCollection, $selectionCollection) {
852852
->method('setStoreFilter');
853853
$buyRequest->expects($this->once())
854854
->method('getBundleOption')
855-
->willReturn([3 => 5, 10 => [7 => 2, 11 => 14]]);
855+
->willReturn([3 => 5]);
856856
$selectionCollection->expects($this->any())
857857
->method('getItems')
858858
->willReturn([$selection]);
@@ -881,13 +881,13 @@ function ($key) use ($optionCollection, $selectionCollection) {
881881
->willReturn($productType);
882882
$option->expects($this->at(3))
883883
->method('getId')
884-
->willReturn(10);
884+
->willReturn(3);
885885
$option->expects($this->at(9))
886886
->method('getId')
887-
->willReturn(10);
887+
->willReturn(3);
888888
$option->expects($this->once())
889889
->method('getRequired')
890-
->willReturn(true);
890+
->willReturn(false);
891891
$option->expects($this->once())
892892
->method('isMultiSelection')
893893
->willReturn(true);
@@ -1112,41 +1112,29 @@ function ($key) use ($optionCollection, $selectionCollection) {
11121112
$resultValue = $selectionCollection;
11131113
break;
11141114
case '_cache_instance_used_selections_ids':
1115-
$resultValue = [2, 5, 14];
1115+
$resultValue = [5];
11161116
break;
11171117
}
11181118

11191119
return $resultValue;
11201120
}
11211121
);
1122-
$optionCollection->expects($this->once())
1123-
->method('getItemById')
1124-
->willReturn($option);
11251122
$optionCollection->expects($this->once())
11261123
->method('appendSelections');
11271124
$productType->expects($this->once())
11281125
->method('setStoreFilter');
11291126
$buyRequest->expects($this->once())
11301127
->method('getBundleOption')
1131-
->willReturn([3 => 5, 10 => [7 => 2, 11 => 14]]);
1128+
->willReturn([3 => 5]);
11321129
$selectionCollection->expects($this->at(0))
11331130
->method('getItems')
11341131
->willReturn([$selection]);
11351132
$selectionCollection->expects($this->at(1))
11361133
->method('getItems')
11371134
->willReturn([]);
1138-
$selection->expects($this->once())
1139-
->method('isSalable')
1140-
->willReturn(false);
1141-
$option->expects($this->at(3))
1135+
$option->expects($this->any())
11421136
->method('getId')
1143-
->willReturn(10);
1144-
$option->expects($this->once())
1145-
->method('getRequired')
1146-
->willReturn(true);
1147-
$option->expects($this->once())
1148-
->method('isMultiSelection')
1149-
->willReturn(true);
1137+
->willReturn(3);
11501138

11511139
$result = $this->model->prepareForCartAdvanced($buyRequest, $product);
11521140
$this->assertEquals('Please specify product option(s).', $result);
@@ -1255,7 +1243,7 @@ function ($key) use ($optionCollection, $selectionCollection) {
12551243
$buyRequest->expects($this->once())
12561244
->method('getBundleOption')
12571245
->willReturn([3 => 5]);
1258-
$selectionCollection->expects($this->once())
1246+
$selectionCollection->expects($this->any())
12591247
->method('getItems')
12601248
->willReturn([$selection]);
12611249
$selection->expects($this->once())
@@ -1901,8 +1889,7 @@ public function testGetSelectionsByIds()
19011889
'setPositionOrder',
19021890
'addFilterByRequiredOptions',
19031891
'setSelectionIdsFilter',
1904-
'joinPrices',
1905-
'getItems'
1892+
'joinPrices'
19061893
]
19071894
)
19081895
->disableOriginalConstructor()
@@ -1971,9 +1958,6 @@ public function testGetSelectionsByIds()
19711958
->method('setSelectionIdsFilter')
19721959
->with($selectionIds)
19731960
->will($this->returnSelf());
1974-
$usedSelectionsMock->expects($this->once())
1975-
->method('getItems')
1976-
->willReturn($usedSelectionsIds);
19771961

19781962
$usedSelectionsMock->expects($this->once())
19791963
->method('joinPrices')
@@ -1987,96 +1971,6 @@ public function testGetSelectionsByIds()
19871971
$this->model->getSelectionsByIds($selectionIds, $productMock);
19881972
}
19891973

1990-
/**
1991-
* @expectedException \Magento\Framework\Exception\LocalizedException
1992-
* @expectedExceptionMessage The options you selected are not available.
1993-
*
1994-
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
1995-
*/
1996-
public function testGetSelectionsByIdsException()
1997-
{
1998-
$selectionIds = [1, 2, 3];
1999-
$usedSelectionsIds = [4, 5];
2000-
$storeId = 2;
2001-
$storeFilter = 'store_filter';
2002-
$productMock = $this->getMockBuilder('Magento\Catalog\Model\Product')
2003-
->disableOriginalConstructor()
2004-
->getMock();
2005-
$usedSelectionsMock = $this->getMockBuilder('Magento\Bundle\Model\ResourceModel\Selection\Collection')
2006-
->setMethods(
2007-
[
2008-
'addAttributeToSelect',
2009-
'setFlag',
2010-
'addStoreFilter',
2011-
'setStoreId',
2012-
'setPositionOrder',
2013-
'addFilterByRequiredOptions',
2014-
'setSelectionIdsFilter',
2015-
'joinPrices',
2016-
'getItems'
2017-
]
2018-
)
2019-
->disableOriginalConstructor()
2020-
->getMock();
2021-
$productGetMap = [
2022-
['_cache_instance_used_selections', null, null],
2023-
['_cache_instance_used_selections_ids', null, $usedSelectionsIds],
2024-
['_cache_instance_store_filter', null, $storeFilter],
2025-
];
2026-
$productMock->expects($this->any())
2027-
->method('getData')
2028-
->will($this->returnValueMap($productGetMap));
2029-
$productSetMap = [
2030-
['_cache_instance_used_selections', $usedSelectionsMock, $productMock],
2031-
['_cache_instance_used_selections_ids', $selectionIds, $productMock],
2032-
];
2033-
$productMock->expects($this->any())
2034-
->method('setData')
2035-
->will($this->returnValueMap($productSetMap));
2036-
$productMock->expects($this->once())
2037-
->method('getStoreId')
2038-
->will($this->returnValue($storeId));
2039-
2040-
$this->bundleCollection->expects($this->once())
2041-
->method('create')
2042-
->will($this->returnValue($usedSelectionsMock));
2043-
2044-
$usedSelectionsMock->expects($this->once())
2045-
->method('addAttributeToSelect')
2046-
->with('*')
2047-
->will($this->returnSelf());
2048-
$flagMap = [
2049-
['require_stock_items', true, $usedSelectionsMock],
2050-
['product_children', true, $usedSelectionsMock],
2051-
];
2052-
$usedSelectionsMock->expects($this->any())
2053-
->method('setFlag')
2054-
->will($this->returnValueMap($flagMap));
2055-
$usedSelectionsMock->expects($this->once())
2056-
->method('addStoreFilter')
2057-
->with($storeFilter)
2058-
->will($this->returnSelf());
2059-
$usedSelectionsMock->expects($this->once())
2060-
->method('setStoreId')
2061-
->with($storeId)
2062-
->will($this->returnSelf());
2063-
$usedSelectionsMock->expects($this->once())
2064-
->method('setPositionOrder')
2065-
->will($this->returnSelf());
2066-
$usedSelectionsMock->expects($this->once())
2067-
->method('addFilterByRequiredOptions')
2068-
->will($this->returnSelf());
2069-
$usedSelectionsMock->expects($this->once())
2070-
->method('setSelectionIdsFilter')
2071-
->with($selectionIds)
2072-
->will($this->returnSelf());
2073-
$usedSelectionsMock->expects($this->once())
2074-
->method('getItems')
2075-
->willReturn($usedSelectionsIds);
2076-
2077-
2078-
$this->model->getSelectionsByIds($selectionIds, $productMock);
2079-
}
20801974
/**
20811975
* @return void
20821976
*/

app/code/Magento/Checkout/CustomerData/DefaultItem.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ protected function doGetItemData()
7070
'item_id' => $this->item->getId(),
7171
'configure_url' => $this->getConfigureUrl(),
7272
'is_visible_in_site_visibility' => $this->item->getProduct()->isVisibleInSiteVisibility(),
73+
'product_id' => $this->item->getProduct()->getId(),
7374
'product_name' => $this->item->getProduct()->getName(),
7475
'product_url' => $this->getProductUrl(),
7576
'product_has_url' => $this->hasProductUrl(),

app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,9 +818,15 @@ public function getSelectedAttributesInfo($product)
818818
$value = $value->getSource()->getOptionText($attributeValue);
819819
} else {
820820
$value = '';
821+
$attributeValue = '';
821822
}
822823

823-
$attributes[] = ['label' => $label, 'value' => $value];
824+
$attributes[] = [
825+
'label' => $label,
826+
'value' => $value,
827+
'option_id' => $attributeId,
828+
'option_value' => $attributeValue,
829+
];
824830
}
825831
}
826832
}

app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/ConfigurableTest.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,14 @@ public function testGetSelectedAttributesInfo()
564564

565565
$this->assertEquals(
566566
$this->_model->getSelectedAttributesInfo($productMock),
567-
[['label' => 'attr_store_label', 'value' => '']]
567+
[
568+
[
569+
'label' => 'attr_store_label',
570+
'value' => '',
571+
'option_id' => 1,
572+
'option_value' => ''
573+
]
574+
]
568575
);
569576
}
570577

app/code/Magento/ConfigurableProduct/view/frontend/layout/checkout_cart_configure_type_configurable.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
*/
77
-->
88
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
9+
<head>
10+
<link src="Magento_ConfigurableProduct::js/configurable-customer-data.js"/>
11+
</head>
912
<update handle="catalog_product_view_type_configurable"/>
1013
<body/>
1114
</page>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* Copyright © 2016 Magento. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
require([
7+
'jquery',
8+
'Magento_ConfigurableProduct/js/options-updater'
9+
], function ($, Updater) {
10+
'use strict';
11+
12+
var selectors = {
13+
formSelector: '#product_addtocart_form'
14+
},
15+
configurableWidgetName = 'mageConfigurable',
16+
widgetInitEvent = 'configurable.initialized',
17+
18+
/**
19+
* Sets all configurable attribute's selected values
20+
*/
21+
updateConfigurableOptions = function () {
22+
var configurableWidget = $(selectors.formSelector).data(configurableWidgetName);
23+
24+
if (!configurableWidget) {
25+
return;
26+
}
27+
configurableWidget.options.values = this.productOptions || {};
28+
configurableWidget._configureForValues();
29+
},
30+
updater = new Updater(widgetInitEvent, updateConfigurableOptions);
31+
32+
updater.listen();
33+
});

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ define([
5353

5454
// Setup/configure values to inputs
5555
this._configureForValues();
56+
57+
$(this.element).trigger('configurable.initialized');
5658
},
5759

5860
/**

0 commit comments

Comments
 (0)