Skip to content

Commit 5dc13c3

Browse files
Merge pull request #7903 from magento-gl/comm_78764_25677
[Bluetooth] Community Pull Requests delivery - 2.4-develop
2 parents b053b83 + 1beed2c commit 5dc13c3

File tree

4 files changed

+206
-5
lines changed

4 files changed

+206
-5
lines changed

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class Type extends \Magento\Catalog\Model\Product\Type\AbstractType
3131
/**
3232
* Product type
3333
*/
34-
const TYPE_CODE = 'bundle';
34+
public const TYPE_CODE = 'bundle';
3535

3636
/**
3737
* Product is composite
@@ -52,6 +52,7 @@ class Type extends \Magento\Catalog\Model\Product\Type\AbstractType
5252
*
5353
* @var string
5454
* @deprecated 100.2.0
55+
* @see MAGETWO-71174
5556
*/
5657
protected $_keySelectionsCollection = '_cache_instance_selections_collection';
5758

@@ -91,14 +92,14 @@ class Type extends \Magento\Catalog\Model\Product\Type\AbstractType
9192
protected $_canConfigure = true;
9293

9394
/**
94-
* Catalog data
95+
* Catalog data helper
9596
*
9697
* @var \Magento\Catalog\Helper\Data
9798
*/
9899
protected $_catalogData = null;
99100

