Add an order attribute in Magento 2 – expose in API and show in grid – part 4

Add an order attribute in Magento 2 – expose in API and show in grid – part 4

In this post, we’ll expose our new attribute in the API so that our finance system can retrieve the value of this attribute when it makes a REST request for an order. There are two steps, first add a getter method for this attribute to the order extension interface and for the class which implements it, and second add the new attribute’s value during order data retrieval. We’ll do the second with a plugin that gets the attribute and sets it in methods which add attributes for both single and multiple records (i.e. for multiple in the case of an order search).

First step, create getter methods:-

DavidMann/OrderSource/etc/​extension_attributes.xml – add getter methods to the order extension interface

1<?xml version=”1.0″?>

2<config xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:noNamespaceSchemaLocation=”urn:magento:framework:Api/etc/extension_attributes.xsd”>

3<extension_attributes for=”Magento\Sales\Api\Data\OrderInterface”>

4<attribute code=”order_source” type=”string” />

5</extension_attributes>

6</config>

Note we’ve also created setter methods with this step.

To actually generate the getter methods and setter methods, we’ll need to use the compile command at the CLI:

bin/magento setup:di:compile

Only then we’ll see the interface generated/code/Magento/Sales/Api/Data/​OrderExtensionInterface.php and it’s implementation generated/code/Magento/​Sales/Api/Data/OrderExtension.php with added getter and setter methods for our new attribute order_source.

generated/code/Magento/​Sales/Api/Data/​OrderExtension.php

531/**

532* @return string|null

533*/

534public function getOrderSource()

535{

536return $this->_get(‘order_source’);

537}

538

539/**

540* @param string $orderSource

541* @return $this

542*/

543public function setOrderSource($orderSource)

544{

545$this->setData(‘order_source’, $orderSource);

546return $this;

547}

Next step is to register a plugin as shown in orange in our already created di.xml.

DavidMann/OrderSource/etc/​di.xml – register the plugin that will add the new attribute to order data (orange)

1<?xml version=”1.0″?>

2<config xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:noNamespaceSchemaLocation=”urn:magento:framework:ObjectManager/etc/config.xsd”>

3<virtualType name=”Magento\Sales\Model\ResourceModel\Order\Grid” type=”Magento\Sales\Model\ResourceModel\Grid”>

4<arguments>

5<argument name=”columns”>

6<item name=”order_source” xsi:type=”string”>sales_order.order_source</item>

7</argument>

8</arguments>

9</virtualType>

10<type name=”Magento\Sales\Api\OrderRepositoryInterface”>

11<plugin name=”orderSourceUpdate” type=”DavidMann\OrderSource\Plugin\Api\OrderRepository” />

12</type>

13</config>

And next in the plugin we’ll add the value of order_source to the order for both of our REST requests, for retrieving single and multiple records.

DavidMann/OrderSource/​Plugin/Api/OrderRepository.php – add our custom field value during the order data loading

1<?php

2

3namespace DavidMann\OrderSource\Plugin\Api;

4

5use Magento\Sales\Api\Data\OrderExtensionFactory;

6use Magento\Sales\Api\Data\OrderInterface;

7use Magento\Sales\Api\Data\OrderSearchResultInterface;

8use Magento\Sales\Api\OrderRepositoryInterface;

9

10

11class OrderRepository

