Skip to content

Commit 5eb555d

Browse files
authored
LYNX-488: original_row_total field returning wrong value (#283)
1 parent 2a406ec commit 5eb555d

File tree

7 files changed

+954
-14
lines changed

7 files changed

+954
-14
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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\QuoteGraphQl\Model;
20+
21+
use Magento\Catalog\Model\Product\Option;
22+
23+
class GetOptionsRegularPrice
24+
{
25+
/**
26+
* Get product options regular price
27+
*
28+
* @param array $options
29+
* @param Option $productOption
30+
* @return float
31+
*/
32+
public function execute(array $options, Option $productOption): float
33+
{
34+
$price = 0.0;
35+
foreach ($options as $optionValueId) {
36+
$optionValue = $productOption->getValueById($optionValueId);
37+
if ($optionValue) {
38+
$price += $optionValue->getRegularPrice() ?? 0.0;
39+
}
40+
}
41+
return $price;
42+
}
43+
}

app/code/Magento/QuoteGraphQl/Model/Resolver/CartItemPrices.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Magento\Quote\Model\Quote\Item;
1818
use Magento\QuoteGraphQl\Model\Cart\TotalsCollector;
1919
use Magento\QuoteGraphQl\Model\GetDiscounts;
20+
use Magento\QuoteGraphQl\Model\GetOptionsRegularPrice;
2021

2122
/**
2223
* @inheritdoc
@@ -29,14 +30,18 @@ class CartItemPrices implements ResolverInterface, ResetAfterRequestInterface
2930
private $totals;
3031

3132
/**
33+
* CartItemPrices constructor.
34+
*
3235
* @param TotalsCollector $totalsCollector
3336
* @param GetDiscounts $getDiscounts
3437
* @param PriceCurrencyInterface $priceCurrency
38+
* @param GetOptionsRegularPrice $getOptionsRegularPrice
3539
*/
3640
public function __construct(
3741
private readonly TotalsCollector $totalsCollector,
3842
private readonly GetDiscounts $getDiscounts,
39-
private readonly PriceCurrencyInterface $priceCurrency
43+
private readonly PriceCurrencyInterface $priceCurrency,
44+
private readonly GetOptionsRegularPrice $getOptionsRegularPrice
4045
) {
4146
}
4247

@@ -134,10 +139,18 @@ private function getOptionsPrice(Item $cartItem): float
134139
if (!$optionIds) {
135140
return $price;
136141
}
142+
137143
foreach (explode(',', $optionIds->getValue() ?? '') as $optionId) {
138144
$option = $cartItem->getProduct()->getOptionById($optionId);
139-
if ($option) {
145+
$optionValueIds = $cartItem->getOptionByCode('option_' . $optionId);
146+
if (!$option) {
147+
return $price;
148+
}
149+
if ($option->getRegularPrice()) {
140150
$price += $option->getRegularPrice();
151+
} else {
152+
$price += $this->getOptionsRegularPrice
153+
->execute(explode(",", $optionValueIds->getValue()), $option);
141154
}
142155
}
143156

app/code/Magento/SalesGraphQl/Model/OrderItemPrices/PricesProvider.php

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,22 @@
99

1010
use Magento\Framework\Pricing\PriceCurrencyInterface;
1111
use Magento\Sales\Model\Order\Item;
12+
use Magento\QuoteGraphQl\Model\GetOptionsRegularPrice;
1213

1314
/**
1415
* Prices data provider for order item
1516
*/
1617
class PricesProvider
1718
{
1819
/**
20+
* PricesProvider constructor.
21+
*
1922
* @param PriceCurrencyInterface $priceCurrency
23+
* @param GetOptionsRegularPrice $getOptionsRegularPrice
2024
*/
2125
public function __construct(
22-
private readonly PriceCurrencyInterface $priceCurrency
26+
private readonly PriceCurrencyInterface $priceCurrency,
27+
private readonly GetOptionsRegularPrice $getOptionsRegularPrice
2328
) {
2429
}
2530

@@ -117,17 +122,20 @@ private function getOriginalRowTotal(Item $orderItem): float
117122
private function getOptionsPrice(Item $orderItem): float
118123
{
119124
$price = 0.0;
120-
$optionIds = $orderItem->getProduct()->getCustomOption('option_ids');
121-
if (!$optionIds) {
125+
$productOptions = $orderItem->getProductOptions();
126+
if (empty($productOptions['options'])) {
122127
return $price;
123128
}
124-
foreach (explode(',', $optionIds->getValue() ?? '') as $optionId) {
125-
$option = $orderItem->getProduct()->getOptionById($optionId);
126-
if ($option) {
127-
$price += $option->getRegularPrice();
129+
130+
foreach ($productOptions['options'] as $option) {
131+
$productOption = $orderItem->getProduct()->getOptionById($option['option_id']);
132+
if ($productOption->getRegularPrice()) {
133+
$price += $productOption->getRegularPrice();
134+
} elseif (!empty($option['option_value'])) {
135+
$price += $this->getOptionsRegularPrice
136+
->execute(explode(",", $option['option_value']), $productOption);
128137
}
129138
}
130-
131139
return $price;
132140
}
133141
}

app/code/Magento/SalesGraphQl/composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"magento/module-quote": "*",
1313
"magento/module-graph-ql": "*",
1414
"magento/module-shipping": "*",
15-
"magento/module-catalog-graph-ql": "*"
15+
"magento/module-catalog-graph-ql": "*",
16+
"magento/module-quote-graph-ql": "*"
1617
},
1718
"license": [
1819
"OSL-3.0",

dev/tests/api-functional/testsuite/Magento/GraphQl/Quote/ProductsWithCustomOptionsCartPricesTest.php

Lines changed: 147 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,147 @@ public function testProductsWithOneCustomOptionEnteredWithPercentPriceAndOneWith
305305
$this->assertEquals($expectedResponse, $response);
306306
}
307307

308+
#[
309+
DataFixture(GuestCart::class, as: 'quote'),
310+
DataFixture(
311+
Product::class,
312+
[
313+
'sku' => 'simple1',
314+
'price' => 30,
315+
'special_price' => 10,
316+
'options' => [
317+
[
318+
'title' => 'option1',
319+
'type' => ProductCustomOptionInterface::OPTION_TYPE_FIELD,
320+
'price_type' => ProductPriceOptionsInterface::VALUE_PERCENT,
321+
'price' => 10,
322+
'is_require' => false
323+
],
324+
[
325+
'title' => 'option3',
326+
'type' => ProductCustomOptionInterface::OPTION_TYPE_FIELD,
327+
'price' => 0,
328+
'is_require' => false
329+
],
330+
[
331+
'title' => 'dropdown',
332+
'type' => ProductCustomOptionInterface::OPTION_TYPE_DROP_DOWN,
333+
'is_require' => false,
334+
'values' => [
335+
[
336+
'title' => 'option1_value1',
337+
'price' => 10,
338+
'price_type' => ProductPriceOptionsInterface::VALUE_PERCENT,
339+
]
340+
]
341+
],
342+
[
343+
'title' => 'multiple option',
344+
'type' => ProductCustomOptionInterface::OPTION_TYPE_MULTIPLE,
345+
'is_require' => false,
346+
'values' => [
347+
[
348+
'title' => 'multiple option 1',
349+
'price' => 10,
350+
'price_type' => ProductPriceOptionsInterface::VALUE_FIXED,
351+
'sku' => 'multiple option 1 sku',
352+
'sort_order' => 1,
353+
],
354+
[
355+
'title' => 'multiple option 2',
356+
'price' => 20,
357+
'price_type' => ProductPriceOptionsInterface::VALUE_FIXED,
358+
'sku' => 'multiple option 2 sku',
359+
'sort_order' => 2,
360+
],
361+
],
362+
]
363+
]
364+
],
365+
'product'
366+
)
367+
]
368+
public function testCartWithMultipleCustomProductOption()
369+
{
370+
$cart = $this->fixtures->get('quote');
371+
$maskedQuoteId = $this->quoteIdToMaskedQuoteIdInterface->execute((int) $cart->getId());
372+
$product = $this->fixtures->get('product');
373+
$sku = $product->getSku();
374+
375+
$options = $product->getOptions();
376+
377+
$fieldOption1Id = $this->uidEncoder->encode(
378+
'custom-option' . '/' . $options[0]->getData()['option_id']
379+
);
380+
381+
$fieldOption2Id = $this->uidEncoder->encode(
382+
'custom-option' . '/' . $options[1]->getData()['option_id']
383+
);
384+
385+
$productOptions = [];
386+
foreach ($options[2]->getValues() as $value) {
387+
$productOptions[] = [
388+
'uid' => $this->uidEncoder->encode(
389+
'custom-option' . '/' . $options[2]->getData()['option_id'] . '/' . $value->getId()
390+
)
391+
];
392+
}
393+
394+
$dropDownOptionId = $productOptions[0]['uid'];
395+
396+
$productOptions = [];
397+
foreach ($options[3]->getValues() as $value) {
398+
$productOptions[] = [
399+
'uid' => $this->uidEncoder->encode(
400+
'custom-option' . '/' . $options[3]->getData()['option_id'] . '/' . $value->getId()
401+
)
402+
];
403+
}
404+
$multiOptionId = $productOptions[0]['uid'];
405+
$optionIds = json_encode([$dropDownOptionId, $multiOptionId]);
406+
$selectedOptions = "selected_options: {$optionIds}";
407+
$this->graphQlMutation(
408+
$this->addProductWithOptionMutation(
409+
$maskedQuoteId,
410+
2,
411+
$sku,
412+
$fieldOption1Id,
413+
$fieldOption2Id,
414+
$selectedOptions
415+
)
416+
);
417+
418+
$query = $this->getCartQuery($maskedQuoteId);
419+
$response = $this->graphQlQuery($query);
420+
421+
$expectedResponse = [
422+
"cart" => [
423+
"itemsV2" => [
424+
"items" => [
425+
0 => [
426+
"prices" => [
427+
"price" => [
428+
"value" => 22,
429+
"currency" => "USD"
430+
],
431+
"row_total" => [
432+
"value" => 44,
433+
"currency" => "USD"
434+
],
435+
"original_row_total" => [
436+
"value" => 92,
437+
"currency" => "USD"
438+
]
439+
]
440+
]
441+
]
442+
]
443+
]
444+
];
445+
446+
$this->assertEquals($expectedResponse, $response);
447+
}
448+
308449
/**
309450
* Create cart query with prices data
310451
*
@@ -347,23 +488,26 @@ private function getCartQuery(string $maskedQuoteId): string
347488
* @param string $sku
348489
* @param string $optionUid
349490
* @param string $optionUid2
491+
* @param string $selectedOptions
350492
* @return string
351493
*/
352494
private function addProductWithOptionMutation(
353495
string $cartId,
354496
int $qty,
355497
string $sku,
356498
string $optionUid,
357-
string $optionUid2
499+
string $optionUid2,
500+
string $selectedOptions = ''
358501
): string {
359-
return <<<QRY
502+
return <<<MUTATION
360503
mutation {
361504
addProductsToCart(
362505
cartId: "{$cartId}"
363506
cartItems: [
364507
{
365508
quantity: {$qty}
366509
sku: "{$sku}"
510+
$selectedOptions
367511
entered_options: [
368512
{
369513
uid:"{$optionUid}",
@@ -382,6 +526,6 @@ private function addProductWithOptionMutation(
382526
}
383527
}
384528
}
385-
QRY;
529+
MUTATION;
386530
}
387531
}

0 commit comments

Comments
 (0)