Skip to content

Commit c96e36d

Browse files
LYNX-188: Add a query to retrieve cancellation reasons (#146)
1 parent 46ec51c commit c96e36d

File tree

6 files changed

+245
-1
lines changed

6 files changed

+245
-1
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\OrderCancellationGraphQl\Model\Resolver;
9+
10+
use Magento\Framework\GraphQl\Config\Element\Field;
11+
use Magento\Framework\GraphQl\Query\ResolverInterface;
12+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
13+
14+
/**
15+
* Resolver to return the description of a CancellationReason
16+
*/
17+
class CancellationReason implements ResolverInterface
18+
{
19+
/**
20+
* @inheritdoc
21+
*/
22+
public function resolve(
23+
Field $field,
24+
$context,
25+
ResolveInfo $info,
26+
array $value = null,
27+
array $args = null
28+
) {
29+
return $value['reason'];
30+
}
31+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\OrderCancellationGraphQl\Model\Resolver;
9+
10+
use Magento\Framework\GraphQl\Config\Element\Field;
11+
use Magento\Framework\GraphQl\Query\ResolverInterface;
12+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
13+
14+
/**
15+
* Resolver for generating CancellationReasons
16+
*/
17+
class CancellationReasons implements ResolverInterface
18+
{
19+
/**
20+
* @inheritdoc
21+
*/
22+
public function resolve(
23+
Field $field,
24+
$context,
25+
ResolveInfo $info,
26+
array $value = null,
27+
array $args = null
28+
) {
29+
if (!is_array($value['order_cancellation_reasons'])) {
30+
$cancellationReasons = json_decode($value['order_cancellation_reasons'], true);
31+
} else {
32+
$cancellationReasons = $value['order_cancellation_reasons'];
33+
}
34+
35+
return $cancellationReasons;
36+
}
37+
}

app/code/Magento/OrderCancellationGraphQl/etc/graphql/di.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<arguments>
1111
<argument name="extendedConfigData" xsi:type="array">
1212
<item name="order_cancellation_enabled" xsi:type="string">sales/cancellation/enabled</item>
13+
<item name="order_cancellation_reasons" xsi:type="string">sales/cancellation/reasons</item>
1314
</argument>
1415
</arguments>
1516
</type>

app/code/Magento/OrderCancellationGraphQl/etc/schema.graphqls

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,9 @@
22
# See COPYING.txt for license details.
33
type StoreConfig {
44
order_cancellation_enabled: Boolean @doc(description: "Indicates whether orders can be cancelled by customers or not.")
5+
order_cancellation_reasons: [CancellationReason!]! @resolver(class: "Magento\\OrderCancellationGraphQl\\Model\\Resolver\\CancellationReasons") @doc(description: "An array containing available cancellation reasons.")
6+
}
7+
8+
type CancellationReason {
9+
description: String! @resolver(class: "Magento\\OrderCancellationGraphQl\\Model\\Resolver\\CancellationReason")
510
}
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\GraphQl\OrderCancellation;
9+
10+
use Exception;
11+
use Magento\Store\Api\Data\StoreInterface;
12+
use Magento\Store\Test\Fixture\Group as StoreGroupFixture;
13+
use Magento\Store\Test\Fixture\Store as StoreFixture;
14+
use Magento\Store\Test\Fixture\Website as WebsiteFixture;
15+
use Magento\TestFramework\Fixture\Config;
16+
use Magento\TestFramework\Fixture\DataFixture;
17+
use Magento\TestFramework\Fixture\DataFixtureStorageManager;
18+
use Magento\TestFramework\Fixture\DbIsolation;
19+
use Magento\TestFramework\TestCase\GraphQlAbstract;
20+
21+
/**
22+
* Test that order cancellation are returned via the storeConfig GraphQL query.
23+
* Query must take into account passed store through request header.
24+
* Reasons are returned following the same order as they are stored in the DB.
25+
*/
26+
class OrderCancellationReasonsTest extends GraphQlAbstract
27+
{
28+
private const STORE_CONFIG_QUERY = <<<QUERY
29+
{
30+
storeConfig {
31+
order_cancellation_reasons {
32+
description
33+
}
34+
}
35+
}
36+
QUERY;
37+
38+
/**
39+
* When no cancellation reasons are provided through `sales/cancellation/reasons` configuration
40+
* the query returns the default cancellation reasons from `OrderCancellation/etc/config.xml` file.
41+
*
42+
* @return void
43+
* @throws Exception
44+
*/
45+
#[
46+
DbIsolation(true)
47+
]
48+
public function testGetDefaultCancellationReasons()
49+
{
50+
$response = $this->graphQlQuery(self::STORE_CONFIG_QUERY);
51+
52+
$this->assertEquals(
53+
[
54+
'storeConfig' => [
55+
'order_cancellation_reasons' => [
56+
[
57+
'description' => 'The item(s) are no longer needed'
58+
],
59+
[
60+
'description' => 'The order was placed by mistake'
61+
],
62+
[
63+
'description' => 'Item(s) not arriving within the expected timeframe'
64+
],
65+
[
66+
'description' => 'Found a better price elsewhere'
67+
],
68+
[
69+
'description' => 'Other'
70+
]
71+
],
72+
]
73+
],
74+
$response
75+
);
76+
}
77+
78+
#[
79+
DataFixture(WebsiteFixture::class, as: 'website2'),
80+
DataFixture(StoreGroupFixture::class, ['website_id' => '$website2.id$'], 'store_group2'),
81+
DataFixture(StoreFixture::class, [
82+
'store_group_id' => '$store_group2.id$',
83+
'code' => 'some_store_2',
84+
'name' => 'Some Store 2'
85+
], 'store2'),
86+
Config(
87+
'sales/cancellation/reasons',
88+
'{"item1":{"reason":"Reason 1"},"item2":{"reason":"Reason 2"},"1691592389534":{"reason":"Another reason"}}',
89+
'store',
90+
'some_store_2'
91+
)
92+
]
93+
public function testGetCancellationReasonsSetUpThroughConfiguration()
94+
{
95+
/** @var StoreInterface $store */
96+
$store = DataFixtureStorageManager::getStorage()->get('store2');
97+
98+
$response = $this->graphQlQuery(
99+
self::STORE_CONFIG_QUERY,
100+
[],
101+
'',
102+
['Store' => $store->getCode()]
103+
);
104+
105+
$this->assertEquals(
106+
[
107+
'storeConfig' => [
108+
'order_cancellation_reasons' => [
109+
[
110+
'description' => 'Reason 1'
111+
],
112+
[
113+
'description' => 'Reason 2'
114+
],
115+
[
116+
'description' => 'Another reason'
117+
]
118+
],
119+
]
120+
],
121+
$response
122+
);
123+
}
124+
125+
#[
126+
DataFixture(WebsiteFixture::class, as: 'website3'),
127+
DataFixture(StoreGroupFixture::class, ['website_id' => '$website3.id$'], 'store_group3'),
128+
DataFixture(StoreFixture::class, [
129+
'store_group_id' => '$store_group3.id$',
130+
'code' => 'some_store_3',
131+
'name' => 'Some Store 3'
132+
], 'store3'),
133+
Config(
134+
'sales/cancellation/reasons',
135+
'{"item1": {"reason": "Dummy reason"}}',
136+
'store',
137+
'some_store_3'
138+
)
139+
]
140+
public function testGetCancellationReasonsForDifferentStore()
141+
{
142+
/** @var StoreInterface $store */
143+
$store = DataFixtureStorageManager::getStorage()->get('store3');
144+
145+
$response = $this->graphQlQuery(
146+
self::STORE_CONFIG_QUERY,
147+
[],
148+
'',
149+
['Store' => $store->getCode()]
150+
);
151+
152+
$this->assertEquals(
153+
[
154+
'storeConfig' => [
155+
'order_cancellation_reasons' => [
156+
[
157+
'description' => 'Dummy reason'
158+
]
159+
],
160+
]
161+
],
162+
$response
163+
);
164+
}
165+
}

lib/internal/Magento/Framework/App/Config/Value.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,16 @@ public function isValueChanged()
9494
*/
9595
public function getOldValue()
9696
{
97-
return (string)$this->_config->getValue(
97+
$oldValue = $this->_config->getValue(
9898
$this->getPath(),
9999
$this->getScope() ?: ScopeConfigInterface::SCOPE_TYPE_DEFAULT,
100100
$this->getScopeCode()
101101
);
102+
103+
if (is_array($oldValue)) {
104+
return json_encode($oldValue);
105+
}
106+
return (string)$oldValue;
102107
}
103108

104109
/**

0 commit comments

Comments
 (0)