Skip to content

Commit 1f8d588

Browse files
committed
Merge remote-tracking branch 'origin/MC-37726-price-filter' into HB-PR-delivery-Oct
2 parents d04bf94 + 9094403 commit 1f8d588

File tree

5 files changed

+169
-33
lines changed

5 files changed

+169
-33
lines changed

app/code/Magento/CatalogGraphQl/DataProvider/Product/LayeredNavigation/Builder/Price.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public function build(AggregationInterface $aggregation, ?int $storeId): array
7272
);
7373
}
7474

75-
return [$result];
75+
return [self::PRICE_BUCKET => $result];
7676
}
7777

7878
/**

app/code/Magento/CatalogGraphQl/Model/Resolver/Aggregations.php

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77

88
namespace Magento\CatalogGraphQl\Model\Resolver;
99

10+
use Magento\CatalogGraphQl\DataProvider\Product\LayeredNavigation\LayerBuilder;
11+
use Magento\Directory\Model\PriceCurrency;
12+
use Magento\Framework\App\ObjectManager;
1013
use Magento\Framework\GraphQl\Config\Element\Field;
1114
use Magento\Framework\GraphQl\Query\ResolverInterface;
1215
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
13-
use Magento\CatalogGraphQl\DataProvider\Product\LayeredNavigation\LayerBuilder;
1416
use Magento\Store\Api\Data\StoreInterface;
1517

1618
/**
@@ -28,16 +30,24 @@ class Aggregations implements ResolverInterface
2830
*/
2931
private $layerBuilder;
3032

33+
/**
34+
* @var PriceCurrency
35+
*/
36+
private $priceCurrency;
37+
3138
/**
3239
* @param \Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider\Filters $filtersDataProvider
3340
* @param LayerBuilder $layerBuilder
41+
* @param PriceCurrency $priceCurrency
3442
*/
3543
public function __construct(
3644
\Magento\CatalogGraphQl\Model\Resolver\Layer\DataProvider\Filters $filtersDataProvider,
37-
LayerBuilder $layerBuilder
45+
LayerBuilder $layerBuilder,
46+
PriceCurrency $priceCurrency = null
3847
) {
3948
$this->filtersDataProvider = $filtersDataProvider;
4049
$this->layerBuilder = $layerBuilder;
50+
$this->priceCurrency = $priceCurrency ?: ObjectManager::getInstance()->get(PriceCurrency::class);
4151
}
4252

4353
/**
@@ -60,7 +70,18 @@ public function resolve(
6070
/** @var StoreInterface $store */
6171
$store = $context->getExtensionAttributes()->getStore();
6272
$storeId = (int)$store->getId();
63-
return $this->layerBuilder->build($aggregations, $storeId);
73+
$results = $this->layerBuilder->build($aggregations, $storeId);
74+
if (isset($results['price_bucket'])) {
75+
foreach ($results['price_bucket']['options'] as &$value) {
76+
list($from, $to) = explode('-', $value['label']);
77+
$newLabel = $this->priceCurrency->convertAndRound($from)
78+
. '-'
79+
. $this->priceCurrency->convertAndRound($to);
80+
$value['label'] = $newLabel;
81+
$value['value'] = str_replace('-', '_', $newLabel);
82+
}
83+
}
84+
return $results;
6485
} else {
6586
return [];
6687
}

app/code/Magento/CatalogGraphQl/composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"magento/module-eav": "*",
88
"magento/module-catalog": "*",
99
"magento/module-catalog-inventory": "*",
10+
"magento/module-directory": "*",
1011
"magento/module-search": "*",
1112
"magento/module-store": "*",
1213
"magento/module-eav-graph-ql": "*",

dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductPriceTest.php

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,55 @@ public function testProductWithSinglePrice()
7878
$this->assertPrices($expectedPriceRange, $product['price_range']);
7979
}
8080

