0

In a Magento 2.4.5, I've (successfully) added a custom field (opening_mon) to the AdminHtml form for a Source (MSI), using view/adminhtml/ui_component/inventory_source_form.xml. I do see the field in the form.

<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <fieldset name="opening_times" sortOrder="40">
        <settings>
            <label translate="true">Opening times</label>
            <collapsible>true</collapsible>
            <opened>false</opened>
            <dataScope>general</dataScope>
        </settings>
        <field name="opening_mon" formElement="input" sortOrder="50">
            <settings>
                <dataScope>extension_attributes.opening_mon</dataScope>
                <dataType>string</dataType>
                <label translate="true">Opening times Monday</label>
            </settings>
        </field>
    </fieldset>
</form>

I've also added a field in the database table inventory_source (using etc/db_schema.xml). I see the field in the database table.

<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="opening_mon" length="50" nullable="true" comment="opening times monday" />
    </table>
</schema>

When I enter a value in the custom field and save the form, I get confirmation the form is saved ('The Source has been saved.') but I don't see the value in the database table (inventory_source). My expectation is that I would see this value in the database table. How to save value entered in custom field in the Source (MSI) form? I've tried many suggestions from internet. Also I need to know how to show the value from the database field opening_mon in the form field.

A working example for M2.4 is highly appreciated or documentation I can use. Thanks in advance. Kind regards.

1 Answer 1

0

In your case you try to modify specific logic and you need to made additional changes

1. Register your field in extension attributes

app/code/Acme/StackExchange/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="opening_mon" type="string"/>
    </extension_attributes>
</config>

2. Register Source Repository Plugin

app/code/Acme/StackExchange/etc/di.xml

<?xml version="1.0" encoding="UTF-8"?>
<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="Acme_StackExchange_Plugin_InventoryApi_Api_SourceRepositoryPlugin"
                type="Acme\StackExchange\Plugin\InventoryApi\Api\SourceRepositoryPlugin"/>
    </type>
</config>

3. Create Source Repository Plugin

app/code/Acme/StackExchange/Plugin/InventoryApi/Api/SourceRepositoryPlugin.php

<?php
declare(strict_types=1);

namespace Acme\StackExchange\Plugin\InventoryApi\Api;

use Magento\Framework\Api\ExtensionAttributesFactory;
use Magento\Framework\DataObject;
use Magento\InventoryApi\Api\Data\SourceInterface;
use Magento\InventoryApi\Api\Data\SourceSearchResultsInterface;
use Magento\InventoryApi\Api\SourceRepositoryInterface;

class SourceRepositoryPlugin
{
    protected const ATTRIBUTE = 'opening_mon';

    protected ExtensionAttributesFactory $extensionAttributesFactory;

    /**
     * @inheritDoc
     */
    public function __construct(
        ExtensionAttributesFactory $extensionAttributesFactory
    ) {
        $this->extensionAttributesFactory = $extensionAttributesFactory;
    }


    public function beforeSave(
        SourceRepositoryInterface $subject,
        SourceInterface $source
    ): array {
        if ($source instanceof DataObject) {
            $extensionAttributes = $source->getExtensionAttributes();
            if ($extensionAttributes !== null) {
                $source->setData(self::ATTRIBUTE, $extensionAttributes->getOpeningMon());
            }
        }

        return [$source];
    }

    private function extendSource(SourceInterface $source): void
    {
        if (!$source instanceof DataObject) {
            return;
        }

        $extensionAttributes = $source->getExtensionAttributes();

        if ($extensionAttributes === null) {
            $extensionAttributes = $this->extensionAttributesFactory->create(SourceInterface::class);
            /** @noinspection PhpParamsInspection */
            $source->setExtensionAttributes($extensionAttributes);
        }

        $extensionAttributes->setOpeningMon($source->getData(self::ATTRIBUTE));
    }

    public function afterGet(
        SourceRepositoryInterface $subject,
        SourceInterface $source
    ): SourceInterface {
        $this->extendSource($source);

        return $source;
    }

    public function afterGetList(
        SourceRepositoryInterface $subject,
        SourceSearchResultsInterface $sourceSearchResults
    ): SourceSearchResultsInterface {
        $items = $sourceSearchResults->getItems();
        array_walk(
            $items,
            [$this, 'extendSource']
        );

        return $sourceSearchResults;
    }
}
1
  • Hi Victor, Don't know how you did it and it worked!!! Incredible! Thank you so much. I've been breaking my head over this issue for so many hours. Aug 18, 2022 at 5:41

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.