0

I followed this guide to add a custom product attribute to quote and sales order item throughout the order process and this works fine.

My custom attribute is added to the sales_order_item table correctly but will not return in the order api call: /rest/V1/orders/X . The item in the order are present but the custom added attribute seems to be missing.

How do I add this sales_order_item attribute to the API output?

I tried it by adding a "extension_attributes.xml" to my custom module (that included the custom attribute: see earlier mentioned link) but that seems to have no effect:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
    <extension_attributes for="Magento\Sales\Api\Data\OrderItemInterface">
        <attribute code="deliverycode" type="string" />
    </extension_attributes>
</config>

Thanks for the help!

Update

Still haven't resolved the issues after trying some minor things. I ran into this topic, which is closely related to my issue. I am trying to adjust the code to suit my needs but I haven't found the answer yet after a few hours of trying to switch the code the be suitable for "sales_order_item". If anyone has any solutions or tips to push me in the right direction they are very much appreciated!

1
  • Have you got the above answer ?? Commented Jul 15, 2020 at 15:33

3 Answers 3

0

Hi,

Please try to get the order item rest/V1/orders/items/(orderid)

Or else add extension attributes in order api

1. create Vendor\Module\etc\extension_attributes.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
<extension_attributes for="Magento\Sales\Api\Data\OrderInterface">
    <attribute code="order_attribute" type="string" />
</extension_attributes>
</config>

Then create observer for event ‘sales_order_load_after’

2. Vendor\Module\etc\events.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="sales_order_load_after">
    <observer name="sales_order_load_order_attribute" instance="Vendor\Module\Observer\Sales\OrderLoadAfter" />
</event>
</config>

Create a file to get the event data

3. vendor\Module\Observer\Sales\OrderLoadAfter.php

<?php
namespace Vendor\Module\Observer\Sales;
use Magento\Framework\Event\ObserverInterface;
class OrderLoadAfter implements ObserverInterface
{
public function execute(\Magento\Framework\Event\Observer $observer)
{
    $order = $observer->getOrder();
    $extensionAttributes = $order->getExtensionAttributes();
    if ($extensionAttributes === null) {
        $extensionAttributes = $this->getOrderExtensionDependency();
    }
    $attr = `Get the order item attributes`
    $extensionAttributes->setOrderAttribute($attr);
    $order->setExtensionAttributes($extensionAttributes);
}
private function getOrderExtensionDependency()
{
    $orderExtension = \Magento\Framework\App\ObjectManager::getInstance()->get(
        '\Magento\Sales\Api\Data\OrderExtension'
    );
    return $orderExtension;
}
}

Please run the upgrade, compile and deploy command

THanks

7
  • Hi, I am trying your suggestions, thanks! I think your code above relates to extending the ORDERS instead of the ORDER ITEMS that have a custom attribute (sales_order_items) am I correct in assuming so? I am trying to rewrite for it, no luck yet though.
    – JohnRP
    Commented Jul 30, 2019 at 13:35
  • Yes, We add the custom attribute in order. Probably, we can not add in the order_item directly. YOu need to use the order extension attributes to achieve that.
    – Moin Malek
    Commented Jul 30, 2019 at 13:42
  • I do not quite understand. So in order to add my custom sales_order_item attribute to the API I will need to use an order extension instead of an order item extension (OrderItemInterface)? Thanks!
    – JohnRP
    Commented Jul 30, 2019 at 13:49
  • 1
    I looked into your code a bit further and I thank you for your effort, but I need to expose the custom sales_order_item attribute to the api and not a custom sales_order attribute. I am still looking into it, if I find a way I will post an update.
    – JohnRP
    Commented Jul 31, 2019 at 17:49
  • 1
    Sadly I have not found an answer to this issue.
    – JohnRP
    Commented Jun 23, 2020 at 19:17
0

Let's imagine that you are implementing this for the order service. Then, you request the following service to get a single order:

rest/V1/orders/:orderId

In fact you are requesting the get method of OrderRepository.

So in your extension_attributes.xml you already have this:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
    <extension_attributes for="Magento\Sales\Api\Data\OrderItemInterface">
        <attribute code="deliverycode" type="string" />
    </extension_attributes>
</config>

After doing that you need to implement you Plugin for the OrderRepository, where in your implementation you should follow the example down below:

<?php

namespace YourVendor\Sales\Plugin\Model;

class OrderRepository
{

    protected $orderItemExtension;

    public function __construct(
        \Magento\Sales\Api\Data\OrderItemExtensionInterfaceFactory $orderItemExtension
    )
    {
        $this->orderItemExtension = $orderItemExtension;
    }

    public function afterGet(
        \Magento\Sales\Model\OrderRepository $subject,
        $result
    )
    {
        foreach ($result->getItems() as $item) {
            $deliveryCode = ""; // whatever it comes from...

            $extensionAttributes = $this->orderItemExtension->create();
            $extensionAttributes->setData('deliverycode', $deliveryCode );
            $item->setExtensionAttributes($extensionAttributes);
        }

        return $result;
    }
}

I hope it helps!

0

Tested solution on 2.4 is as followings:

  1. declare extension attribute for order items (in my case it was item_image) I want to add each item image url.

    <extension_attributes for="Magento\Sales\Api\Data\OrderItemInterface">

    <attribute code="item_image" type="string" />
    

    </extension_attributes>

  2. Declare plugin for order item repository which is responsible to collect order items data

     <type name="Magento\Sales\Model\Order\ItemRepository">
     <plugin name="Alrajhi_FoodPickupApi_Plugin_Magento_Sales_Model_Order_ItemRepository" type="Alrajhi\FoodPickupApi\Plugin\Order\ItemImage\ItemRepository" sortOrder="10" disabled="false"/></type>
    
  3. write your logic in the plugin

namespace Alrajhi\FoodPickupApi\Plugin\Order\ItemImage;

use Magento\Sales\Api\Data\OrderItemInterface;

class ItemRepository {

public function afterGetList(
    \Magento\Sales\Model\Order\ItemRepository $subject,
                                              $result,
                                              $searchCriteria
) {
    foreach ($result->getItems() as $item) {
        $this->setItemImage($item);
    }
    return $result;
}

/**
 * Set item image
 *
 * @param OrderItemInterface $item
 */
public function setItemImage(OrderItemInterface $item)
{
    $extensionAttributes = $item->getExtensionAttributes() ?: $this->orderExtensionFactory->create();
    $extensionAttributes->setItemImage("hassanalishahzad"); // here you can write you logic
    $item->setExtensionAttributes($extensionAttributes);
}

}

This will now show you in the orders API response

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.