Skip to content

Commit 53c9efb

Browse files
Merge pull request magento#2078 from magento-panda/PANDA-FIXES-2.2
Fixed issues: - MAGETWO-69634: Product with a special price must be showed with this price in the wishlist - MAGETWO-86918: Saving configurable product erases and reinserts records in table "catalog_product_super_link" even with no changes
2 parents 40c9d62 + 0ad6fdd commit 53c9efb

File tree

37 files changed

+1984
-455
lines changed

37 files changed

+1984
-455
lines changed

app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,18 +228,23 @@ private function getSelectionItemData(Product $product, Product $selection)
228228
$qty = ($selection->getSelectionQty() * 1) ?: '1';
229229

230230
$optionPriceAmount = $product->getPriceInfo()
231-
->getPrice('bundle_option')
231+
->getPrice(\Magento\Bundle\Pricing\Price\BundleOptionPrice::PRICE_CODE)
232232
->getOptionSelectionAmount($selection);
233233
$finalPrice = $optionPriceAmount->getValue();
234234
$basePrice = $optionPriceAmount->getBaseAmount();
235235

236+
$oldPrice = $product->getPriceInfo()
237+
->getPrice(\Magento\Bundle\Pricing\Price\BundleOptionRegularPrice::PRICE_CODE)
238+
->getOptionSelectionAmount($selection)
239+
->getValue();
240+
236241
$selection = [
237242
'qty' => $qty,
238243
'customQty' => $selection->getSelectionCanChangeQty(),
239244
'optionId' => $selection->getId(),
240245
'prices' => [
241246
'oldPrice' => [
242-
'amount' => $basePrice
247+
'amount' => $oldPrice
243248
],
244249
'basePrice' => [
245250
'amount' => $basePrice

app/code/Magento/Bundle/Pricing/Price/BundleOptionPrice.php

Lines changed: 21 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
use Magento\Framework\Pricing\Price\AbstractPrice;
1111

1212
/**
13-
* Bundle option price model
13+
* Bundle option price model with final price
1414
*/
1515
class BundleOptionPrice extends AbstractPrice implements BundleOptionPriceInterface
1616
{
@@ -26,6 +26,7 @@ class BundleOptionPrice extends AbstractPrice implements BundleOptionPriceInterf
2626

2727
/**
2828
* @var BundleSelectionFactory
29+
* @deprecated
2930
*/
3031
protected $selectionFactory;
3132

@@ -34,23 +35,32 @@ class BundleOptionPrice extends AbstractPrice implements BundleOptionPriceInterf
3435
*/
3536
protected $maximalPrice;
3637

38+
/**
39+
* @var \Magento\Bundle\Pricing\Price\BundleOptions
40+
*/
41+
private $bundleOptions;
42+
3743
/**
3844
* @param Product $saleableItem
3945
* @param float $quantity
4046
* @param BundleCalculatorInterface $calculator
4147
* @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
4248
* @param BundleSelectionFactory $bundleSelectionFactory
49+
* @param BundleOptions|null $bundleOptions
4350
*/
4451
public function __construct(
4552
Product $saleableItem,
4653
$quantity,
4754
BundleCalculatorInterface $calculator,
4855
\Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
49-
BundleSelectionFactory $bundleSelectionFactory
56+
BundleSelectionFactory $bundleSelectionFactory,
57+
BundleOptions $bundleOptions = null
5058
) {
5159
$this->selectionFactory = $bundleSelectionFactory;
5260
parent::__construct($saleableItem, $quantity, $calculator, $priceCurrency);
5361
$this->product->setQty($this->quantity);
62+
$this->bundleOptions = $bundleOptions ?: \Magento\Framework\App\ObjectManager::getInstance()
63+
->get(\Magento\Bundle\Pricing\Price\BundleOptions::class);
5464
}
5565

5666
/**
@@ -59,7 +69,7 @@ public function __construct(
5969
public function getValue()
6070
{
6171
if (null === $this->value) {
62-
$this->value = $this->calculateOptions();
72+
$this->value = $this->bundleOptions->calculateOptions($this->product);
6373
}
6474
return $this->value;
6575
}
@@ -68,11 +78,12 @@ public function getValue()
6878
* Getter for maximal price of options
6979
*
7080
* @return bool|float
81+
* @deprecated
7182
*/
7283
public function getMaxValue()
7384
{
7485
if (null === $this->maximalPrice) {
75-
$this->maximalPrice = $this->calculateOptions(false);
86+
$this->maximalPrice = $this->bundleOptions->calculateOptions($this->product, false);
7687
}
7788
return $this->maximalPrice;
7889
}
@@ -84,21 +95,7 @@ public function getMaxValue()
8495
*/
8596
public function getOptions()
8697
{
87-
$bundleProduct = $this->product;
88-
/** @var \Magento\Bundle\Model\Product\Type $typeInstance */
89-
$typeInstance = $bundleProduct->getTypeInstance();
90-
$typeInstance->setStoreFilter($bundleProduct->getStoreId(), $bundleProduct);
91-
92-
/** @var \Magento\Bundle\Model\ResourceModel\Option\Collection $optionCollection */
93-
$optionCollection = $typeInstance->getOptionsCollection($bundleProduct);
94-
95-
$selectionCollection = $typeInstance->getSelectionsCollection(
96-
$typeInstance->getOptionsIds($bundleProduct),
97-
$bundleProduct
98-
);
99-
100-
$priceOptions = $optionCollection->appendSelections($selectionCollection, true, false);
101-
return $priceOptions;
98+
return $this->bundleOptions->getOptions($this->product);
10299
}
103100

104101
/**
@@ -109,22 +106,11 @@ public function getOptions()
109106
*/
110107
public function getOptionSelectionAmount($selection)
111108
{
112-
$cacheKey = implode(
113-
'_',
114-
[
115-
$this->product->getId(),
116-
$selection->getOptionId(),
117-
$selection->getSelectionId()
118-
]
109+
return $this->bundleOptions->getOptionSelectionAmount(
110+
$this->product,
111+
$selection,
112+
false
119113
);
120-
121-
if (!isset($this->optionSelecionAmountCache[$cacheKey])) {
122-
$selectionPrice = $this->selectionFactory
123-
->create($this->product, $selection, $selection->getSelectionQty());
124-
$this->optionSelecionAmountCache[$cacheKey] = $selectionPrice->getAmount();
125-
}
126-
127-
return $this->optionSelecionAmountCache[$cacheKey];
128114
}
129115

130116
/**
@@ -135,18 +121,7 @@ public function getOptionSelectionAmount($selection)
135121
*/
136122
protected function calculateOptions($searchMin = true)
137123
{
138-
$priceList = [];
139-
/* @var $option \Magento\Bundle\Model\Option */
140-
foreach ($this->getOptions() as $option) {
141-
if ($searchMin && !$option->getRequired()) {
142-
continue;
143-
}
144-
$selectionPriceList = $this->calculator->createSelectionPriceList($option, $this->product);
145-
$selectionPriceList = $this->calculator->processOptions($option, $selectionPriceList, $searchMin);
146-
$priceList = array_merge($priceList, $selectionPriceList);
147-
}
148-
$amount = $this->calculator->calculateBundleAmount(0., $this->product, $priceList);
149-
return $amount->getValue();
124+
return $this->bundleOptions->calculateOptions($this->product, $searchMin);
150125
}
151126

152127
/**
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Bundle\Pricing\Price;
9+
10+
use Magento\Bundle\Pricing\Adjustment\BundleCalculatorInterface;
11+
use Magento\Catalog\Model\Product;
12+
use Magento\Framework\Pricing\Price\AbstractPrice;
13+
14+
/**
15+
* Bundle option price model with final price
16+
*/
17+
class BundleOptionRegularPrice extends AbstractPrice implements BundleOptionPriceInterface
18+
{
19+
/**
20+
* Price model code
21+
*/
22+
const PRICE_CODE = 'bundle_option_regular_price';
23+
24+
/**
25+
* @var BundleCalculatorInterface
26+
*/
27+
protected $calculator;
28+
29+
/**
30+
* @var \Magento\Bundle\Pricing\Price\BundleOptions
31+
*/
32+
private $bundleOptions;
33+
34+
/**
35+
* @param Product $saleableItem
36+
* @param float $quantity
37+
* @param BundleCalculatorInterface $calculator
38+
* @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
39+
* @param BundleOptions $bundleOptions
40+
*/
41+
public function __construct(
42+
Product $saleableItem,
43+
$quantity,
44+
BundleCalculatorInterface $calculator,
45+
\Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
46+
BundleOptions $bundleOptions
47+
) {
48+
parent::__construct($saleableItem, $quantity, $calculator, $priceCurrency);
49+
$this->product->setQty($this->quantity);
50+
$this->bundleOptions = $bundleOptions;
51+
}
52+
53+
/**
54+
* {@inheritdoc}
55+
*/
56+
public function getValue()
57+
{
58+
if (null === $this->value) {
59+
$this->value = $this->bundleOptions->calculateOptions($this->product);
60+
}
61+
return $this->value;
62+
}
63+
64+
/**
65+
* Get Options with attached Selections collection
66+
*
67+
* @return \Magento\Bundle\Model\ResourceModel\Option\Collection
68+
*/
69+
public function getOptions()
70+
{
71+
return $this->bundleOptions->getOptions($this->product);
72+
}
73+
74+
/**
75+
* Get selection amount
76+
*
77+
* @param \Magento\Bundle\Model\Selection $selection
78+
* @return \Magento\Framework\Pricing\Amount\AmountInterface
79+
*/
80+
public function getOptionSelectionAmount($selection)
81+
{
82+
return $this->bundleOptions->getOptionSelectionAmount(
83+
$this->product,
84+
$selection,
85+
true
86+
);
87+
}
88+
89+
/**
90+
* Get minimal amount of bundle price with options
91+
*
92+
* @return \Magento\Framework\Pricing\Amount\AmountInterface
93+
*/
94+
public function getAmount()
95+
{
96+
return $this->calculator->getOptionsAmount($this->product);
97+
}
98+
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Bundle\Pricing\Price;
9+
10+
/**
11+
* Bundle option price calculation model.
12+
*/
13+
class BundleOptions
14+
{
15+
/**
16+
* @var \Magento\Bundle\Pricing\Adjustment\BundleCalculatorInterface
17+
*/
18+
private $calculator;
19+
20+
/**
21+
* @var BundleSelectionFactory
22+
*/
23+
private $selectionFactory;
24+
25+
/**
26+
* @var \Magento\Framework\Pricing\Amount\AmountInterface[]
27+
*/
28+
private $optionSelectionAmountCache = [];
29+
30+
/**
31+
* @param \Magento\Bundle\Pricing\Adjustment\BundleCalculatorInterface $calculator
32+
* @param BundleSelectionFactory $bundleSelectionFactory
33+
*/
34+
public function __construct(
35+
\Magento\Bundle\Pricing\Adjustment\BundleCalculatorInterface $calculator,
36+
BundleSelectionFactory $bundleSelectionFactory
37+
) {
38+
$this->calculator = $calculator;
39+
$this->selectionFactory = $bundleSelectionFactory;
40+
}
41+
42+
/**
43+
* Get Options with attached Selections collection
44+
*
45+
* @param \Magento\Framework\Pricing\SaleableInterface $bundleProduct
46+
* @return \Magento\Bundle\Model\ResourceModel\Option\Collection
47+
*/
48+
public function getOptions(\Magento\Framework\Pricing\SaleableInterface $bundleProduct)
49+
{
50+
/** @var \Magento\Bundle\Model\Product\Type $typeInstance */
51+
$typeInstance = $bundleProduct->getTypeInstance();
52+
$typeInstance->setStoreFilter($bundleProduct->getStoreId(), $bundleProduct);
53+
54+
/** @var \Magento\Bundle\Model\ResourceModel\Option\Collection $optionCollection */
55+
$optionCollection = $typeInstance->getOptionsCollection($bundleProduct);
56+
57+
/** @var \Magento\Bundle\Model\ResourceModel\Selection\Collection $selectionCollection */
58+
$selectionCollection = $typeInstance->getSelectionsCollection(
59+
$typeInstance->getOptionsIds($bundleProduct),
60+
$bundleProduct
61+
);
62+
63+
$priceOptions = $optionCollection->appendSelections($selectionCollection, true, false);
64+
return $priceOptions;
65+
}
66+
67+
/**
68+
* Calculate maximal or minimal options value
69+
*
70+
* @param \Magento\Framework\Pricing\SaleableInterface $bundleProduct
71+
* @param bool $searchMin
72+
* @return float
73+
*/
74+
public function calculateOptions(
75+
\Magento\Framework\Pricing\SaleableInterface $bundleProduct,
76+
bool $searchMin = true
77+
) {
78+
$priceList = [];
79+
/* @var $option \Magento\Bundle\Model\Option */
80+
foreach ($this->getOptions($bundleProduct) as $option) {
81+
if ($searchMin && !$option->getRequired()) {
82+
continue;
83+
}
84+
/** @var \Magento\Bundle\Pricing\Price\BundleSelectionPrice $selectionPriceList */
85+
$selectionPriceList = $this->calculator->createSelectionPriceList($option, $bundleProduct);
86+
$selectionPriceList = $this->calculator->processOptions($option, $selectionPriceList, $searchMin);
87+
$priceList = array_merge($priceList, $selectionPriceList);
88+
}
89+
$amount = $this->calculator->calculateBundleAmount(0., $bundleProduct, $priceList);
90+
return $amount->getValue();
91+
}
92+
93+
/**
94+
* Get selection amount
95+
*
96+
* @param \Magento\Catalog\Model\Product $bundleProduct
97+
* @param \Magento\Bundle\Model\Selection $selection
98+
* @param bool $useRegularPrice
99+
* @return \Magento\Framework\Pricing\Amount\AmountInterface
100+
*/
101+
public function getOptionSelectionAmount(
102+
\Magento\Catalog\Model\Product $bundleProduct,
103+
$selection,
104+
bool $useRegularPrice = false
105+
) {
106+
$cacheKey = implode(
107+
'_',
108+
[
109+
$bundleProduct->getId(),
110+
$selection->getOptionId(),
111+
$selection->getSelectionId(),
112+
$useRegularPrice ? 1 : 0
113+
]
114+
);
115+
116+
if (!isset($this->optionSelectionAmountCache[$cacheKey])) {
117+
$selectionPrice = $this->selectionFactory
118+
->create(
119+
$bundleProduct,
120+
$selection,
121+
$selection->getSelectionQty(),
122+
['useRegularPrice' => $useRegularPrice]
123+
);
124+
$this->optionSelectionAmountCache[$cacheKey] = $selectionPrice->getAmount();
125+
}
126+
127+
return $this->optionSelectionAmountCache[$cacheKey];
128+
}
129+
}

0 commit comments

Comments
 (0)