Skip to content

Commit 245e51a

Browse files
committed
Merge remote-tracking branch 'origin/AC-10847-V2' into spartans_pr_29082025
2 parents b11dd0b + 28550dd commit 245e51a

File tree

1 file changed

+61
-14
lines changed

1 file changed

+61
-14
lines changed

app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurableRegularPrice.php

Lines changed: 61 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2015 Adobe
4+
* All Rights Reserved.
55
*/
66

77
namespace Magento\ConfigurableProduct\Pricing\Price;
@@ -60,6 +60,11 @@ class ConfigurableRegularPrice extends AbstractPrice implements
6060
*/
6161
private $configurableMaxPriceCalculator;
6262

63+
/**
64+
* @var array<int, bool>
65+
*/
66+
private $equalFinalPriceCache = [];
67+
6368
/**
6469
* @param \Magento\Framework\Pricing\SaleableInterface $saleableItem
6570
* @param float $quantity
@@ -193,29 +198,71 @@ private function getConfigurableOptionsProvider()
193198
public function _resetState(): void
194199
{
195200
$this->values = [];
201+
$this->equalFinalPriceCache = [];
196202
}
197203

198204
/**
199205
* Check whether Configurable Product have more than one children products
200206
*
201207
* @param SaleableInterface $product
202208
* @return bool
209+
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
210+
* @SuppressWarnings(PHPMD.NPathComplexity)
203211
*/
204212
public function isChildProductsOfEqualPrices(SaleableInterface $product): bool
205213
{
206-
$minPrice = $this->getMinRegularAmount()->getValue();
207-
$final_price = $product->getFinalPrice();
208-
$productId = $product->getId();
209-
if ($final_price < $minPrice) {
210-
return false;
214+
$storeId = (int) ($product->getStoreId() ?: 0);
215+
$cacheKey = (int) $product->getId() . ':' . $storeId;
216+
if (isset($this->equalFinalPriceCache[$cacheKey])) {
217+
return $this->equalFinalPriceCache[$cacheKey];
218+
}
219+
220+
$memoKey = '_children_final_prices_equal_store_' . $storeId;
221+
$memoized = $product->getData($memoKey);
222+
if ($memoized !== null) {
223+
return (bool) $memoized;
224+
}
225+
226+
// Listing fast-path: if index fields are present, rely on them and avoid any child loading
227+
$minIndexed = $product->getData('minimal_price');
228+
$maxIndexed = $product->getData('max_price');
229+
if (is_numeric($minIndexed) && is_numeric($maxIndexed)) {
230+
$result = ((float)$minIndexed === (float)$maxIndexed);
231+
$this->equalFinalPriceCache[$cacheKey] = $result;
232+
$product->setData($memoKey, $result);
233+
return $result;
211234
}
212-
$attributes = $product->getTypeInstance()->getConfigurableAttributes($product);
213-
$items = $attributes->getItems();
214-
$options = reset($items);
215-
$maxPrice = $this->configurableMaxPriceCalculator->getMaxPriceForConfigurableProduct($productId);
216-
if ($maxPrice == 0) {
217-
$maxPrice = $this->getMaxRegularAmount()->getValue();
235+
236+
$children = $product->getTypeInstance()->getUsedProducts($product);
237+
$firstFinal = null;
238+
$saleableChildrenCount = 0;
239+
$allEqual = true;
240+
foreach ($children as $child) {
241+
if (!$child->isSalable()) {
242+
continue;
243+
}
244+
$saleableChildrenCount++;
245+
$value = $child->getPriceInfo()->getPrice('final_price')->getAmount()->getValue();
246+
if ($firstFinal === null) {
247+
$firstFinal = $value;
248+
continue;
249+
}
250+
if ($value != $firstFinal) {
251+
$allEqual = false;
252+
break;
253+
}
218254
}
219-
return (count($options->getOptions()) > 1) && $minPrice == $maxPrice;
255+
256+
if ($saleableChildrenCount <= 1 || $firstFinal === null || !$allEqual) {
257+
$product->setData($memoKey, false);
258+
$this->equalFinalPriceCache[$cacheKey] = false;
259+
return false;
260+
}
261+
262+
// Guard against parent-level extra discounts (compute only when children are equal)
263+
$result = !($product->getFinalPrice() < $firstFinal);
264+
$this->equalFinalPriceCache[$cacheKey] = $result;
265+
$product->setData($memoKey, $result);
266+
return $result;
220267
}
221268
}

0 commit comments

Comments
 (0)