100101
/**
101-
* Catalog product
102+
* Catalog product helper
102103
*
103104
* @var \Magento\Catalog\Helper\Product
104105
*/
@@ -1286,7 +1287,7 @@ protected function checkIsAllRequiredOptions($product, $isStrictProcessMode, $op
12861287
{
12871288
if (!$product->getSkipCheckRequiredOption() && $isStrictProcessMode) {
12881289
foreach ($optionsCollection->getItems() as $option) {
1289-
if ($option->getRequired() && !isset($options[$option->getId()])) {
1290+
if ($option->getRequired() && empty($options[$option->getId()])) {
12901291
throw new \Magento\Framework\Exception\LocalizedException(
12911292
__('Please select all required options.')
12921293
);
@@ -1421,6 +1422,7 @@ protected function mergeSelectionsWithOptions($options, $selections)
14211422
/**
14221423
* Get prepared options with selection ids
14231424
*
1425+
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
14241426
* @param array $options
14251427
* @return array
14261428
*/

app/code/Magento/BundleGraphQl/Model/Resolver/Options/Collection.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,15 @@ private function fetch() : array
112112

113113
$productTable = $optionsCollection->getTable('catalog_product_entity');
114114
$linkField = $optionsCollection->getConnection()->getAutoIncrementField($productTable);
115+
$entityIds = array_column($this->skuMap, 'entity_id');
116+
115117
$optionsCollection->getSelect()->join(
116118
['cpe' => $productTable],
117119
'cpe.' . $linkField . ' = main_table.parent_id',
118120
[]
119121
)->where(
120122
"cpe.entity_id IN (?)",
121-
$this->skuMap
123+
$entityIds
122124
);
123125
$optionsCollection->setPositionOrder();
124126

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

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,19 @@
77

88
namespace Magento\GraphQl\Bundle;
99

10+
use Magento\Bundle\Test\Fixture\Link as BundleSelectionFixture;
11+
use Magento\Bundle\Test\Fixture\Option as BundleOptionFixture;
12+
use Magento\Bundle\Test\Fixture\Product as BundleProductFixture;
1013
use Magento\Catalog\Api\ProductRepositoryInterface;
14+
use Magento\Catalog\Test\Fixture\Product as ProductFixture;
1115
use Magento\TestFramework\TestCase\GraphQlAbstract;
1216
use Magento\TestFramework\Helper\Bootstrap;
1317
use Magento\Quote\Model\Quote;
1418
use Magento\Quote\Model\QuoteIdToMaskedQuoteIdInterface;
1519
use Magento\Quote\Model\ResourceModel\Quote as QuoteResource;
20+
use Magento\TestFramework\Fixture\DataFixture;
21+
use Magento\TestFramework\Fixture\DataFixtureStorage;
22+
use Magento\TestFramework\Fixture\DataFixtureStorageManager;
1623

1724
/**
1825
* Test adding bundled products to cart
@@ -39,6 +46,11 @@ class AddBundleProductToCartTest extends GraphQlAbstract
3946
*/
4047
private $productRepository;
4148

49+
/**
50+
* @var DataFixtureStorage
51+
*/
52+
private $fixtures;
53+
4254
/**
4355
* @inheritdoc
4456
*/
@@ -49,6 +61,7 @@ protected function setUp(): void
4961
$this->quote = $objectManager->create(Quote::class);
5062
$this->quoteIdToMaskedId = $objectManager->get(QuoteIdToMaskedQuoteIdInterface::class);
5163
$this->productRepository = $objectManager->get(ProductRepositoryInterface::class);
64+
$this->fixtures = $objectManager->get(DataFixtureStorageManager::class)->getStorage();
5265
}
5366

5467
/**
@@ -372,6 +385,119 @@ public function testAddBundleToCartWithRadioAndSelectErr()
372385
}
373386
}
374387
}
388+
QUERY;
389+
390+
$this->graphQlMutation($query);
391+
}
392+
393+
/**
394+
* @magentoApiDataFixture Magento/Checkout/_files/active_quote.php
395+
*/
396+
#[
397+
DataFixture(ProductFixture::class, ['sku' => 'simple-1', 'price' => 10], 'p1'),
398+
DataFixture(ProductFixture::class, ['sku' => 'simple2', 'price' => 20], 'p2'),
399+
DataFixture(BundleSelectionFixture::class, ['sku' => '$p1.sku$', 'price' => 10, 'price_type' => 0], 'link1'),
400+
DataFixture(BundleSelectionFixture::class, ['sku' => '$p2.sku$', 'price' => 25, 'price_type' => 1], 'link2'),
401+
DataFixture(BundleOptionFixture::class, ['title' => 'Checkbox Options', 'type' => 'checkbox',
402+
'required' => 1,'product_links' => ['$link1$', '$link2$']], 'opt1'),
403+
DataFixture(BundleOptionFixture::class, ['title' => 'Multiselect Options', 'type' => 'multi',
404+
'required' => 1,'product_links' => ['$link1$', '$link2$']], 'opt2'),
405+
DataFixture(
406+
BundleProductFixture::class,
407+
['sku' => 'bundle-product-multiselect-checkbox-options','price' => 50,'price_type' => 1,
408+
'_options' => ['$opt1$', '$opt2$']],
409+
'bundle-product-multiselect-checkbox-options'
410+
),
411+
]
412+
public function testAddBundleToCartWithEmptyMultiselectOptionValue()
413+
{
414+
$this->expectException(\Exception::class);
415+
$this->expectExceptionMessage('Please select all required options.');
416+
417+
$this->quoteResource->load(
418+
$this->quote,
419+
'test_order_1',
420+
'reserved_order_id'
421+
);
422+
$sku = 'bundle-product-multiselect-checkbox-options';
423+
424+
$product = $this->fixtures->get($sku);
425+
426+
/** @var $typeInstance \Magento\Bundle\Model\Product\Type */
427+
$typeInstance = $product->getTypeInstance();
428+
$typeInstance->setStoreFilter($product->getStoreId(), $product);
429+
/** @var $option \Magento\Bundle\Model\Option */
430+
$options = $typeInstance->getOptionsCollection($product);
431+
432+
$selectionIds = [];
433+
$optionIds = [];
434+
foreach ($options as $option) {
435+
$type = $option->getType();
436+
437+
/** @var \Magento\Catalog\Model\Product $selection */
438+
$selections = $typeInstance->getSelectionsCollection([$option->getId()], $product);
439+
$optionIds[$type] = $option->getId();
440+
441+
foreach ($selections->getItems() as $selection) {
442+
$selectionIds[$type][] = $selection->getSelectionId();
443+
}
444+
}
445+
446+
$maskedQuoteId = $this->quoteIdToMaskedId->execute((int)$this->quote->getId());
447+
448+
$query = <<<QUERY
449+
mutation {
450+
addBundleProductsToCart(input:{
451+
cart_id: "{$maskedQuoteId}"
452+
cart_items: [
453+
{
454+
data: {
455+
sku: "{$sku}"
456+
quantity: 1
457+
}
458+
bundle_options: [
459+
{
460+
id: {$optionIds['multi']}
461+
quantity: 1
462+
value: [
463+
""
464+
]
465+
},
466+
{
467+
id: {$optionIds['checkbox']}
468+
quantity: 1
469+
value: [
470+
"{$selectionIds['checkbox'][0]}"
471+
]
472+
}
473+
]
474+
}
475+
]
476+
}) {
477+
cart {
478+
items {
479+
id
480+
quantity
481+
product {
482+
sku
483+
}
484+
... on BundleCartItem {
485+
bundle_options {
486+
id
487+
label
488+
type
489+
values {
490+
id
491+
label
492+
price
493+
quantity
494+
}
495+
}
496+
}
497+
}
498+
}
499+
}
500+
}
375501
QUERY;
376502

377503
$this->graphQlMutation($query);

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

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,19 @@
88
namespace Magento\GraphQl\Bundle;
99

1010
use Magento\Bundle\Model\Product\OptionList;
11+
use Magento\Bundle\Test\Fixture\Option as BundleOptionFixture;
12+
use Magento\Bundle\Test\Fixture\Product as BundleProductFixture;
1113
use Magento\Catalog\Api\Data\ProductInterface;
1214
use Magento\Catalog\Api\ProductRepositoryInterface;
15+
use Magento\Catalog\Test\Fixture\Product as ProductFixture;
1316
use Magento\Framework\App\Config\ScopeConfigInterface;
17+
use Magento\TestFramework\Fixture\DataFixture;
1418
use Magento\TestFramework\ObjectManager;
1519
use Magento\TestFramework\TestCase\GraphQlAbstract;
1620
use Magento\Store\Model\StoreManagerInterface;
1721
use Magento\Catalog\Model\Product\Attribute\Source\Status as ProductStatus;
22+
use Magento\TestFramework\Fixture\DataFixtureStorage;
23+
use Magento\TestFramework\Fixture\DataFixtureStorageManager;
1824

1925
/**
2026
* Test querying Bundle products
@@ -502,4 +508,69 @@ public function testBundleProductWithDisabledProductOption()
502508
$response = $this->graphQlQuery($query);
503509
$this->assertEmpty($response['products']['items']);
504510
}
511+
512+
#[
513+
DataFixture(ProductFixture::class, ['price' => 10], 'p1'),
514+
DataFixture(ProductFixture::class, ['price' => 20], 'p2'),
515+
DataFixture(BundleOptionFixture::class, ['product_links' => ['$p1$']], 'opt1'),
516+
DataFixture(BundleOptionFixture::class, ['product_links' => ['$p2$']], 'opt2'),
517+
DataFixture(
518+
BundleProductFixture::class,
519+
['id' => 3, 'sku' => '4bundle-product','_options' => ['$opt1$', '$opt2$']],
520+
'4bundle-product'
521+
),
522+
DataFixture(
523+
BundleProductFixture::class,
524+
['id' => 4, 'sku' => '5bundle-product','_options' => ['$opt1$', '$opt2$']],
525+
'5bundle-product'
526+
),
527+
]
528+
public function testBundleProductHavingSKUAsNextBundleProductId()
529+
{
530+
531+
$productSku = '4bundle-product';
532+
$query
533+
= <<<QUERY
534+
{
535+
products(filter: {sku: {eq: "{$productSku}"}})
536+
{
537+
items{
538+
id
539+
type_id
540+
name
541+
sku
542+
... on BundleProduct {
543+
items {
544+
option_id
545+
title
546+
required
547+
type
548+
position
549+
sku
550+
options {
551+
id
552+
quantity
553+
position
554+
is_default
555+
price
556+
price_type
557+
can_change_quantity
558+
label
559+
product {
560+
id
561+
name
562+
sku
563+
type_id
564+
}
565+
}
566+
}
567+
}
568+
}
569+
}
570+
}
571+
QUERY;
572+
573+
$response = $this->graphQlQuery($query);
574+
$this->assertNotEmpty($response['products']['items']);
575+
}
505576
}

0 commit comments

Comments
 (0)