Skip to content

Commit 01a7159

Browse files
committed
MC-35065: Catalog pricerules are not working with custom options as expected in Magento 2.3.0 product details page
1 parent a8e07e9 commit 01a7159

File tree

7 files changed

+71
-46
lines changed

7 files changed

+71
-46
lines changed

app/code/Magento/Catalog/Block/Product/View/Options/AbstractOptions.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ public function getOption()
124124
* Retrieve formatted price
125125
*
126126
* @return string
127+
* @since 102.0.6
127128
*/
128129
public function getFormattedPrice()
129130
{
@@ -143,7 +144,7 @@ public function getFormattedPrice()
143144
*
144145
* @return string
145146
*
146-
* @deprecated
147+
* @deprecated 102.0.6
147148
* @see getFormattedPrice()
148149
*/
149150
public function getFormatedPrice()
@@ -175,11 +176,14 @@ protected function _formatPrice($value, $flag = true)
175176
$customOptionPrice = $this->getProduct()->getPriceInfo()->getPrice('custom_option_price');
176177

177178
if (!$value['is_percent']) {
178-
$value['pricing_value'] = $this->calculateCustomOptionCatalogRule->execute(
179+
$catalogPriceValue = $this->calculateCustomOptionCatalogRule->execute(
179180
$this->getProduct(),
180181
(float)$value['pricing_value'],
181182
(bool)$value['is_percent']
182183
);
184+
if ($catalogPriceValue!==null) {
185+
$value['pricing_value'] = $catalogPriceValue;
186+
}
183187
}
184188

185189
$context = [CustomOptionPriceInterface::CONFIGURATION_OPTION_FLAG => true];

app/code/Magento/Catalog/Model/Product/Option.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Magento\Catalog\Model\Product\Option\Type\Text;
1919
use Magento\Catalog\Model\Product\Option\Value;
2020
use Magento\Catalog\Model\ResourceModel\Product\Option\Value\Collection;
21+
use Magento\Catalog\Pricing\Price\BasePrice;
2122
use Magento\Catalog\Pricing\Price\CalculateCustomOptionCatalogRule;
2223
use Magento\Framework\App\ObjectManager;
2324
use Magento\Framework\EntityManager\MetadataPool;
@@ -473,12 +474,18 @@ public function afterSave()
473474
*/
474475
public function getPrice($flag = false)
475476
{
476-
if ($flag) {
477-
return $this->calculateCustomOptionCatalogRule->execute(
477+
if ($flag && $this->getPriceType() == self::$typePercent) {
478+
$price = $this->calculateCustomOptionCatalogRule->execute(
478479
$this->getProduct(),
479480
(float)$this->getData(self::KEY_PRICE),
480481
$this->getPriceType() === Value::TYPE_PERCENT
481482
);
483+
484+
if ($price == null) {
485+
$basePrice = $this->getProduct()->getPriceInfo()->getPrice(BasePrice::PRICE_CODE)->getValue();
486+
$price = $basePrice * ($this->_getData(self::KEY_PRICE) / 100);
487+
}
488+
return $price;
482489
}
483490
return $this->_getData(self::KEY_PRICE);
484491
}

app/code/Magento/Catalog/Model/Product/Option/Type/DefaultType.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,11 +352,20 @@ public function getOptionPrice($optionValue, $basePrice)
352352
{
353353
$option = $this->getOption();
354354

355-
return $this->calculateCustomOptionCatalogRule->execute(
355+
$catalogPriceValue = $this->calculateCustomOptionCatalogRule->execute(
356356
$option->getProduct(),
357357
(float)$option->getPrice(),
358358
$option->getPriceType() === Value::TYPE_PERCENT
359359
);
360+
if ($catalogPriceValue!==null) {
361+
return $catalogPriceValue;
362+
} else {
363+
return $this->_getChargeableOptionPrice(
364+
$option->getPrice(),
365+
$option->getPriceType() == 'percent',
366+
$basePrice
367+
);
368+
}
360369
}
361370

362371
/**

app/code/Magento/Catalog/Model/Product/Option/Type/Select.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,11 +260,20 @@ public function getOptionPrice($optionValue, $basePrice)
260260
foreach (explode(',', $optionValue) as $value) {
261261
$_result = $option->getValueById($value);
262262
if ($_result) {
263-
$result += $this->calculateCustomOptionCatalogRule->execute(
263+
$catalogPriceValue = $this->calculateCustomOptionCatalogRule->execute(
264264
$option->getProduct(),
265265
(float)$_result->getPrice(),
266266
$_result->getPriceType() === Value::TYPE_PERCENT
267267
);
268+
if ($catalogPriceValue!==null) {
269+
$result += $catalogPriceValue;
270+
} else {
271+
$result += $this->_getChargeableOptionPrice(
272+
$_result->getPrice(),
273+
$_result->getPriceType() == 'percent',
274+
$basePrice
275+
);
276+
}
268277
} else {
269278
if ($this->getListener()) {
270279
$this->getListener()->setHasError(true)->setMessage($this->_getWrongConfigurationMessage());
@@ -275,11 +284,20 @@ public function getOptionPrice($optionValue, $basePrice)
275284
} elseif ($this->_isSingleSelection()) {
276285
$_result = $option->getValueById($optionValue);
277286
if ($_result) {
278-
$result = $this->calculateCustomOptionCatalogRule->execute(
287+
$catalogPriceValue = $this->calculateCustomOptionCatalogRule->execute(
279288
$option->getProduct(),
280289
(float)$_result->getPrice(),
281290
$_result->getPriceType() === Value::TYPE_PERCENT
282291
);
292+
if ($catalogPriceValue !== null) {
293+
$result = $catalogPriceValue;
294+
} else {
295+
$result = $this->_getChargeableOptionPrice(
296+
$_result->getPrice(),
297+
$_result->getPriceType() == 'percent',
298+
$basePrice
299+
);
300+
}
283301
} else {
284302
if ($this->getListener()) {
285303
$this->getListener()->setHasError(true)->setMessage($this->_getWrongConfigurationMessage());

app/code/Magento/Catalog/Model/Product/Option/Value.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,11 +264,16 @@ public function saveValues()
264264
public function getPrice($flag = false)
265265
{
266266
if ($flag) {
267-
return $this->calculateCustomOptionCatalogRule->execute(
267+
$catalogPriceValue = $this->calculateCustomOptionCatalogRule->execute(
268268
$this->getProduct(),
269269
(float)$this->getData(self::KEY_PRICE),
270270
$this->getPriceType() === self::TYPE_PERCENT
271271
);
272+
if ($catalogPriceValue!==null) {
273+
return $catalogPriceValue;
274+
} else {
275+
return $this->customOptionPriceCalculator->getOptionPriceByPriceCode($this, BasePrice::PRICE_CODE);
276+
}
272277
}
273278
return $this->_getData(self::KEY_PRICE);
274279
}

app/code/Magento/Catalog/Pricing/Price/CalculateCustomOptionCatalogRule.php

Lines changed: 5 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99

1010
use Magento\Catalog\Model\Product;
1111
use Magento\Catalog\Model\Product\PriceModifierInterface;
12-
use Magento\CatalogRule\Pricing\Price\CatalogRulePrice;
13-
use Magento\Framework\Pricing\Price\BasePriceProviderInterface;
1412
use Magento\Framework\Pricing\PriceCurrencyInterface;
1513

1614
/**
@@ -29,6 +27,7 @@ class CalculateCustomOptionCatalogRule
2927
private $priceModifier;
3028

3129
/**
30+
* CalculateCustomOptionCatalogRule constructor.
3231
* @param PriceCurrencyInterface $priceCurrency
3332
* @param PriceModifierInterface $priceModifier
3433
*/
@@ -46,13 +45,13 @@ public function __construct(
4645
* @param Product $product
4746
* @param float $optionPriceValue
4847
* @param bool $isPercent
49-
* @return float
48+
* @return float|null
5049
*/
5150
public function execute(
5251
Product $product,
5352
float $optionPriceValue,
5453
bool $isPercent
55-
): float {
54+
) {
5655
$regularPrice = (float)$product->getPriceInfo()
5756
->getPrice(RegularPrice::PRICE_CODE)
5857
->getValue();
@@ -68,39 +67,9 @@ public function execute(
6867
$product
6968
);
7069
$finalOptionPrice = $totalCatalogRulePrice - $catalogRulePrice;
71-
} else {
72-
$finalOptionPrice = $this->getOptionPriceWithoutPriceRule(
73-
$optionPriceValue,
74-
$isPercent,
75-
$this->getGetBasePriceWithOutCatalogRules($product)
76-
);
77-
}
78-
79-
return $this->priceCurrency->convertAndRound($finalOptionPrice);
80-
}
81-
82-
/**
83-
* Get product base price without catalog rules applied.
84-
*
85-
* @param Product $product
86-
* @return float
87-
*/
88-
private function getGetBasePriceWithOutCatalogRules(Product $product): float
89-
{
90-
$basePrice = null;
91-
foreach ($product->getPriceInfo()->getPrices() as $price) {
92-
if ($price instanceof BasePriceProviderInterface
93-
&& $price->getPriceCode() !== CatalogRulePrice::PRICE_CODE
94-
&& $price->getValue() !== false
95-
) {
96-
$basePrice = min(
97-
$price->getValue(),
98-
$basePrice ?? $price->getValue()
99-
);
100-
}
70+
return $this->priceCurrency->convertAndRound($finalOptionPrice);
10171
}
102-
103-
return $basePrice ?? $product->getPrice();
72+
return null;
10473
}
10574

10675
/**

app/code/Magento/CatalogRule/Test/Mftf/Test/ApplyCatalogRuleForSimpleProductsWithCustomOptionsTest.xml

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
</annotations>
2121
<before>
2222
<!-- Login as Admin -->
23-
<actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/>
2423
<createData entity="_defaultCategory" stepKey="createCategory"/>
2524
<createData entity="_defaultProduct" stepKey="createProduct1">
2625
<requiredEntity createDataKey="createCategory"/>
@@ -39,7 +38,7 @@
3938
<updateData createDataKey="createProduct1" entity="productWithCustomOptions" stepKey="updateProductWithOptions1"/>
4039
<updateData createDataKey="createProduct2" entity="productWithCustomOptions" stepKey="updateProductWithOptions2"/>
4140
<updateData createDataKey="createProduct3" entity="productWithCustomOptions" stepKey="updateProductWithOptions3"/>
42-
<magentoCron stepKey="runCronIndex" groups="index"/>
41+
<actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/>
4342
</before>
4443
<after>
4544
<!-- Delete products and category -->
@@ -55,6 +54,13 @@
5554
<argument name="searchInput" value="{{AdminSecondaryGridSection.catalogRuleIdentifierSearch}}"/>
5655
</actionGroup>
5756

57+
<actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindexAdterTest">
58+
<argument name="indices" value=""/>
59+
</actionGroup>
60+
<actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCacheAfterTest">
61+
<argument name="tags" value=""/>
62+
</actionGroup>
63+
5864
<!-- Logout -->
5965
<actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/>
6066
</after>
@@ -71,6 +77,13 @@
7177
<click selector="{{AdminNewCatalogPriceRule.save}}" stepKey="clickSave"/>
7278
<waitForPageLoad stepKey="waitForSave"/>
7379

80+
<actionGroup ref="CliIndexerReindexActionGroup" stepKey="reindex">
81+
<argument name="indices" value=""/>
82+
</actionGroup>
83+
<actionGroup ref="CliCacheFlushActionGroup" stepKey="flushCache">
84+
<argument name="tags" value=""/>
85+
</actionGroup>
86+
7487
<!-- Navigate to category on store front -->
7588
<amOnPage url="{{StorefrontProductPage.url($createCategory.name$)}}" stepKey="goToCategoryPage"/>
7689

0 commit comments

Comments
 (0)