Skip to content

Commit 7f4a6df

Browse files
authored
Merge pull request #1430 from algolia/update/MAGE-758
MAGE-758 Special price range for configurable products
2 parents 1f4dc4b + 4fb2e51 commit 7f4a6df

File tree

3 files changed

+99
-24
lines changed

3 files changed

+99
-24
lines changed

Helper/Entity/Product/PriceManager/Configurable.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,18 @@ class Configurable extends ProductWithChildren
99
/**
1010
* @param $groupId
1111
* @param $product
12+
* @param $subProducts
1213
* @return float|int|mixed
1314
*/
14-
protected function getRulePrice($groupId, $product)
15+
protected function getRulePrice($groupId, $product, $subProducts)
1516
{
1617
$childrenPrices = [];
17-
/** @var \Magento\ConfigurableProduct\Model\Product\Type\Configurable $typeInstance */
1818
$typeInstance = $product->getTypeInstance();
19-
$children = $typeInstance->getUsedProducts($product);
20-
foreach ($children as $child) {
19+
if (!$typeInstance instanceof \Magento\ConfigurableProduct\Model\Product\Type\Configurable) {
20+
return parent::getRulePrice($groupId, $product, $subProducts);
21+
}
22+
23+
foreach ($subProducts as $child) {
2124
$childrenPrices[] = (float) $this->rule->getRulePrice(
2225
new DateTime(),
2326
$this->store->getWebsiteId(),

Helper/Entity/Product/PriceManager/ProductWithChildren.php

100644100755
Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,6 @@ protected function addAdditionalData($product, $withTax, $subProducts, $currency
2626
$this->handleOriginalPrice($field, $currencyCode, $min, $max, $minOriginal, $maxOriginal);
2727
if (!$this->customData[$field][$currencyCode]['default']) {
2828
$this->handleZeroDefaultPrice($field, $currencyCode, $min, $max);
29-
# need to rehandle specialPrice
30-
$specialPrice = $this->getSpecialPrice($product, $currencyCode, $withTax);
31-
$this->addSpecialPrices($specialPrice, $field, $currencyCode);
3229
}
3330
if ($this->areCustomersGroupsEnabled) {
3431
$this->setFinalGroupPrices($field, $currencyCode, $min, $max, $dashedFormat, $product, $subProducts, $withTax);
@@ -51,7 +48,14 @@ protected function getMinMaxPrices(Product $product, $withTax, $subProducts, $cu
5148
if (count($subProducts) > 0) {
5249
/** @var Product $subProduct */
5350
foreach ($subProducts as $subProduct) {
54-
$price = $this->getTaxPrice($product, $subProduct->getFinalPrice(), $withTax);
51+
$specialPrice = $this->getSpecialPrice($subProduct, $currencyCode, $withTax, $subProducts);
52+
$tierPrice = $this->getTierPrice($subProduct, $currencyCode, $withTax);
53+
if (!empty($tierPrice[0]) && $specialPrice[0] > $tierPrice[0]){
54+
$minPrice = $tierPrice[0];
55+
} else {
56+
$minPrice = $specialPrice[0];
57+
}
58+
$price = $minPrice ?? $this->getTaxPrice($product, $subProduct->getFinalPrice(), $withTax);
5559
$basePrice = $this->getTaxPrice($product, $subProduct->getPrice(), $withTax);
5660
$min = min($min, $price);
5761
$original = min($original, $basePrice);
@@ -153,28 +157,32 @@ protected function handleZeroDefaultPrice($field, $currencyCode, $min, $max)
153157
protected function setFinalGroupPrices($field, $currencyCode, $min, $max, $dashedFormat, $product, $subproducts, $withTax)
154158
{
155159
if (count($subproducts) > 0) {
156-
$array = [];
160+
$groupPriceList = [];
157161
/** @var Group $group */
158162
foreach ($this->groups as $group) {
159163
$groupId = (int) $group->getData('customer_group_id');
164+
$minPrice = $min;
160165
foreach ($subproducts as $subProduct) {
161166
$subProduct->setData('customer_group_id', $groupId);
162167
$subProduct->setData('website_id', $subProduct->getStore()->getWebsiteId());
168+
$specialPrice = $this->getSpecialPrice($subProduct, $currencyCode, $withTax, []);
169+
$tierPrice = $this->getTierPrice($subProduct, $currencyCode, $withTax);
163170
$price = $this->getTaxPrice($product, $subProduct->getPriceModel()->getFinalPrice(1, $subProduct), $withTax);
164-
$array[$groupId][] = $price;
171+
if (!empty($tierPrice[$groupId]) && $specialPrice[$groupId] > $tierPrice[$groupId]){
172+
$minPrice = $tierPrice[$groupId];
173+
}
174+
$groupPriceList[$groupId]['min'] = min($minPrice, $price);
175+
$groupPriceList[$groupId]['max'] = max($max, $price);
165176
$subProduct->setData('customer_group_id', null);
166177
}
167178
}
179+
168180
$minArray = [];
169-
foreach ($array as $key => $value) {
170-
$minArray[$key]['price'] = min($value);
171-
$price = min($value);
172-
$formattedPrice = $this->formatPrice($price, $currencyCode);
173-
$minArray[$key]['formatted'] = $formattedPrice;
181+
foreach ($groupPriceList as $key => $value) {
182+
$minArray[$key]['price'] = $value['min'];
183+
$minArray[$key]['formatted'] = $this->formattedConfigPrice($value['min'], $value['max'], $currencyCode);
174184
if ($currencyCode !== $this->baseCurrencyCode) {
175-
$min = $this->convertPrice($price, $currencyCode);
176-
$formattedPrice = $this->formatPrice($min, $currencyCode);
177-
$minArray[$key]['formatted'] = strval($formattedPrice);
185+
$minArray[$key]['formatted'] = $this->formattedConfigPrice($value['min'], $value['max'], $currencyCode);
178186
}
179187
}
180188
/** @var Group $group */
@@ -200,6 +208,20 @@ protected function setFinalGroupPrices($field, $currencyCode, $min, $max, $dashe
200208
}
201209
}
202210

211+
/**
212+
* @param $min
213+
* @param $max
214+
* @param $currencyCode
215+
* @return mixed|string
216+
*/
217+
public function formattedConfigPrice($min, $max, $currencyCode) {
218+
if ($min != $max) {
219+
return $this->getDashedPriceFormat($min, $max, $currencyCode);
220+
} else {
221+
return $this->formatPrice($min, $currencyCode);
222+
}
223+
}
224+
203225
/**
204226
* @param $field
205227
* @param $currencyCode
@@ -219,11 +241,13 @@ public function handleOriginalPrice($field, $currencyCode, $min, $max, $minOrigi
219241
$maxOriginal,
220242
$currencyCode
221243
);
244+
$this->handleGroupOrginalPriceformated($field, $currencyCode, $this->customData[$field][$currencyCode]['default_original_formated']);
222245
} else {
223246
$this->customData[$field][$currencyCode]['default_original_formated'] = $this->formatPrice(
224247
$minOriginal,
225248
$currencyCode
226249
);
250+
$this->handleGroupOrginalPriceformated($field, $currencyCode, $this->customData[$field][$currencyCode]['default_original_formated']);
227251
}
228252
}
229253
} else {
@@ -232,6 +256,25 @@ public function handleOriginalPrice($field, $currencyCode, $min, $max, $minOrigi
232256
$minOriginal,
233257
$currencyCode
234258
);
259+
$this->handleGroupOrginalPriceformated($field, $currencyCode, $this->customData[$field][$currencyCode]['default_original_formated']);
260+
}
261+
}
262+
263+
}
264+
265+
/**
266+
* @param $field
267+
* @param $currencyCode
268+
* @param $formatedPrice
269+
* @return void
270+
*/
271+
public function handleGroupOrginalPriceformated($field, $currencyCode, $formatedPrice) {
272+
if ($this->areCustomersGroupsEnabled) {
273+
/** @var Group $group */
274+
foreach ($this->groups as $group) {
275+
$groupId = (int)$group->getData('customer_group_id');
276+
$this->customData[$field][$currencyCode]['group_' . $groupId . '_original_formated'] =
277+
$formatedPrice;
235278
}
236279
}
237280
}

Helper/Entity/Product/PriceManager/ProductWithoutChildren.php

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Magento\Framework\Pricing\PriceCurrencyInterface;
1515
use Magento\Tax\Helper\Data as TaxHelper;
1616
use Magento\Tax\Model\Config as TaxConfig;
17+
use Magento\Catalog\Api\ScopedProductTierPriceManagementInterface;
1718

1819
abstract class ProductWithoutChildren
1920
{
@@ -46,6 +47,11 @@ abstract class ProductWithoutChildren
4647
*/
4748
protected $productloader;
4849

50+
/**
51+
* @var ScopedProductTierPriceManagementInterface
52+
*/
53+
private $productTierPrice;
54+
4955
protected $store;
5056
protected $baseCurrencyCode;
5157
protected $groups;
@@ -60,6 +66,7 @@ abstract class ProductWithoutChildren
6066
* @param TaxHelper $taxHelper
6167
* @param Rule $rule
6268
* @param ProductFactory $productloader
69+
* @param ScopedProductTierPriceManagementInterface $productTierPrice
6370
*/
6471
public function __construct(
6572
ConfigHelper $configHelper,
@@ -68,7 +75,8 @@ public function __construct(
6875
CatalogHelper $catalogHelper,
6976
TaxHelper $taxHelper,
7077
Rule $rule,
71-
ProductFactory $productloader
78+
ProductFactory $productloader,
79+
ScopedProductTierPriceManagementInterface $productTierPrice
7280
) {
7381
$this->configHelper = $configHelper;
7482
$this->customerGroupCollectionFactory = $customerGroupCollectionFactory;
@@ -77,6 +85,7 @@ public function __construct(
7785
$this->taxHelper = $taxHelper;
7886
$this->rule = $rule;
7987
$this->productloader = $productloader;
88+
$this->productTierPrice = $productTierPrice;
8089
}
8190

8291
/**
@@ -110,7 +119,7 @@ public function addPriceData($customData, Product $product, $subProducts): array
110119
$price = $this->getTaxPrice($product, $price, $withTax);
111120
$this->customData[$field][$currencyCode]['default'] = $this->priceCurrency->round($price);
112121
$this->customData[$field][$currencyCode]['default_formated'] = $this->formatPrice($price, $currencyCode);
113-
$specialPrice = $this->getSpecialPrice($product, $currencyCode, $withTax);
122+
$specialPrice = $this->getSpecialPrice($product, $currencyCode, $withTax, $subProducts);
114123
$tierPrice = $this->getTierPrice($product, $currencyCode, $withTax);
115124
if ($this->areCustomersGroupsEnabled) {
116125
$this->addCustomerGroupsPrices($product, $currencyCode, $withTax, $field);
@@ -202,16 +211,17 @@ public function getTaxPrice($product, $amount, $withTax): float
202211
* @param Product $product
203212
* @param $currencyCode
204213
* @param $withTax
214+
* @param $subProducts
205215
* @return array
206216
*/
207-
protected function getSpecialPrice(Product $product, $currencyCode, $withTax): array
217+
protected function getSpecialPrice(Product $product, $currencyCode, $withTax, $subProducts): array
208218
{
209219
$specialPrice = [];
210220
/** @var Group $group */
211221
foreach ($this->groups as $group) {
212222
$groupId = (int) $group->getData('customer_group_id');
213223
$specialPrices[$groupId] = [];
214-
$specialPrices[$groupId][] = $this->getRulePrice($groupId, $product);
224+
$specialPrices[$groupId][] = $this->getRulePrice($groupId, $product, $subProducts);
215225
// The price with applied catalog rules
216226
$specialPrices[$groupId][] = $product->getFinalPrice(); // The product's special price
217227
$specialPrices[$groupId] = array_filter($specialPrices[$groupId], function ($price) {
@@ -243,7 +253,7 @@ protected function getTierPrice(Product $product, $currencyCode, $withTax)
243253
$tierPrice = [];
244254
$tierPrices = [];
245255

246-
if (!is_null($product->getTierPrices())) {
256+
if (!empty($product->getTierPrices())) {
247257
$product->setData('website_id', $product->getStore()->getWebsiteId());
248258
$productTierPrices = $product->getTierPrices();
249259
foreach ($productTierPrices as $productTierPrice) {
@@ -258,6 +268,24 @@ protected function getTierPrice(Product $product, $currencyCode, $withTax)
258268
$productTierPrice->getValue()
259269
);
260270
}
271+
} else {
272+
/** @var Group $group */
273+
foreach ($this->groups as $group) {
274+
$customerGroupId = (int) $group->getData('customer_group_id');
275+
$productTierPrices = $this->productTierPrice->getList($product->getSku(), $customerGroupId);
276+
if(!empty($productTierPrices)) {
277+
foreach ($productTierPrices as $productTierPrice) {
278+
if (!isset($tierPrices[$productTierPrice->getCustomerGroupId()])) {
279+
$tierPrices[$productTierPrice->getCustomerGroupId()] = $productTierPrice->getValue();
280+
continue;
281+
}
282+
$tierPrices[$productTierPrice->getCustomerGroupId()] = min(
283+
$tierPrices[$productTierPrice->getCustomerGroupId()],
284+
$productTierPrice->getValue()
285+
);
286+
}
287+
}
288+
}
261289
}
262290

263291
/** @var Group $group */
@@ -325,9 +353,10 @@ protected function addTierPrices($tierPrice, $field, $currencyCode)
325353
/**
326354
* @param $groupId
327355
* @param $product
356+
* @param $subProducts
328357
* @return float
329358
*/
330-
protected function getRulePrice($groupId, $product)
359+
protected function getRulePrice($groupId, $product, $subProducts)
331360
{
332361
return (float) $this->rule->getRulePrice(
333362
new DateTime(),

0 commit comments

Comments
 (0)