Skip to content

Commit 06cfb37

Browse files
committed
Merge branch 'ACP2E-3190' of https://github.com/adobe-commerce-tier-4/magento2ce into TIer4-PR-07-22-2024
2 parents 29cd372 + a7d9ba5 commit 06cfb37

File tree

2 files changed

+167
-7
lines changed

2 files changed

+167
-7
lines changed

app/code/Magento/ConfigurableProductGraphQl/Model/Variant/Collection.php

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77

88
namespace Magento\ConfigurableProductGraphQl\Model\Variant;
99

10+
use Exception;
1011
use Magento\Catalog\Api\Data\ProductInterface;
1112
use Magento\Catalog\Model\Product;
12-
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
1313
use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\Collection as ChildCollection;
1414
use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\CollectionFactory;
1515
use Magento\Framework\EntityManager\MetadataPool;
@@ -91,6 +91,7 @@ public function __construct(
9191
*
9292
* @param Product $product
9393
* @return void
94+
* @throws Exception
9495
*/
9596
public function addParentProduct(Product $product) : void
9697
{
@@ -143,6 +144,7 @@ public function getChildProductsByParentId(int $id, ContextInterface $context, a
143144
* @param ContextInterface $context
144145
* @param array $attributeCodes
145146
* @return array
147+
* @throws Exception
146148
*/
147149
private function fetch(ContextInterface $context, array $attributeCodes) : array
148150
{
@@ -156,6 +158,11 @@ private function fetch(ContextInterface $context, array $attributeCodes) : array
156158
$childCollection->setProductFilter($product);
157159
}
158160
$childCollection->addWebsiteFilter($context->getExtensionAttributes()->getStore()->getWebsiteId());
161+
$linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField();
162+
$childCollection->getSelect()->group('e.' . $linkField);
163+
$childCollection->getSelect()->columns([
164+
'parent_ids' => new \Zend_Db_Expr('GROUP_CONCAT(link_table.parent_id)')
165+
]);
159166

160167
$attributeCodes = array_unique(array_merge($this->attributeCodes, $attributeCodes));
161168

@@ -173,14 +180,14 @@ private function fetch(ContextInterface $context, array $attributeCodes) : array
173180
continue;
174181
}
175182
$formattedChild = ['model' => $childProduct, 'sku' => $childProduct->getSku()];
176-
$parentId = (int)$childProduct->getParentId();
177-
if (!isset($this->childrenMap[$parentId])) {
178-
$this->childrenMap[$parentId] = [];
183+
$parentIds = $childProduct->getParentIds() ? explode(',', $childProduct->getParentIds()) : [];
184+
foreach ($parentIds as $parentId) {
185+
if (!isset($this->childrenMap[$parentId])) {
186+
$this->childrenMap[$parentId] = [];
187+
}
188+
$this->childrenMap[$parentId][] = $formattedChild;
179189
}
180-
181-
$this->childrenMap[$parentId][] = $formattedChild;
182190
}
183-
184191
return $this->childrenMap;
185192
}
186193

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
<?php
2+
/**
3+
* Copyright 2024 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\GraphQl\ConfigurableProduct;
9+
10+
use Magento\Catalog\Test\Fixture\Category as CategoryFixture;
11+
use Magento\Catalog\Test\Fixture\Product as ProductFixture;
12+
use Magento\ConfigurableProduct\Test\Fixture\Attribute;
13+
use Magento\ConfigurableProduct\Test\Fixture\Product as ConfigurableProductFixture;
14+
use Magento\TestFramework\Fixture\DataFixture;
15+
use Magento\TestFramework\TestCase\GraphQlAbstract;
16+
17+
/**
18+
* Test configurable product queries work correctly
19+
*/
20+
class MultipleConfigurableProductWithSameSimpleProductTest extends GraphQlAbstract
21+
{
22+
/**
23+
* Test if multiple configurable product can have same simple product
24+
*
25+
*/
26+
#[
27+
DataFixture(CategoryFixture::class, ['name' => 'Test category'], 'test_category'),
28+
DataFixture(Attribute::class, ['options' => [['label' => 'color', 'sort_order' => 0]]], as:'attribute'),
29+
DataFixture(
30+
ProductFixture::class,
31+
[
32+
'name' => 'Simple Product in Test Category',
33+
'sku' => 'simple-product-1',
34+
'category_ids' => ['$test_category.id$'],
35+
'price' => 10,
36+
],
37+
'simple_product_1'
38+
),
39+
DataFixture(
40+
ConfigurableProductFixture::class,
41+
[
42+
'name' => 'Configurable Product 1',
43+
'sku' => 'configurable_product_1',
44+
'category_ids' => ['$test_category.id$'],
45+
'_options' => ['$attribute$'],
46+
'_links' => [
47+
'$simple_product_1$'
48+
]
49+
],
50+
'configurable-product-1'
51+
),
52+
DataFixture(
53+
ConfigurableProductFixture::class,
54+
[
55+
'name' => 'Configurable Product 2',
56+
'sku' => 'configurable_product_2',
57+
'category_ids' => ['$test_category.id$'],
58+
'_options' => ['$attribute$'],
59+
'_links' => [
60+
'$simple_product_1$'
61+
]
62+
],
63+
'configurable-product-2'
64+
),
65+
]
66+
public function testMultipleConfigurableProductCanHaveSameSimpleProduct()
67+
{
68+
$query = $this->getGraphQlQuery('"configurable_product_1", "configurable_product_2"');
69+
$result = $this->graphQlQuery($query);
70+
71+
self::assertArrayNotHasKey('errors', $result);
72+
self::assertNotEmpty($result['products']);
73+
self::assertCount(2, $result['products']['items']);
74+
self::assertNotEmpty($result['products']['items'][0]['variants'][0]);
75+
self::assertCount(2, $result['products']['items'][0]['variants'][0]);
76+
self::assertNotEmpty($result['products']['items'][1]['variants'][0]);
77+
self::assertCount(2, $result['products']['items'][1]['variants'][0]);
78+
}
79+
80+
/**
81+
* Get GraphQl products query with aggregations
82+
*
83+
* @param string $skus
84+
* @return string
85+
*/
86+
private function getGraphQlQuery(string $skus)
87+
{
88+
return <<<QUERY
89+
{
90+
products(filter: {sku: {in: [{$skus}]}}) {
91+
items {
92+
id
93+
attribute_set_id
94+
name
95+
sku
96+
__typename
97+
price {
98+
regularPrice {
99+
amount {
100+
currency
101+
value
102+
}
103+
}
104+
}
105+
categories {
106+
id
107+
}
108+
... on ConfigurableProduct {
109+
configurable_options {
110+
id
111+
attribute_id_v2
112+
label
113+
position
114+
use_default
115+
attribute_code
116+
values {
117+
value_index
118+
label
119+
}
120+
product_id
121+
}
122+
variants {
123+
product {
124+
id
125+
name
126+
sku
127+
attribute_set_id
128+
... on PhysicalProductInterface {
129+
weight
130+
}
131+
price_range{
132+
minimum_price{
133+
regular_price{
134+
value
135+
currency
136+
}
137+
}
138+
}
139+
}
140+
attributes {
141+
uid
142+
label
143+
code
144+
value_index
145+
}
146+
}
147+
}
148+
}
149+
}
150+
}
151+
QUERY;
152+
}
153+
}

0 commit comments

Comments
 (0)