Skip to content

Commit 0e33b80

Browse files
authored
Merge pull request #8480 from magento-lynx/order-cancellation
[LYNX] Order Cancellation GraphQl
2 parents 3cc15fb + cf1c502 commit 0e33b80

File tree

25 files changed

+686
-1
lines changed

25 files changed

+686
-1
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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\OrderCancellation\Block\Adminhtml\Form\Field;
9+
10+
use Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray;
11+
12+
class Reasons extends AbstractFieldArray
13+
{
14+
/**
15+
* Prepare rendering the new field by adding all the needed columns
16+
*/
17+
protected function _prepareToRender()
18+
{
19+
$this->addColumn('reason', ['label' => __('Reason'), 'class' => 'required-entry']);
20+
$this->_addAfter = false;
21+
$this->_addButtonLabel = __('Add Reason');
22+
}
23+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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\OrderCancellation\Model\Config\Backend;
9+
10+
use Magento\Config\Model\Config\Backend\Serialized;
11+
use Magento\Framework\Exception\LocalizedException;
12+
13+
class Reasons extends Serialized
14+
{
15+
/**
16+
* Processing object before save data
17+
*
18+
* @return $this
19+
* @throws LocalizedException
20+
*/
21+
public function beforeSave()
22+
{
23+
$value = $this->getValue();
24+
if (is_array($value)) {
25+
unset($value['__empty']);
26+
27+
if (empty($value)) {
28+
throw new LocalizedException(
29+
__('At least one reason value is required')
30+
);
31+
}
32+
}
33+
$this->setValue($value);
34+
return parent::beforeSave();
35+
}
36+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Magento_OrderCancellation module
2+
3+
This module allows to cancel an order and specify the order cancellation reason. Only orders in `RECEIVED`, `PENDING` or `PROCESSING` statuses can be cancelled and if the customer has paid for the order a refund is processed.
4+
5+
This functionality is enabled / disabled by a feature flag that is set at storeView level.
6+
7+
After the cancellation, the customer receive an email confirming it and this cancellation is reflected in the customer's order history.
8+
9+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd">
9+
<page name="AdminOrderCancellationConfigPage" url="admin/system_config/edit/section/sales/" area="admin" module="Magento_OrderCancellationGraphQl">
10+
<section name="AdminOrderCancellationConfigSection"/>
11+
</page>
12+
</pages>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
9+
<section name="AdminOrderCancellationConfigSection">
10+
<element name="valueForSalesCancellation" type="select" selector="#sales_cancellation_enabled"/>
11+
<element name="systemValueForSalesCancellation" type="checkbox" selector="#sales_cancellation_enabled_inherit"/>
12+
<element name="systemValueForSalesCancellationReasons" type="checkbox" selector="#sales_cancellation_reasons_inherit"/>
13+
<element name="deleteReasonRow" type="button" selector="#sales_cancellation_reasons #item{{row}} td.col-actions button.action-delete" parameterized="true"/>
14+
<element name="deleteFirstReason" type="button" selector="#sales_cancellation_reasons tbody tr:first-child td.col-actions button.action-delete" />
15+
<element name="editReasonRow" type="input" selector="#sales_cancellation_reasons #item{{row}} input" parameterized="true"/>
16+
<element name="addReason" type="button" selector="#sales_cancellation_reasons td.col-actions-add button.action-add" />
17+
<element name="editFirstReason" type="input" selector="#sales_cancellation_reasons tbody tr:first-child input" />
18+
<element name="editLastReason" type="input" selector="#sales_cancellation_reasons tbody tr:last-child input" />
19+
</section>
20+
</sections>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
10+
<test name="AdminOrderCancellationConfigTest">
11+
<annotations>
12+
<features value="Order Cancellation"/>
13+
<stories value="Enable / disable order cancellation feature through the admin."/>
14+
<title value="Enable / disable order cancellation feature through the admin."/>
15+
<description value="Test feature flag to enable / disable order cancellation through the admin."/>
16+
<severity value="AVERAGE"/>
17+
<testCaseId value="LYNX-174"/>
18+
<group value="configuration"/>
19+
<group value="pr_exclude"/>
20+
</annotations>
21+
<before>
22+
<actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/>
23+
</before>
24+
<after>
25+
<actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/>
26+
</after>
27+
<amOnPage url="{{AdminOrderCancellationConfigPage.url('#sales_cancellation-head')}}" stepKey="navigateToConfigurationPage"/>
28+
<waitForPageLoad time="30" stepKey="waitForAdminSalesConfigPageLoad"/>
29+
<uncheckOption selector="{{AdminOrderCancellationConfigSection.systemValueForSalesCancellation}}" stepKey="uncheckUseSystemValue"/>
30+
<selectOption selector="{{AdminOrderCancellationConfigSection.valueForSalesCancellation}}" userInput="1" stepKey="valueForSalesCancellation"/>
31+
<actionGroup ref="AdminSaveConfigActionGroup" stepKey="saveConfig"/>
32+
</test>
33+
</tests>
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
10+
<test name="AdminOrderCancellationReasonsConfigCreateEditTest">
11+
<annotations>
12+
<features value="Order Cancellation"/>
13+
<stories value="Create order cancellation reasons through the admin."/>
14+
<title value="Create order cancellation reasons through the admin."/>
15+
<description value="Test adding, modifying and deleting order cancellation reasons through the admin."/>
16+
<severity value="AVERAGE"/>
17+
<testCaseId value="LYNX-189"/>
18+
<group value="configuration"/>
19+
<group value="pr_exclude"/>
20+
</annotations>
21+
<before>
22+
<actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/>
23+
</before>
24+
<after>
25+
<actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/>
26+
</after>
27+
<amOnPage url="{{AdminOrderCancellationConfigPage.url('#sales_cancellation-head')}}" stepKey="navigateToConfigurationPage"/>
28+
<waitForPageLoad time="30" stepKey="waitForAdminSalesConfigPageLoad"/>
29+
<uncheckOption selector="{{AdminOrderCancellationConfigSection.systemValueForSalesCancellationReasons}}" stepKey="uncheckUseSystemValue"/>
30+
<click selector="{{AdminOrderCancellationConfigSection.deleteFirstReason}}" stepKey="deleteDefaultReason"/>
31+
<fillField selector="{{AdminOrderCancellationConfigSection.editFirstReason}}" userInput="Modified reason" stepKey="editDefaultReason"/>
32+
<click selector="{{AdminOrderCancellationConfigSection.addReason}}" stepKey="addReason"/>
33+
<fillField selector="{{AdminOrderCancellationConfigSection.editLastReason}}" userInput="New reason" stepKey="fillReason" />
34+
<click selector="{{AdminConfigSection.saveButton}}" stepKey="saveConfig"/>
35+
<waitForElementVisible selector="{{AdminMessagesSection.success}}" stepKey="waitForElementVisible"/>
36+
<see selector="{{AdminMessagesSection.success}}" userInput="You saved the configuration." stepKey="seeConfigSuccessMessage"/>
37+
</test>
38+
</tests>
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
10+
<test name="AdminOrderCancellationReasonsConfigRemoveAllTest">
11+
<annotations>
12+
<features value="Order Cancellation"/>
13+
<stories value="Remove order cancellation reasons through the admin."/>
14+
<title value="Remove delete order cancellation reasons through the admin."/>
15+
<description value="Test that removing all order cancellation reasons through the admin yields an error when saving."/>
16+
<severity value="AVERAGE"/>
17+
<testCaseId value="LYNX-189"/>
18+
<group value="configuration"/>
19+
<group value="pr_exclude"/>
20+
</annotations>
21+
<before>
22+
<actionGroup ref="AdminLoginActionGroup" stepKey="loginAsAdmin"/>
23+
</before>
24+
<after>
25+
<actionGroup ref="AdminLogoutActionGroup" stepKey="logout"/>
26+
</after>
27+
<amOnPage url="{{AdminOrderCancellationConfigPage.url('#sales_cancellation-head')}}" stepKey="navigateToConfigurationPage"/>
28+
<waitForPageLoad time="30" stepKey="waitForAdminSalesConfigPageLoad"/>
29+
<uncheckOption selector="{{AdminOrderCancellationConfigSection.systemValueForSalesCancellationReasons}}" stepKey="uncheckUseSystemValue"/>
30+
<click selector="{{AdminOrderCancellationConfigSection.deleteFirstReason}}" stepKey="deleteDefaultReason1"/>
31+
<click selector="{{AdminOrderCancellationConfigSection.deleteFirstReason}}" stepKey="deleteDefaultReason2"/>
32+
<click selector="{{AdminOrderCancellationConfigSection.deleteFirstReason}}" stepKey="deleteDefaultReason3"/>
33+
<click selector="{{AdminOrderCancellationConfigSection.deleteFirstReason}}" stepKey="deleteDefaultReason4"/>
34+
<click selector="{{AdminOrderCancellationConfigSection.deleteFirstReason}}" stepKey="deleteDefaultReason5"/>
35+
<click selector="{{AdminConfigSection.saveButton}}" stepKey="saveConfig"/>
36+
<waitForElementVisible selector="{{AdminMessagesSection.error}}" stepKey="waitForElementVisible"/>
37+
<see selector="{{AdminMessagesSection.error}}" userInput="At least one reason value is required" stepKey="seeConfigErrorMessage"/>
38+
</test>
39+
</tests>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "magento/module-order-cancellation",
3+
"description": "N/A",
4+
"config": {
5+
"sort-packages": true
6+
},
7+
"require": {
8+
"php": "~8.1.0||~8.2.0",
9+
"magento/framework": "*",
10+
"magento/module-config": "*"
11+
},
12+
"type": "magento2-module",
13+
"license": [
14+
"OSL-3.0",
15+
"AFL-3.0"
16+
],
17+
"autoload": {
18+
"files": [
19+
"registration.php"
20+
],
21+
"psr-4": {
22+
"Magento\\OrderCancellation\\": ""
23+
}
24+
}
25+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9+
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
10+
<system>
11+
<section id="sales">
12+
<group id="cancellation" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
13+
<label>Order cancellation</label>
14+
<field id="enabled" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
15+
<label>Order cancellation through GraphQL</label>
16+
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
17+
</field>
18+
<field id="reasons" translate="label" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
19+
<label>Order cancellation reasons</label>
20+
<frontend_model>Magento\OrderCancellation\Block\Adminhtml\Form\Field\Reasons</frontend_model>
21+
<backend_model>Magento\OrderCancellation\Model\Config\Backend\Reasons</backend_model>
22+
</field>
23+
</group>
24+
</section>
25+
</system>
26+
</config>

0 commit comments

Comments
 (0)