Skip to content

Commit efd2f66

Browse files
author
Serhii Balko
committed
Merge remote-tracking branch 'origin/MC-41810' into 2.4-develop-pr60
2 parents 2f6955c + 709555d commit efd2f66

File tree

4 files changed

+142
-21
lines changed

4 files changed

+142
-21
lines changed

app/code/Magento/Bundle/Model/Product/Type.php

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,11 @@ protected function _prepareProduct(\Magento\Framework\DataObject $buyRequest, $p
665665
$skipSaleableCheck = $this->_catalogProduct->getSkipSaleableCheck();
666666
$_appendAllSelections = (bool)$product->getSkipCheckRequiredOption() || $skipSaleableCheck;
667667

668-
$options = $buyRequest->getBundleOption();
668+
if ($buyRequest->getBundleOptionsData()) {
669+
$options = $this->getPreparedOptions($buyRequest->getBundleOptionsData());
670+
} else {
671+
$options = $buyRequest->getBundleOption();
672+
}
669673
if (is_array($options)) {
670674
$options = $this->recursiveIntval($options);
671675
$optionIds = array_keys($options);
@@ -732,7 +736,11 @@ protected function _prepareProduct(\Magento\Framework\DataObject $buyRequest, $p
732736
if ((is_array($selections) && count($selections) > 0) || !$isStrictProcessMode) {
733737
$uniqueKey = [$product->getId()];
734738
$selectionIds = [];
735-
$qtys = $buyRequest->getBundleOptionQty();
739+
if ($buyRequest->getBundleOptionsData()) {
740+
$qtys = $buyRequest->getBundleOptionsData();
741+
} else {
742+
$qtys = $buyRequest->getBundleOptionQty();
743+
}
736744

737745
// Shuffle selection array by option position
738746
usort($selections, [$this, 'shakeSelections']);
@@ -1231,7 +1239,12 @@ public function getIdentities(\Magento\Catalog\Model\Product $product)
12311239
protected function getQty($selection, $qtys, $selectionOptionId)
12321240
{
12331241
if ($selection->getSelectionCanChangeQty() && isset($qtys[$selectionOptionId])) {
1234-
$qty = (float)$qtys[$selectionOptionId] > 0 ? $qtys[$selectionOptionId] : 1;
1242+
if (is_array($qtys[$selectionOptionId]) && isset($qtys[$selectionOptionId][$selection->getSelectionId()])) {
1243+
$selectionQty = $qtys[$selectionOptionId][$selection->getSelectionId()];
1244+
$qty = (float)$selectionQty > 0 ? $selectionQty : 1;
1245+
} else {
1246+
$qty = (float)$qtys[$selectionOptionId] > 0 ? $qtys[$selectionOptionId] : 1;
1247+
}
12351248
} else {
12361249
$qty = (float)$selection->getSelectionQty() ? $selection->getSelectionQty() : 1;
12371250
}
@@ -1404,4 +1417,21 @@ protected function mergeSelectionsWithOptions($options, $selections)
14041417

14051418
return array_merge([], ...$selections);
14061419
}
1420+
1421+
/**
1422+
* Get prepared options with selection ids
1423+
*
1424+
* @param array $options
1425+
* @return array
1426+
*/
1427+
private function getPreparedOptions(array $options): array
1428+
{
1429+
foreach ($options as $optionId => $option) {
1430+
foreach ($option as $selectionId => $optionQty) {
1431+
$options[$optionId][$selectionId] = $selectionId;
1432+
}
1433+
}
1434+
1435+
return $options;
1436+
}
14071437
}

app/code/Magento/Bundle/Test/Unit/Model/Product/TypeTest.php

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,16 @@ public function testPrepareForCartAdvancedWithoutOptions()
232232
/** @var MockObject|DataObject $buyRequest */
233233
$buyRequest = $this->getMockBuilder(DataObject::class)
234234
->setMethods(
235-
['__wakeup', 'getOptions', 'getSuperProductConfig', 'unsetData', 'getData', 'getQty', 'getBundleOption']
235+
[
236+
'__wakeup',
237+
'getOptions',
238+
'getSuperProductConfig',
239+
'unsetData',
240+
'getData',
241+
'getQty',
242+
'getBundleOption',
243+
'getBundleOptionsData',
244+
]
236245
)
237246
->disableOriginalConstructor()
238247
->getMock();
@@ -342,7 +351,8 @@ public function testPrepareForCartAdvancedWithShoppingCart()
342351
'getData',
343352
'getQty',
344353
'getBundleOption',
345-
'getBundleOptionQty'
354+
'getBundleOptionQty',
355+
'getBundleOptionsData',
346356
]
347357
)
348358
->disableOriginalConstructor()
@@ -586,7 +596,8 @@ public function testPrepareForCartAdvancedEmptyShoppingCart()
586596
'getData',
587597
'getQty',
588598
'getBundleOption',
589-
'getBundleOptionQty'
599+
'getBundleOptionQty',
600+
'getBundleOptionsData',
590601
]
591602
)
592603
->disableOriginalConstructor()
@@ -811,7 +822,8 @@ public function testPrepareForCartAdvancedStringInResult()
811822
'getData',
812823
'getQty',
813824
'getBundleOption',
814-
'getBundleOptionQty'
825+
'getBundleOptionQty',
826+
'getBundleOptionsData',
815827
]
816828
)
817829
->disableOriginalConstructor()
@@ -1030,7 +1042,8 @@ public function testPrepareForCartAdvancedWithoutSelections()
10301042
'getData',
10311043
'getQty',
10321044
'getBundleOption',
1033-
'getBundleOptionQty'
1045+
'getBundleOptionQty',
1046+
'getBundleOptionsData',
10341047
]
10351048
)
10361049
->disableOriginalConstructor()
@@ -1131,7 +1144,16 @@ public function testPrepareForCartAdvancedSelectionsSelectionIdsExists()
11311144
/** @var MockObject|DataObject $buyRequest */
11321145
$buyRequest = $this->getMockBuilder(DataObject::class)
11331146
->setMethods(
1134-
['__wakeup', 'getOptions', 'getSuperProductConfig', 'unsetData', 'getData', 'getQty', 'getBundleOption']
1147+
[
1148+
'__wakeup',
1149+
'getOptions',
1150+
'getSuperProductConfig',
1151+
'unsetData',
1152+
'getData',
1153+
'getQty',
1154+
'getBundleOption',
1155+
'getBundleOptionsData',
1156+
]
11351157
)
11361158
->disableOriginalConstructor()
11371159
->getMock();
@@ -1258,7 +1280,16 @@ public function testPrepareForCartAdvancedSelectRequiredOptions()
12581280
/** @var MockObject|DataObject $buyRequest */
12591281
$buyRequest = $this->getMockBuilder(DataObject::class)
12601282
->setMethods(
1261-
['__wakeup', 'getOptions', 'getSuperProductConfig', 'unsetData', 'getData', 'getQty', 'getBundleOption']
1283+
[
1284+
'__wakeup',
1285+
'getOptions',
1286+
'getSuperProductConfig',
1287+
'unsetData',
1288+
'getData',
1289+
'getQty',
1290+
'getBundleOption',
1291+
'getBundleOptionsData',
1292+
]
12621293
)
12631294
->disableOriginalConstructor()
12641295
->getMock();
@@ -1422,7 +1453,16 @@ public function testPrepareForCartAdvancedAllRequiredOption()
14221453
/** @var MockObject|DataObject $buyRequest */
14231454
$buyRequest = $this->getMockBuilder(DataObject::class)
14241455
->setMethods(
1425-
['__wakeup', 'getOptions', 'getSuperProductConfig', 'unsetData', 'getData', 'getQty', 'getBundleOption']
1456+
[
1457+
'__wakeup',
1458+
'getOptions',
1459+
'getSuperProductConfig',
1460+
'unsetData',
1461+
'getData',
1462+
'getQty',
1463+
'getBundleOption',
1464+
'getBundleOptionsData',
1465+
]
14261466
)
14271467
->disableOriginalConstructor()
14281468
->getMock();
@@ -1523,7 +1563,16 @@ public function testPrepareForCartAdvancedSpecifyProductOptions()
15231563
/** @var MockObject|DataObject $buyRequest */
15241564
$buyRequest = $this->getMockBuilder(DataObject::class)
15251565
->setMethods(
1526-
['__wakeup', 'getOptions', 'getSuperProductConfig', 'unsetData', 'getData', 'getQty', 'getBundleOption']
1566+
[
1567+
'__wakeup',
1568+
'getOptions',
1569+
'getSuperProductConfig',
1570+
'unsetData',
1571+
'getData',
1572+
'getQty',
1573+
'getBundleOption',
1574+
'getBundleOptionsData',
1575+
]
15271576
)
15281577
->disableOriginalConstructor()
15291578
->getMock();