12{

13

14const ORDER_SOURCE = ‘order_source’;

15

16/**

17* Order Extension Attributes Factory

18*

19* @var OrderExtensionFactory

20*/

21protected $extensionFactory;

22

23/**

24* OrderRepositoryPlugin constructor

25*

26* @param OrderExtensionFactory $extensionFactory

27*/

28public function __construct(OrderExtensionFactory $extensionFactory)

29{

30$this->extensionFactory = $extensionFactory;

31}

32

33/**

34* Add “order_source” extension attribute to order to make it accessible in API data

35*

36* @param OrderRepositoryInterface $subject

37* @param OrderInterface $order

38*

39* @return OrderInterface

40*/

41public function afterGet(OrderRepositoryInterface $subject, OrderInterface $order)

42{

43$orderSource = $order->getData(self::ORDER_SOURCE);

44$extensionAttributes = $order->getExtensionAttributes();

45$extensionAttributes = $extensionAttributes ? $extensionAttributes : $this->extensionFactory->create();

46$extensionAttributes->setOrderSource($orderSource);

47$order->setExtensionAttributes($extensionAttributes);

48

49return $order;

50}

51

52/**

53* Add “order_source” extension attribute to order to make it accessible in API data

54*

55* @param OrderRepositoryInterface $subject

56* @param OrderSearchResultInterface $searchResult

57*

58* @return OrderSearchResultInterface

59*/

60public function afterGetList(OrderRepositoryInterface $subject, OrderSearchResultInterface $searchResult)

61{

62$orders = $searchResult->getItems();

63

64foreach ($orders as &$order) {

65$orderSource = $order->getData(self::ORDER_SOURCE);

66$extensionAttributes = $order->getExtensionAttributes();

67$extensionAttributes = $extensionAttributes ? $extensionAttributes : $this->extensionFactory->create();

68$extensionAttributes->setOrderSource($orderSource);

69$order->setExtensionAttributes($extensionAttributes);

70}

71

72return $searchResult;

73}

74}

And run bin/magento setup:di:compile again.

Try now retrieving the order data in Postman or your preferred alternative tool.

We’ll need to get a token initially for the session before making either of our requests with:-

https://davidmann.test/rest/V1/integration/admin/token?username=davidmann&password=*********

The request for a single order record is quite straightforward:-

https://davidmann.test/rest/V1/orders/42408

where 42408 is the order ID. As part of the request, we’ll also need to specify the token in ‘Authorization’ as a ‘Bearer Token’ in Postman.

This request uses the afterGet method on line 41 of DavidMann/OrderSource/​Plugin/Api/OrderRepository.php.

You can see order_source and its value for this record in the Postman response to your request:

https://davidmann.test/rest/​V1/orders/42408 – Response under ‘extension_attributes’

57“extension_attributes”: {

58“converting_from_quote”: true,

59“connectors_sales_order”: {

60“parent_id”: 42408,

61“is_exported_to_io”: 0

62},

63“order_source”: “Admin”

64}

65}

The request for multiple records is a little more demanding:-

https://davidmann.test/rest/V1/orders?searchCriteria[filter_groups][0][filters][0][field]=order_source&searchCriteria[filter_groups][0][filters][0][value]=Admin&searchCriteria[filter_groups][0][filters][0][condition_type]=eq
https://magento2.test/rest/V1/orders?
searchCriteria[filter_groups][0][filters][0][field]=order_source
&searchCriteria[filter_groups][0][filters][0][value]=Admin
&searchCriteria[filter_groups][0][filters][0][condition_type]=eq

Again, we’ll need to specify the token in ‘Authorization’ as a ‘Bearer Token’ in Postman.
This request pulls back all orders placed in Admin, i.e. those that have the value ‘Admin’ in the order_source column.

This request uses the afterGetList method on line 60 of DavidMann/OrderSource/​Plugin/Api/OrderRepository.php.

When constructing a search, keep the following in mind:
1) To perform a logical OR, specify multiple filters within a filter_groups.
2) To perform a logical AND, specify multiple filter_groups.

For example, to request records created between April 26, 2020 AND April 30, 2020 specify two filter groups with value 0 and 1.

https://davidmann.test/rest/V1/orders?
searchCriteria[filter_groups][0][filters][0][field]=created_at
&searchCriteria[filter_groups][0][filters][0][value]=2020-04-26T04:00:00.0000000Z
&searchCriteria[filter_groups][0][filters][0][condition_type]=from
&searchCriteria[filter_groups][1][filters][0][field]=created_at
&searchCriteria[filter_groups][1][filters][0][value]=2020-04-30T17:59:00.0000000Z
&searchCriteria[filter_groups][1][filters][0][condition_type]=to
&searchCriteria[currentPage]=1
&searchCriteria[pageSize]=100

That’s it! We’ve successfully exposed order_source to incoming requests by providing the necessary methods and data.


david.mann

Leave a Reply

Your email address will not be published. Required fields are marked *