3

I have a requirement to add the custom attribute (delivery_time) to each inventory source.

my-vendor/module/etc/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="Magento\InventoryApi\Api\SourceRepositoryInterface">
        <plugin name="plugin_source_save" type="<vendor-name>\<module>\Plugin\SourceSave"/>
    </type>
</config>

my-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\InventoryApi\Api\Data\SourceInterface">
        <attribute code="delivery_time" type="string" />
    </extension_attributes>
</config>

my-vendor/module/view/adminhtml/ui_component/inventory_source_form.xml

<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">

<fieldset name="general">
    <field name="delivery_time" formElement="input" sortOrder="70">
        <settings>
            <dataType>text</dataType>
            <label translate="true">Delivery Time</label>
        </settings>
    </field>
</fieldset>

my-vendor/module/Plugin/SourceSave.php

<?php
namespace my-vendor\module\Plugin;

use Magento\InventoryApi\Api\SourceRepositoryInterface;
use Magento\InventoryApi\Api\Data\SourceInterface;
use Magento\InventoryApi\Api\Data\SourceSearchResultsInterface;
use Magento\InventoryApi\Api\Data\SourceExtensionFactory;
use Magento\InventoryApi\Api\Data\SourceExtensionInterfaceFactory;
use Magento\InventoryApi\Api\Data\StockInterfaceFactory;


class SourceSave
{

    const FIELD_NAME = 'delivery_time';

    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->setDeliveryTime($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->setDeliveryTime($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->getDeliveryTime() !== null) {
            $source->setDeliveryTime($extensionAttributes->getDeliveryTime());
        }
        var_dump($source->getData());die;
        return [$source];
    }

}

enter image description here

The Delivery Time field is visible from the frontend, but the delivery_time value is returning NULL on the before save method which should be saved in DB

I save the delivery time extension attribute value to DB by observing

controller_action_inventory_populate_source_with_data

    $request = $observer->getEvent()->getRequest();
    $requestData = $request->getParam('general', []);

    $type =  $requestData['delivery_time'];
    $sourceCode = $requestData['source_code'];

    //Magento\InventoryApi\Api\SourceRepositoryInterface 
    $source = $this->sourceRepository->get($sourceCode);
    $source->setDeliveryTime($type);
    $source->save();

But the admin UI form data is not filled up. Kindly help me where I'm struck. Thanks in advance!

3 Answers 3

2

In your inventory_source_form.xml under <settings>, try adding <dataScope>extension_attributes.delivery_time</dataScope>.

Something like this:

<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">

<fieldset name="general">
    <field name="delivery_time" formElement="input" sortOrder="70">
        <settings>
            <dataType>text</dataType>
            <dataScope>extension_attributes.delivery_time</dataScope>
            <label translate="true">Delivery Time</label>
        </settings>
    </field>
</fieldset>
1

In addition to to the fix above you will need to make sure your module has dependency/sequence to ensure the form is populated.

module.xml

<sequence>
    <module name="Magento_InventoryAdminUi" />
</sequence>
0

Also you have to create de database column, with db_schema.xml, like this.

<?xml version="1.0"?>
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
    <table name="inventory_source">
        <column xsi:type="varchar" name="delivery_time" unsigned="true" nullable="true" identity="false"/>
    </table>
</schema>

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.