Skip to content

Value not getting saved or fetched using extension attribute, For a newly added field in ‘inventory_source’ admin ui page

Have gone through several posts but was somehow not able to find a fix for this issue

When I save, its says “Source saved” but my custom field is not beign saved/fetched

What I have done so far is as below:
enter image description here

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="MagentoInventoryApiApiDataSourceInterface">
        <attribute code="warehouse_timezone" type="string" />
    </extension_attributes>
</config>

inventory_source_form.xml

<?xml version="1.0" encoding="UTF-8"?>
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <fieldset name="address">
        <field name="warehouse_timezone" formElement="select" sortOrder="70">
            <settings>
                <dataType>text</dataType>
                <dataScope>extension_attributes.warehouse_timezone</dataScope>
                <label translate="true">Warehouse timezone</label>
                <notice translate="true">Warehouse timezone will be used in fetching Fedex shipping rates accodring to warehouse current date-time.</notice>
            </settings>
            <formElements>
                <select>
                    <settings>
                        <options class="vendormoduleModelWarehouseTimezone"/>
                        <!-- <options class="MagentoConfigModelConfigSourceLocaleTimezone"/> -->
                    </settings>
                </select>
            </formElements>
        </field>
    </fieldset>
</form>

Model/WarehouseTimezon.php (for fetching option array)

<?php namespace vendormoduleModel;
class WarehouseTimezone implements MagentoFrameworkOptionArrayInterface
{
    const US_EASTERN='US/Eastern';
    const US_CENTRAL='US/Central';
    const US_ARIZONA='US/Arizona';

    public function getOptionArray()
    {
        $data_array=array(); 
        $data_array[self::US_EASTERN]=self::US_EASTERN;
        $data_array[self::US_CENTRAL]=self::US_CENTRAL;
        $data_array[self::US_ARIZONA]=self::US_ARIZONA;
        return($data_array);
    }

    public function getValueArray()
    {
        $data_array=array();
        foreach($this->getOptionArray() as $key=>$value){ $data_array[]=array('label'=>$key, 'value'=>$value); }
        return($data_array);
    }

    /**
     * @return array
     */
    public function toOptionArray(){ return $this->getValueArray(); }
}

di.xml

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="MagentoInventoryApiApiSourceRepositoryInterface">
        <plugin name="plugin_source_save" type="vendormodulePluginSourceSave" sortOrder="1" />
    </type>
</config>

Plugin/SourceSave.php

<?php namespace vendormodulePlugin;
use MagentoInventoryApiApiSourceRepositoryInterface;
use MagentoInventoryApiApiDataSourceInterface;
use MagentoInventoryApiApiDataSourceSearchResultsInterface;
use MagentoInventoryApiApiDataSourceExtensionFactory;
use MagentoInventoryApiApiDataSourceExtensionInterfaceFactory;
use MagentoInventoryApiApiDataStockInterfaceFactory;
class SourceSave
{
    const FIELD_NAME='warehouse_timezone';
    protected $extensionFactory;
    protected $sourceFactory;

    public function __construct
    (
        SourceExtensionFactory $extensionFactory
    )
    {
        $this->extensionFactory=$extensionFactory;
    }


    public function afterGet(SourceRepositoryInterface $subject, SourceInterface $source)
    {
        $sourceComment=$source->getData(self::FIELD_NAME);
        $extensionAttributes=$source->getExtensionAttributes();
        $extensionAttributes=$extensionAttributes ? $extensionAttributes : $this->extensionFactory->create();
        $extensionAttributes->setWarehouseTimezone($sourceComment);
        $source->setExtensionAttributes($extensionAttributes);
        return $source;
    }

    public function afterGetList(SourceRepositoryInterface $subject, SourceSearchResultsInterface $result)
    {
        $products=[];
        $sources=$result->getItems();
        foreach ($sources as $source)
        {
            $sourceComment=$source->getData(self::FIELD_NAME);
            // echo $sourceComment;
            $extensionAttributes=$source->getExtensionAttributes();
            $extensionAttributes=$extensionAttributes ? $extensionAttributes : $this->extensionFactory->create();
            $extensionAttributes->setWarehouseTimezone($sourceComment);
            $source->setExtensionAttributes($extensionAttributes);
            $products[]=$source;
        }
        $result->setItems($products);
        return $result;
    }

    public function beforeSave(SourceRepositoryInterface $subject, SourceInterface $source)
    {
        $extensionAttributes=$source->getExtensionAttributes() ?: $this->extensionFactory->create();
        if($extensionAttributes !== null && $extensionAttributes->getWarehouseTimezone() !== null)
        {
            $source->setWarehouseTimezone($extensionAttributes->getWarehouseTimezone());
        }
        // var_dump($source->getData());die; // getting here value
        return [$source];
    }
}

events.xml Observer For saving its value

<?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="controller_action_inventory_populate_source_with_data">
        <observer name="update_warehouse_timezone" instance="vendormoduleObserverUpdateWarehouseTimezone"/>
    </event>
</config>

Observer/UpdateWarehouseTimezone.php

<?php namespace vendormoduleObserver;
use MagentoFrameworkEventObserverInterface;
/**
 * Class UpdateWarehouseTimezone
 *
 * @package vendormoduleObserver
 */
class UpdateWarehouseTimezone implements ObserverInterface
{
    public function __construct
    (
        PsrLogLoggerInterface $logger,
        MagentoInventoryApiApiSourceRepositoryInterface $sourceRepository
    )
    {
        $this->logger=$logger;
        $this->sourceRepository=$sourceRepository;
    }

    /**
     * @param MagentoFrameworkEventObserver $observer
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function execute(MagentoFrameworkEventObserver $observer)
    {
        $request=$observer->getEvent()->getRequest();
        $requestData=$request->getParam('general', []);
        $type=vendormoduleModelWarehouseTimezone::US_EASTERN;
        if(isset($requestData['extension_attributes']) && isset($requestData['extension_attributes']['warehouse_timezone']))
        { $type=$requestData['extension_attributes']['warehouse_timezone']; }
        $sourceCode=$requestData['source_code'];
        //MagentoInventoryApiApiSourceRepositoryInterface 
        $source=$this->sourceRepository->get($sourceCode);
        $source->setWarehouseTimezone($type);
        $source->save();
    }
}