Skip to content

Commit bcb8d10

Browse files
Merge branch '2.4-develop' into issue/36163
2 parents 994765c + 203c2f7 commit bcb8d10

File tree

11 files changed

+986
-12
lines changed

11 files changed

+986
-12
lines changed

app/code/Magento/Quote/Model/ResourceModel/Quote/Address/Rate/Collection.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,10 @@ public function save()
131131
$itemsToDelete = [];
132132
$itemsToSave = [];
133133
/** @var Rate $item */
134-
foreach ($this->getItems() as $item) {
134+
foreach ($this->getItems() as $key => $item) {
135135
if ($item->isDeleted()) {
136136
$itemsToDelete[] = $item;
137+
$this->removeItemByKey($key);
137138
} else {
138139
$itemsToSave[] = $item;
139140
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
/**
3+
* ADOBE CONFIDENTIAL
4+
*
5+
* Copyright 2024 Adobe
6+
* All Rights Reserved.
7+
*
8+
* NOTICE: All information contained herein is, and remains
9+
* the property of Adobe and its suppliers, if any. The intellectual
10+
* and technical concepts contained herein are proprietary to Adobe
11+
* and its suppliers and are protected by all applicable intellectual
12+
* property laws, including trade secret and copyright laws.
13+
* Dissemination of this information or reproduction of this material
14+
* is strictly forbidden unless prior written permission is obtained
15+
* from Adobe.
16+
*/
17+
18+
declare(strict_types=1);
19+
20+
namespace Magento\QuoteGraphQl\Model\CartItem\DataProvider\CustomizableOptionValue;
21+
22+
use Magento\Catalog\Model\Product\Option;
23+
use Magento\Catalog\Model\Product\Option\Type\Text as TextOptionType;
24+
use Magento\Quote\Model\Quote\Item as QuoteItem;
25+
use Magento\Quote\Model\Quote\Item\Option as SelectedOption;
26+
use Magento\QuoteGraphQl\Model\CartItem\DataProvider\CustomizableOptionValueInterface;
27+
28+
class File implements CustomizableOptionValueInterface
29+
{
30+
/**
31+
* @param PriceUnitLabel $priceUnitLabel
32+
*/
33+
public function __construct(
34+
private readonly PriceUnitLabel $priceUnitLabel
35+
) {
36+
}
37+
38+
/**
39+
* @inheritdoc
40+
*/
41+
public function getData(
42+
QuoteItem $cartItem,
43+
Option $option,
44+
SelectedOption $selectedOption
45+
): array {
46+
/** @var TextOptionType $optionTypeRenderer */
47+
$optionTypeRenderer = $option->groupFactory($option->getType());
48+
$optionTypeRenderer->setOption($option);
49+
$priceValueUnits = $this->priceUnitLabel->getData($option->getPriceType());
50+
$optionTypeRenderer->setData('configuration_item_option', $selectedOption);
51+
$value = $optionTypeRenderer->getFormattedOptionValue($selectedOption->getValue());
52+
$selectedOptionValueData = [
53+
'id' => $selectedOption->getId(),
54+
'label' => $option->getTitle(),
55+
'value' => $value,
56+
'price' => [
57+
'type' => strtoupper($option->getPriceType()),
58+
'units' => $priceValueUnits,
59+
'value' => $option->getPrice(),
60+
],
61+
];
62+
return [$selectedOptionValueData];
63+
}
64+
}

app/code/Magento/QuoteGraphQl/Model/CartItem/GetPaginatedCartItems.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ public function execute(Quote $cart, int $pageSize, int $offset, string $orderBy
4747
->addFieldToFilter('quote_id', $cart->getId())
4848
->setOrder($orderBy, $order)
4949
->setCurPage($offset)
50-
->setPageSize($pageSize);
50+
->setPageSize($pageSize)
51+
->setQuote($cart);
5152

5253
$items = [];
5354
$itemDeletedCount = 0;

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

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,29 @@ private function getOriginalRowTotal(Item $cartItem): float
118118
{
119119
$qty = $cartItem->getTotalQty();
120120
// Round unit price before multiplying to prevent losing 1 cent on subtotal
121-
return $this->priceCurrency->round($cartItem->getOriginalPrice()) * $qty;
121+
return $this->priceCurrency->round($cartItem->getOriginalPrice() + $this->getOptionsPrice($cartItem)) * $qty;
122+
}
123+
124+
/**
125+
* Get the product custom options price
126+
*
127+
* @param Item $cartItem
128+
* @return float
129+
*/
130+
private function getOptionsPrice(Item $cartItem): float
131+
{
132+
$price = 0.0;
133+
$optionIds = $cartItem->getProduct()->getCustomOption('option_ids');
134+
if (!$optionIds) {
135+
return $price;
136+
}
137+
foreach (explode(',', $optionIds->getValue() ?? '') as $optionId) {
138+
$option = $cartItem->getProduct()->getOptionById($optionId);
139+
if ($option) {
140+
$price += $option->getRegularPrice();
141+
}
142+
}
143+
144+
return $price;
122145
}
123146
}

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

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Magento\Quote\Api\CartRepositoryInterface;
1919
use Magento\Quote\Api\Data\AddressInterface;
2020
use Magento\Quote\Model\MaskedQuoteIdToQuoteIdInterface;
21+
use Magento\Quote\Model\Quote\Address;
2122
use Magento\Quote\Model\Quote\AddressFactory;
2223

2324
/**
@@ -69,7 +70,8 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value
6970
throw new GraphQlInputException(__('Required parameter "country_code" is missing'));
7071
}
7172

72-
$this->totalsInformationManagement->calculate($cartId, $this->getTotalsInformation($args['input']));
73+
$data = $this->getTotalsInformation($args['input']);
74+
$this->totalsInformationManagement->calculate($cartId, $data);
7375

7476
return [
7577
'cart' => [
@@ -106,14 +108,14 @@ private function getTotalsInformation(array $input): TotalsInformationInterface
106108
*/
107109
private function getAddress(array $data): AddressInterface
108110
{
109-
$data = [
110-
AddressInterface::KEY_COUNTRY_ID => $data['country_code'],
111-
AddressInterface::KEY_REGION => $data['region'][AddressInterface::KEY_REGION] ?? null,
112-
AddressInterface::KEY_REGION_ID => $data['region'][AddressInterface::KEY_REGION_ID] ?? null,
113-
AddressInterface::KEY_REGION_CODE => $data['region'][AddressInterface::KEY_REGION_CODE] ?? null,
114-
AddressInterface::KEY_POSTCODE => $data[AddressInterface::KEY_POSTCODE] ?? null,
115-
];
111+
/** @var Address $address */
112+
$address = $this->addressFactory->create();
113+
$address->setCountryId($data['country_code']);
114+
$address->setRegion($data['region'][AddressInterface::KEY_REGION] ?? null);
115+
$address->setRegionId($data['region'][AddressInterface::KEY_REGION_ID] ?? null);
116+
$address->setRegionCode($data['region'][AddressInterface::KEY_REGION_CODE] ?? null);
117+
$address->setPostcode($data[AddressInterface::KEY_POSTCODE] ?? null);
116118

117-
return $this->addressFactory->create(['data' => array_filter($data)]);
119+
return $address;
118120
}
119121
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
<item name="radio" xsi:type="string">Magento\QuoteGraphQl\Model\CartItem\DataProvider\CustomizableOptionValue\Dropdown</item>
3232
<item name="checkbox" xsi:type="string">Magento\QuoteGraphQl\Model\CartItem\DataProvider\CustomizableOptionValue\Multiple</item>
3333
<item name="multiple" xsi:type="string">Magento\QuoteGraphQl\Model\CartItem\DataProvider\CustomizableOptionValue\Multiple</item>
34+
<item name="file" xsi:type="string">Magento\QuoteGraphQl\Model\CartItem\DataProvider\CustomizableOptionValue\File</item>
3435
</argument>
3536
</arguments>
3637
</type>

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

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,117 @@ public function testEstimateTotals(string $countryCode, string $shipping, array
117117
);
118118
}
119119

120+
/**
121+
* @return void
122+
* @throws LocalizedException
123+
*/
124+
#[
125+
DataFixture(
126+
ProductTaxClass::class,
127+
as: 'product_tax_class'
128+
),
129+
DataFixture(
130+
TaxRateFixture::class,
131+
[
132+
'tax_country_id' => 'ES',
133+
'tax_postcode' => '08005',
134+
],
135+
'rate'
136+
),
137+
DataFixture(
138+
TaxRuleFixture::class,
139+
[
140+
'customer_tax_class_ids' => [3],
141+
'product_tax_class_ids' => ['$product_tax_class.classId$'],
142+
'tax_rate_ids' => ['$rate.id$']
143+
],
144+
'rule'
145+
),
146+
DataFixture(
147+
ProductFixture::class,
148+
[
149+
'custom_attributes' => [
150+
'tax_class_id' => '$product_tax_class.classId$'
151+
],
152+
],
153+
'product'
154+
),
155+
DataFixture(GuestCart::class, ['currency' => 'USD'], 'cart'),
156+
DataFixture(QuoteIdMask::class, ['cart_id' => '$cart.id$'], 'quoteIdMask'),
157+
DataFixture(AddProductToCart::class, [
158+
'cart_id' => '$cart.id$',
159+
'product_id' => '$product.id$',
160+
'qty' => 1
161+
])
162+
]
163+
public function testEstimateTotalsCleanPostCode(): void
164+
{
165+
$maskedQuoteId = DataFixtureStorageManager::getStorage()->get('quoteIdMask')->getMaskedId();
166+
167+
$query = <<<QUERY
168+
mutation {
169+
estimateTotals(input: {
170+
cart_id: "{$maskedQuoteId}",
171+
address: {
172+
country_code: ES
173+
postcode: "%s"
174+
},
175+
shipping_method: {
176+
carrier_code: "flatrate",
177+
method_code: "flatrate"
178+
}
179+
}) {
180+
cart {
181+
prices {
182+
applied_taxes {
183+
amount {
184+
value
185+
currency
186+
}
187+
}
188+
}
189+
}
190+
}
191+
}
192+
QUERY;
193+
$response = $this->graphQlMutation(sprintf($query, '08005'));
194+
195+
self::assertEquals(
196+
[
197+
'estimateTotals' => [
198+
'cart' => [
199+
'prices' => [
200+
'applied_taxes' => [
201+
[
202+
'amount' => [
203+
'value' => 1,
204+
'currency' => 'USD'
205+
]
206+
]
207+
]
208+
]
209+
]
210+
]
211+
],
212+
$response
213+
);
214+
215+
$response = $this->graphQlMutation(sprintf($query, ''));
216+
217+
self::assertEquals(
218+
[
219+
'estimateTotals' => [
220+
'cart' => [
221+
'prices' => [
222+
'applied_taxes' => []
223+
]
224+
]
225+
]
226+
],
227+
$response
228+
);
229+
}
230+
120231
public function estimationsProvider(): array
121232
{
122233
return [

0 commit comments

Comments
 (0)