app/code/Magento/QuoteBundleOptions/Model/Cart/BuyRequest/BundleDataProvider.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public function execute(CartItem $cartItem): array
4040
if ($optionType == self::OPTION_TYPE) {
4141
$bundleOptionsData['bundle_option'][$optionId] = $optionValueId;
4242
$bundleOptionsData['bundle_option_qty'][$optionId] = $optionQuantity;
43+
$bundleOptionsData['bundle_options_data'][$optionId][$optionValueId] = $optionQuantity;
4344
}
4445
}
4546
//for bundle options with custom quantity
@@ -57,6 +58,7 @@ public function execute(CartItem $cartItem): array
5758
$optionQuantity = $option->getValue();
5859
$bundleOptionsData['bundle_option'][$optionId] = $optionValueId;
5960
$bundleOptionsData['bundle_option_qty'][$optionId] = $optionQuantity;
61+
$bundleOptionsData['bundle_options_data'][$optionId][$optionValueId] = $optionQuantity;
6062
}
6163
}
6264

dev/tests/api-functional/testsuite/Magento/GraphQl/Bundle/AddBundleProductToCartSingleMutationTest.php

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -232,10 +232,16 @@ public function testAddBundleToCartWithWrongBundleOptions()
232232
/**
233233
* @magentoApiDataFixture Magento/Bundle/_files/product_with_multiple_options_and_custom_quantity.php
234234
* @magentoApiDataFixture Magento/Checkout/_files/active_quote.php
235+
* @dataProvider bundleItemOptionsDataProvider
236+
* @return void
235237
*/
236-
public function testAddBundleItemWithCustomOptionQuantity()
238+
public function testAddBundleItemWithCustomOptionQuantity(
239+
string $optionQty0,
240+
string $optionQty1,
241+
string $expectedOptionQty0,
242+
string $expectedOptionQty1
243+
): void
237244
{
238-
239245
$this->quoteResource->load(
240246
$this->quote,
241247
'test_order_1',
@@ -250,11 +256,34 @@ public function testAddBundleItemWithCustomOptionQuantity()
250256
$uId0 = $bundleOptions[0]['options'][0]['uid'];
251257
$uId1 = $bundleOptions[1]['options'][0]['uid'];
252258
$response = $this->graphQlMutation(
253-
$this->getMutationsQuery($maskedQuoteId, $uId0, $uId1, $sku)
259+
$this->getMutationsQuery($maskedQuoteId, $uId0, $uId1, $sku, $optionQty0, $optionQty1)
254260
);
255261
$bundleOptions = $response['addProductsToCart']['cart']['items'][0]['bundle_options'];
256-
$this->assertEquals(5, $bundleOptions[0]['values'][0]['quantity']);
257-
$this->assertEquals(1, $bundleOptions[1]['values'][0]['quantity']);
262+
$this->assertEquals($expectedOptionQty0, $bundleOptions[0]['values'][0]['quantity']);
263+
$this->assertEquals($expectedOptionQty1, $bundleOptions[1]['values'][0]['quantity']);
264+
}
265+
266+
/**
267+
* Data provider for testAddBundleItemWithCustomOptionQuantity
268+
*
269+
* @return array
270+
*/
271+
public function bundleItemOptionsDataProvider(): array
272+
{
273+
return [
274+
[
275+
'optionQty0' => '10',
276+
'optionQty1' => '1',
277+
'expectedOptionQty0' => '10',
278+
'expectedOptionQty1' => '1',
279+
],
280+
[
281+
'optionQty0' => '5',
282+
'optionQty1' => '5',
283+
'expectedOptionQty0' => '5',
284+
'expectedOptionQty1' => '1',
285+
],
286+
];
258287
}
259288

260289
/**
@@ -298,11 +327,22 @@ private function getProductQuery(string $sku): string
298327
QUERY;
299328
}
300329

330+
/**
331+
* @param string $maskedQuoteId
332+
* @param string $optionUid0
333+
* @param string $optionUid1
334+
* @param string $sku
335+
* @param string $optionQty0
336+
* @param string $optionQty1
337+
* @return string
338+
*/
301339
private function getMutationsQuery(
302340
string $maskedQuoteId,
303341
string $optionUid0,
304342
string $optionUid1,
305-
string $sku
343+
string $sku,
344+
string $optionQty0,
345+
string $optionQty1
306346
): string {
307347
return <<<QUERY
308348
mutation {
@@ -313,15 +353,15 @@ private function getMutationsQuery(
313353
sku: "{$sku}"
314354
quantity: 2
315355
selected_options: [
316-
"{$optionUid1}", "{$optionUid0}"
356+
"{$optionUid0}", "{$optionUid1}"
317357
],
318358
entered_options: [{
319359
uid: "{$optionUid0}"
320-
value: "5"
360+
value: "{$optionQty0}"
321361
},
322362
{
323363
uid: "{$optionUid1}"
324-
value: "5"
364+
value: "{$optionQty1}"
325365
}]
326366
}
327367
]

0 commit comments

Comments
 (0)