Skip to content

multiselect custom field does not save in sales rule admin form in magento 2.4

I need to save custom multiselect field value in the apply_on_weekday column which is located in the salesrule Db table. I tried a lot but it doesn’t save the data in the database.

Below is my code.

VendorModuleviewadminhtmlui_componentsales_rule_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="rule_information" sortOrder="10">
        <field name="apply_on_weekday" formElement="multiselect">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <!-- <item name="dataType" xsi:type="string">int</item> -->
                    <item name="source" xsi:type="string">sales_rule</item>
                    <item name="default" xsi:type="string">Mon</item>
                </item>
            </argument>
            <settings>
                <label translate="true">Apply for specific weekdays</label>
                <dataScope>apply_on_weekday</dataScope>
            </settings>
            <formElements>
                <multiselect>
                    <settings>
                        <options class="VendorModuleModelConfigSourceWeekdays"/>
                    </settings>
                </multiselect>
            </formElements>
        </field>
    </fieldset>
</form>

VendorModuleModelConfigSourceWeekdays.php file

<?php

namespace VendorModuleModelConfigSource;

use MagentoFrameworkDataOptionSourceInterface;

class Weekdays implements OptionSourceInterface
{
    /**
     * Value which equal "Monday" for Weekdays dropdown.
     */
    const MONDAY = "Mon";

    /**
     * Value which equal "Tuesday" for Weekdays dropdown.
     */
    const TUESDAY = "Tue";

    /**
     * Value which equal "Wednesday" for Weekdays dropdown.
     */
    const WEDNESDAY = "Wed";

    /**
     * Value which equal "Thursday" for Weekdays dropdown.
     */
    const THURSDAY = "Thu";

    /**
     * Value which equal "Friday" for Weekdays dropdown.
     */
    const FRIDAY = "Fri";

    /**
     * Value which equal "Saturday" for Weekdays dropdown.
     */
    const SATURDAY = "Sat";

    /**
     * Value which equal "Sunday" for Weekdays dropdown.
     */
    const SUNDAY = "Sun";

    /**
     * {@inheritdoc}
     */
    public function toOptionArray()
    {
        return [
            ['value' => self::MONDAY, 'label' => __('Mon')],
            ['value' => self::TUESDAY, 'label' => __('Tue')],
            ['value' => self::WEDNESDAY, 'label' => __('Wed')],
            ['value' => self::THURSDAY, 'label' => __('Thu')],
            ['value' => self::FRIDAY, 'label' => __('Fri')],
            ['value' => self::SATURDAY, 'label' => __('Sat')],
            ['value' => self::SUNDAY, 'label' => __('Sun')],
        ];
    }
}

when we create select formComponent field then We need to declare field in UI_component the xml file only. but here we use multiselect formComponent, now when form submits it will give apply_on_weekday field value in terms of array format.

now we wants to save it in a single row column. So we need to convert apply_on_weekday field value array into comma seperated string to save it in a single column.

So, I use adminhtml_controller_salesrule_prepare_save event

VendorModuleetcevents.xml

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">    
    <event name="adminhtml_controller_salesrule_prepare_save">
        <observer name="vendor_module_adminhtml_controller_salesrule_prepare_save" instance="VendorModuleObserverSalesrulePrepareSaveObserver"/>
    </event>
</config>

VendorModuleObserverSalesrulePrepareSaveObserver.php

<?php

namespace VendorModuleObserver;

use MagentoFrameworkEventObserver as EventObserver;
use MagentoFrameworkEventObserverInterface;

class SalesrulePrepareSaveObserver implements ObserverInterface {

    /**
     * @param MagentoFrameworkEventObserver $observer
     * @return $this
     */
    public function execute(EventObserver $observer) {

        /** @var MagentoFrameworkAppRequestInterface */
        $request = $observer->getRequest();

        $postData = $request->getPostValue();

        $apply_on_weekday = $postData['apply_on_weekday'];

        if($apply_on_weekday && is_array($apply_on_weekday)) {
            $apply_on_weekday = implode(',', $apply_on_weekday);
        }
        
        $request->setPostValue('apply_on_weekday', $apply_on_weekday);
        
        $writer = new Zend_Log_Writer_Stream(BP . '/var/log/custom.log');
        $logger = new Zend_Log();
        $logger->addWriter($writer);
        $logger->info('Your text message');
        $logger->info(json_encode($request->getPostValue()));
        // return $this;
    }

}

when i debugging, I found that comma seperated value saved in the request. but after that event magento use old data array to store it in the database. see this controller here i found that magento doesn’t take updated data to store it. So what can I do?