Question

I'm trying to add an extension attribute to sales_order (\Magento\Sales\Api\Data\OrderInterface), and I have the following extension_attributes.xml:

<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_status" type="string">
            <resources>
                <resource  ref="anonymous"/>
            </resources>
            <join reference_table="aytech_order_approval" reference_field="order_id" join_on_field="entity_id">
                <field>order_status</field>
            </join>
        </attribute>
    </extension_attributes>
</config>

I have already created the table aytech_order_approval with the fields order_id and order_status, and in my code I am trying to test getting the attribute like this (I have manually inserted a row into the table with order_id = 1 and order_status = 'approved':

$orders = $this->orderRepository->getList(\Magento\Framework\App\ObjectManager::getInstance()->create('Magento\Framework\Api\SearchCriteriaInterface'))->getItems();

echo $orders[1]->getExtensionAttributes()->getOrderStatus();

However, I keep getting null. What am I doing wrong? Also I've made sure to clear the var/generation, and the generated class does indeed have the getOrderStatus method

Was it helpful?

Solution

(Fortunately or not, but ) Join Processor (Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface) isn't used everywhere and in particular it is not used in Sales module. As result, extension attributes aren't automatically added to "getList" and "get" methods result for Orders, Invoices and other entities of Sales module. You should do that by yourself, with defining plugin to appropriate method ("getList", "get" or maybe better both). In that plugin you can load all additional data and add it to OrderExtension object.

As a reference example see how it works for GiftMessage module. Three steps to get it done:

  1. declare extension attribute: app/code/Magento/GiftMessage/etc/extension_attributes.xml
  2. declare your plugin: app/code/Magento/GiftMessage/etc/di.xml
  3. add data to OrderExtension object(s) from plugin: \Magento\GiftMessage\Model\Plugin\OrderGet::afterGetList

P.S. One small suggestion, for the sake of performance, if you need to extend the collection of objects, try to do that in one call to database storage, and do not do that inside of the loop for every order. But most likely you already know that :)

And here is a code example for your plugin:

$ids = [];
foreach ($resultOrder->getItems() as $order) {
    $ids[] = $order->getEntityId();
}
$statuses = []; /* should be loaded for collected $ids */
foreach ($resultOrder->getItems() as $order) {
    $orderId = $order->getEntityId();
    if ($statuses[$orderId]) {
        $extensionAttributes = $order->getExtensionAttributes();
        $extensionAttributes->setOrderStatus($statuses[$orderId]);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top