Skip to content

Commit 11c887a

Browse files
committed
MAGETWO-55729: [Customer] Optimize performance for bundled products with lots of product options
- MAGETWO-60726: Bundle price range calculation is incorrect for products with Special Price
1 parent 6a86bc8 commit 11c887a

File tree

2 files changed

+41
-49
lines changed

2 files changed

+41
-49
lines changed

app/code/Magento/Bundle/Pricing/Adjustment/DefaultSelectionPriceListProvider.php

Lines changed: 30 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ class DefaultSelectionPriceListProvider implements SelectionPriceListProviderInt
2121
*/
2222
private $selectionFactory;
2323

24+
/**
25+
* @var \Magento\Bundle\Pricing\Price\BundleSelectionPrice[]
26+
*/
27+
private $priceList;
28+
2429
/**
2530
* @param BundleSelectionFactory $bundleSelectionFactory
2631
*/
@@ -39,7 +44,7 @@ public function getPriceList(Product $bundleProduct, $searchMin, $useRegularPric
3944

4045
/** @var \Magento\Bundle\Model\Product\Type $typeInstance */
4146
$typeInstance = $bundleProduct->getTypeInstance();
42-
$priceList = [];
47+
$this->priceList = [];
4348

4449
foreach ($this->getBundleOptions($bundleProduct) as $option) {
4550
/** @var Option $option */
@@ -54,24 +59,25 @@ public function getPriceList(Product $bundleProduct, $searchMin, $useRegularPric
5459
$selectionsCollection->removeAttributeToSelect();
5560
$selectionsCollection->addQuantityFilter();
5661

62+
if (!$useRegularPrice) {
63+
$selectionsCollection->addAttributeToSelect('special_price');
64+
$selectionsCollection->addAttributeToSelect('special_price_from');
65+
$selectionsCollection->addAttributeToSelect('special_price_to');
66+
$selectionsCollection->addAttributeToSelect('tax_class_id');
67+
}
68+
5769
if (!$searchMin && $option->isMultiSelection()) {
58-
$priceList = array_merge(
59-
$priceList,
60-
$this->getMaximumMultiselectionPriceList($bundleProduct, $selectionsCollection, $useRegularPrice)
61-
);
70+
$this->addMaximumMultiSelectionPriceList($bundleProduct, $selectionsCollection, $useRegularPrice);
6271
} else {
63-
$priceList = array_merge(
64-
$priceList,
65-
$this->getMiniMaxPriceList($bundleProduct, $selectionsCollection, $searchMin, $useRegularPrice)
66-
);
72+
$this->addMiniMaxPriceList($bundleProduct, $selectionsCollection, $searchMin, $useRegularPrice);
6773
}
6874
}
6975

7076
if ($shouldFindMinOption) {
71-
$priceList = $this->getMinPriceForNonRequiredOptions($priceList);
77+
$this->processMinPriceForNonRequiredOptions();
7278
}
7379

74-
return $priceList;
80+
return $this->priceList;
7581
}
7682

7783
/**
@@ -95,31 +101,23 @@ private function isShouldFindMinOption(Product $bundleProduct, $searchMin)
95101
}
96102

97103
/**
98-
* Get minimum or maximum price for option
104+
* Add minimum or maximum price for option
99105
*
100106
* @param Product $bundleProduct
101107
* @param \Magento\Bundle\Model\ResourceModel\Selection\Collection $selectionsCollection
102108
* @param bool $searchMin
103109
* @param bool $useRegularPrice
104-
* @return \Magento\Bundle\Pricing\Price\BundleSelectionPrice[]
110+
* @return void
105111
*/
106-
private function getMiniMaxPriceList(Product $bundleProduct, $selectionsCollection, $searchMin, $useRegularPrice)
112+
private function addMiniMaxPriceList(Product $bundleProduct, $selectionsCollection, $searchMin, $useRegularPrice)
107113
{
108-
$priceList = [];
109-
110114
$selectionsCollection->addPriceFilter($bundleProduct, $searchMin, $useRegularPrice);
111115
$selectionsCollection->setPage(0, 1);
112-
if (!$useRegularPrice) {
113-
$selectionsCollection->addAttributeToSelect('special_price');
114-
$selectionsCollection->addAttributeToSelect('special_price_from');
115-
$selectionsCollection->addAttributeToSelect('special_price_to');
116-
$selectionsCollection->addAttributeToSelect('tax_class_id');
117-
}
118116

119117
$selection = $selectionsCollection->getFirstItem();
120118

121119
if (!$selection->isEmpty()) {
122-
$priceList[] = $this->selectionFactory->create(
120+
$this->priceList[] = $this->selectionFactory->create(
123121
$bundleProduct,
124122
$selection,
125123
$selection->getSelectionQty(),
@@ -128,25 +126,22 @@ private function getMiniMaxPriceList(Product $bundleProduct, $selectionsCollecti
128126
]
129127
);
130128
}
131-
132-
return $priceList;
133129
}
134130

135131
/**
136-
* Get maximum price for multiselection option
132+
* Add maximum price for multi selection option
137133
*
138134
* @param Product $bundleProduct
139135
* @param \Magento\Bundle\Model\ResourceModel\Selection\Collection $selectionsCollection
140136
* @param bool $useRegularPrice
141-
* @return \Magento\Bundle\Pricing\Price\BundleSelectionPrice[]
137+
* @return void
142138
*/
143-
private function getMaximumMultiselectionPriceList(Product $bundleProduct, $selectionsCollection, $useRegularPrice)
139+
private function addMaximumMultiSelectionPriceList(Product $bundleProduct, $selectionsCollection, $useRegularPrice)
144140
{
145-
$priceList = [];
146-
147141
$selectionsCollection->addPriceData();
142+
148143
foreach ($selectionsCollection as $selection) {
149-
$priceList[] = $this->selectionFactory->create(
144+
$this->priceList[] = $this->selectionFactory->create(
150145
$bundleProduct,
151146
$selection,
152147
$selection->getSelectionQty(),
@@ -155,28 +150,23 @@ private function getMaximumMultiselectionPriceList(Product $bundleProduct, $sele
155150
]
156151
);
157152
}
158-
159-
return $priceList;
160153
}
161154

162155
/**
163-
* @param \Magento\Bundle\Pricing\Price\BundleSelectionPrice[] $priceList
164-
* @return \Magento\Bundle\Pricing\Price\BundleSelectionPrice[]
156+
* @return void
165157
*/
166-
private function getMinPriceForNonRequiredOptions($priceList)
158+
private function processMinPriceForNonRequiredOptions()
167159
{
168160
$minPrice = null;
169161
$priceSelection = null;
170-
foreach ($priceList as $price) {
162+
foreach ($this->priceList as $price) {
171163
$minPriceTmp = $price->getAmount()->getValue() * $price->getQuantity();
172164
if (!$minPrice || $minPriceTmp < $minPrice) {
173165
$minPrice = $minPriceTmp;
174166
$priceSelection = $price;
175167
}
176168
}
177-
$priceList = $priceSelection ? [$priceSelection] : [];
178-
179-
return $priceList;
169+
$this->priceList = $priceSelection ? [$priceSelection] : [];
180170
}
181171

182172
/**

dev/tests/integration/testsuite/Magento/Bundle/Model/Product/DynamicBundleWithSpecialPriceCalculatorTest.php

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,12 @@ public function getTestCases()
8989

9090
'
9191
#4 Testing price for dynamic bundle
92-
with one required multi type option, two simples and special price
92+
with one required multi type option, two simples with special price
9393
' => [
9494
'strategy' => $this->getBundleConfiguration4(),
9595
'expectedResults' => [
96-
// 0.5 * 1 * 10
97-
'minimalPrice' => 5,
98-
// 0.5 * (1 * 10 + 3 * 20)
99-
'maximalPrice' => 35
96+
'minimalPrice' => 9.99,
97+
'maximalPrice' => 21.97
10098
]
10199
],
102100

@@ -290,24 +288,28 @@ private function getBundleConfiguration4()
290288
[
291289
'title' => 'Op1',
292290
'required' => true,
293-
'type' => 'multi',
291+
'type' => 'checkbox',
294292
'links' => [
295293
[
296294
'sku' => 'simple1',
297295
'qty' => 1,
298296
],
299297
[
300298
'sku' => 'simple2',
301-
'qty' => 3,
299+
'qty' => 2,
302300
],
303301
]
304302
]
305303
];
306304

307305
return [
308306
[
309-
'modifierName' => 'addSpecialPrice',
310-
'data' => [50]
307+
'modifierName' => 'addSpecialPriceForSimple',
308+
'data' => ['simple1', 9.99]
309+
],
310+
[
311+
'modifierName' => 'addSpecialPriceForSimple',
312+
'data' => ['simple2', 5.99]
311313
],
312314
[
313315
'modifierName' => 'addSimpleProduct',

0 commit comments

Comments
 (0)