Skip to content

Commit 3ebda94

Browse files
LYNX_387: Fix bundle original_row_total field (#238)
1 parent d3057b6 commit 3ebda94

File tree

4 files changed

+911
-0
lines changed

4 files changed

+911
-0
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
<?php
2+
/************************************************************************
3+
*
4+
* Copyright 2024 Adobe
5+
* All Rights Reserved.
6+
*
7+
* NOTICE: All information contained herein is, and remains
8+
* the property of Adobe and its suppliers, if any. The intellectual
9+
* and technical concepts contained herein are proprietary to Adobe
10+
* and its suppliers and are protected by all applicable intellectual
11+
* property laws, including trade secret and copyright laws.
12+
* Dissemination of this information or reproduction of this material
13+
* is strictly forbidden unless prior written permission is obtained
14+
* from Adobe.
15+
* ************************************************************************
16+
*/
17+
declare(strict_types=1);
18+
19+
namespace Magento\Bundle\Model\Product;
20+
21+
use Magento\Catalog\Model\Product;
22+
use Magento\Framework\Serialize\Serializer\Json;
23+
24+
/**
25+
* Get original price for bundle products
26+
*/
27+
class OriginalPrice
28+
{
29+
/**
30+
* @param Json $serializer
31+
*/
32+
public function __construct(private readonly Json $serializer)
33+
{
34+
}
35+
36+
/**
37+
* Get Original Total price for Bundle items
38+
*
39+
* @param Product $product
40+
* @return float
41+
*/
42+
public function getTotalBundleItemsOriginalPrice(Product $product): float
43+
{
44+
$price = 0.0;
45+
46+
if (!$product->hasCustomOptions()) {
47+
return $price;
48+
}
49+
50+
$selectionIds = $this->getBundleSelectionIds($product);
51+
52+
if (empty($selectionIds)) {
53+
return $price;
54+
}
55+
56+
$selections = $product->getTypeInstance()->getSelectionsByIds($selectionIds, $product);
57+
foreach ($selections->getItems() as $selection) {
58+
if (!$selection->isSalable()) {
59+
continue;
60+
}
61+
62+
$selectionQty = $product->getCustomOption('selection_qty_' . $selection->getSelectionId());
63+
if ($selectionQty) {
64+
$price += $this->getSelectionOriginalTotalPrice(
65+
$product,
66+
$selection,
67+
(float) $selectionQty->getValue()
68+
);
69+
}
70+
}
71+
72+
return $price;
73+
}
74+
75+
/**
76+
* Calculate total original price of selection
77+
*
78+
* @param Product $bundleProduct
79+
* @param Product $selectionProduct
80+
* @param float $selectionQty
81+
*
82+
* @return float
83+
*/
84+
private function getSelectionOriginalTotalPrice(
85+
Product $bundleProduct,
86+
Product $selectionProduct,
87+
float $selectionQty
88+
): float {
89+
$price = $this->getSelectionOriginalPrice($bundleProduct, $selectionProduct);
90+
91+
return $price * $selectionQty;
92+
}
93+
94+
/**
95+
* Calculate the original price of selection
96+
*
97+
* @param Product $bundleProduct
98+
* @param Product $selectionProduct
99+
*
100+
* @return float
101+
*/
102+
public function getSelectionOriginalPrice(Product $bundleProduct, Product $selectionProduct): float
103+
{
104+
if ($bundleProduct->getPriceType() == Price::PRICE_TYPE_DYNAMIC) {
105+
return (float) $selectionProduct->getPrice();
106+
}
107+
if ($selectionProduct->getSelectionPriceType()) {
108+
// percent
109+
return $bundleProduct->getPrice() * ($selectionProduct->getSelectionPriceValue() / 100);
110+
}
111+
112+
// fixed
113+
return (float) $selectionProduct->getSelectionPriceValue();
114+
}
115+
116+
/**
117+
* Retrieve array of bundle selection IDs
118+
*
119+
* @param Product $product
120+
* @return array
121+
*/
122+
private function getBundleSelectionIds(Product $product): array
123+
{
124+
$customOption = $product->getCustomOption('bundle_selection_ids');
125+
if ($customOption) {
126+
$selectionIds = $this->serializer->unserialize($customOption->getValue());
127+
if (is_array($selectionIds)) {
128+
return $selectionIds;
129+
}
130+
}
131+
return [];
132+
}
133+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
/************************************************************************
3+
*
4+
* Copyright 2024 Adobe
5+
* All Rights Reserved.
6+
*
7+
* NOTICE: All information contained herein is, and remains
8+
* the property of Adobe and its suppliers, if any. The intellectual
9+
* and technical concepts contained herein are proprietary to Adobe
10+
* and its suppliers and are protected by all applicable intellectual
11+
* property laws, including trade secret and copyright laws.
12+
* Dissemination of this information or reproduction of this material
13+
* is strictly forbidden unless prior written permission is obtained
14+
* from Adobe.
15+
* ************************************************************************
16+
*/
17+
declare(strict_types=1);
18+
19+
namespace Magento\Bundle\Plugin\Quote;
20+
21+
use Magento\Bundle\Model\Product\OriginalPrice;
22+
use Magento\Bundle\Model\Product\Type;
23+
use Magento\Quote\Model\Quote;
24+
use Magento\Quote\Model\Quote\Address\Total\Subtotal;
25+
use Magento\Quote\Api\Data\ShippingAssignmentInterface;
26+
use Magento\Quote\Model\Quote\Address\Total;
27+
28+
/**
29+
* Update bundle base original price
30+
*/
31+
class UpdateBundleQuoteItemBaseOriginalPrice
32+
{
33+
/**
34+
* @param OriginalPrice $price
35+
*/
36+
public function __construct(
37+
private readonly OriginalPrice $price
38+
) {
39+
}
40+
41+
/**
42+
* Update bundle base original price
43+
*
44+
* @param Subtotal $subject
45+
* @param Subtotal $result
46+
* @param Quote $quote
47+
* @param ShippingAssignmentInterface $shippingAssignment
48+
* @param Total $total
49+
*
50+
* @return Subtotal
51+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
52+
*/
53+
public function afterCollect(
54+
Subtotal $subject,
55+
Subtotal $result,
56+
Quote $quote,
57+
ShippingAssignmentInterface $shippingAssignment,
58+
Total $total
59+
): Subtotal {
60+
foreach ($quote->getAllVisibleItems() as $quoteItem) {
61+
if ($quoteItem->getProductType() === Type::TYPE_CODE) {
62+
$price = $quoteItem->getProduct()->getPrice();
63+
$price += $this->price->getTotalBundleItemsOriginalPrice($quoteItem->getProduct());
64+
$quoteItem->setBaseOriginalPrice($price);
65+
}
66+
}
67+
return $result;
68+
}
69+
}

app/code/Magento/Bundle/etc/di.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,4 +284,9 @@
284284
</argument>
285285
</arguments>
286286
</type>
287+
<type name="Magento\Quote\Model\Quote\Address\Total\Subtotal">
288+
<plugin name="update_bundle_quote_item_base_original_price"
289+
type="Magento\Bundle\Plugin\Quote\UpdateBundleQuoteItemBaseOriginalPrice"
290+
sortOrder="10"/>
291+
</type>
287292
</config>

0 commit comments

Comments
 (0)