81+
/**
82+
* @magentoApiDataFixture Magento/Catalog/_files/products.php
83+
* @magentoApiDataFixture Magento/Directory/_files/usd_cny_rate.php
84+
* @magentoConfigFixture default_store currency/options/allow CNY,USD
85+
*/
86+
public function testProductWithSinglePriceNonDefaultCurrency()
87+
{
88+
$skus = ['simple'];
89+
$query = $this->getProductQuery($skus);
90+
$headerMap = [
91+
'Content-Currency' => 'CNY'
92+
];
93+
$result = $this->graphQlQuery($query, [], '', $headerMap);
94+
95+
$this->assertArrayNotHasKey('errors', $result);
96+
$this->assertNotEmpty($result['products']['items']);
97+
$product = $result['products']['items'][0];
98+
$this->assertNotEmpty($product['price_range']);
99+
100+
$expectedPriceRange = [
101+
"minimum_price" => [
102+
"regular_price" => [
103+
"value" => 70
104+
],
105+
"final_price" => [
106+
"value" => 70
107+
],
108+
"discount" => [
109+
"amount_off" => 0,
110+
"percent_off" => 0
111+
]
112+
],
113+
"maximum_price" => [
114+
"regular_price" => [
115+
"value" => 70
116+
],
117+
"final_price" => [
118+
"value" => 70
119+
],
120+
"discount" => [
121+
"amount_off" => 0,
122+
"percent_off" => 0
123+
]
124+
]
125+
];
126+
127+
$this->assertPrices($expectedPriceRange, $product['price_range'], 'CNY');
128+
}
129+
81130
/**
82131
* Pricing for Simple, Grouped and Configurable products with no special or tier prices configured
83132
*
@@ -909,7 +958,7 @@ private function getQueryConfigurableProductAndVariants(array $sku): string
909958
name
910959
sku
911960
price_range {
912-
minimum_price {regular_price
961+
minimum_price {regular_price
913962
{
914963
value
915964
currency
@@ -949,13 +998,13 @@ private function getQueryConfigurableProductAndVariants(array $sku): string
949998
... on ConfigurableProduct{
950999
variants{
9511000
product{
952-
1001+
9531002
sku
9541003
price_range {
9551004
minimum_price {regular_price {value}
9561005
final_price {
9571006
value
958-
1007+
9591008
}
9601009
discount {
9611010
amount_off
@@ -965,11 +1014,11 @@ private function getQueryConfigurableProductAndVariants(array $sku): string
9651014
maximum_price {
9661015
regular_price {
9671016
value
968-
1017+
9691018
}
9701019
final_price {
9711020
value
972-
1021+
9731022
}
9741023
discount {
9751024
amount_off
@@ -985,7 +1034,7 @@ private function getQueryConfigurableProductAndVariants(array $sku): string
9851034
final_price{value}
9861035
quantity
9871036
}
988-
1037+
9891038
}
9901039
}
9911040
}

dev/tests/api-functional/testsuite/Magento/GraphQl/Catalog/ProductSearchAggregationsTest.php

Lines changed: 88 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
namespace Magento\GraphQl\Catalog;
99

10-
use Magento\TestFramework\Helper\Bootstrap;
1110
use Magento\TestFramework\TestCase\GraphQlAbstract;
1211

1312
class ProductSearchAggregationsTest extends GraphQlAbstract
@@ -22,28 +21,9 @@ public function testAggregationBooleanAttribute()
2221
. 'MC-36768: Custom attribute not appears in elasticsearch'
2322
);
2423

25-
$skus= '"search_product_1", "search_product_2", "search_product_3", "search_product_4" ,"search_product_5"';
26-
$query = <<<QUERY
27-
{
28-
products(filter: {sku: {in: [{$skus}]}}){
29-
items{
30-
id
31-
sku
32-
name
33-
}
34-
aggregations{
35-
label
36-
attribute_code
37-
count
38-
options{
39-
label
40-
value
41-
count
42-
}
43-
}
44-
}
45-
}
46-
QUERY;
24+
$query = $this->getGraphQlQuery(
25+
'"search_product_1", "search_product_2", "search_product_3", "search_product_4" ,"search_product_5"'
26+
);
4727

4828
$result = $this->graphQlQuery($query);
4929

@@ -69,4 +49,89 @@ function ($a) {
6949
$this->assertCount(2, $booleanAggregation['options']);
7050
$this->assertContainsEquals(['label' => '0', 'value'=> '0', 'count' => '2'], $booleanAggregation['options']);
7151
}
52+
53+
/**
54+
* @magentoApiDataFixture Magento/Catalog/_files/products_for_search.php
55+
*/
56+
public function testAggregationPriceRanges()
57+
{
58+
$query = $this->getGraphQlQuery(
59+
'"search_product_1", "search_product_2", "search_product_3", "search_product_4" ,"search_product_5"'
60+
);
61+
$result = $this->graphQlQuery($query);
62+
63+
$this->assertArrayNotHasKey('errors', $result);
64+
$this->assertArrayHasKey('aggregations', $result['products']);
65+
66+
$priceAggregation = array_filter(
67+
$result['products']['aggregations'],
68+
function ($a) {
69+
return $a['attribute_code'] == 'price';
70+
}
71+
);
72+
$this->assertNotEmpty($priceAggregation);
73+
$priceAggregation = reset($priceAggregation);
74+
$this->assertEquals('Price', $priceAggregation['label']);
75+
$this->assertEquals(4, $priceAggregation['count']);
76+
$expectedOptions = [
77+
['label' => '10-20', 'value'=> '10_20', 'count' => '2'],
78+
['label' => '20-30', 'value'=> '20_30', 'count' => '1'],
79+
['label' => '30-40', 'value'=> '30_40', 'count' => '1'],
80+
['label' => '40-50', 'value'=> '40_50', 'count' => '1']
81+
];
82+
$this->assertEquals($expectedOptions, $priceAggregation['options']);
83+
}
84+
85+
/**
86+
* @magentoApiDataFixture Magento/Catalog/_files/products_for_search.php
87+
* @magentoApiDataFixture Magento/Directory/_files/usd_cny_rate.php
88+
* @magentoConfigFixture default_store currency/options/allow CNY,USD
89+
*/
90+
public function testAggregationPriceRangesWithCurrencyHeader()
91+
{
92+
$headerMap['Content-Currency'] = 'CNY';
93+
$query = $this->getGraphQlQuery(
94+
'"search_product_1", "search_product_2", "search_product_3", "search_product_4" ,"search_product_5"'
95+
);
96+
$result = $this->graphQlQuery($query, [], '', $headerMap);
97+
$this->assertArrayNotHasKey('errors', $result);
98+
$this->assertArrayHasKey('aggregations', $result['products']);
99+
$priceAggregation = array_filter(
100+
$result['products']['aggregations'],
101+
function ($a) {
102+
return $a['attribute_code'] == 'price';
103+
}
104+
);
105+
$this->assertNotEmpty($priceAggregation);
106+
$priceAggregation = reset($priceAggregation);
107+
$this->assertEquals('Price', $priceAggregation['label']);
108+
$this->assertEquals(4, $priceAggregation['count']);
109+
$expectedOptions = [
110+
['label' => '70-140', 'value'=> '70_140', 'count' => '2'],
111+
['label' => '140-210', 'value'=> '140_210', 'count' => '1'],
112+
['label' => '210-280', 'value'=> '210_280', 'count' => '1'],
113+
['label' => '280-350', 'value'=> '280_350', 'count' => '1']
114+
];
115+
$this->assertEquals($expectedOptions, $priceAggregation['options']);
116+
}
117+
118+
private function getGraphQlQuery(string $skus)
119+
{
120+
return <<<QUERY
121+
{
122+
products(filter: {sku: {in: [{$skus}]}}){
123+
aggregations{
124+
label
125+
attribute_code
126+
count
127+
options{
128+
label
129+
value
130+
count
131+
}
132+
}
133+
}
134+
}
135+
QUERY;
136+
}
72137
}

0 commit comments

Comments
 (0)