Magento – Custom checkout field doesn’t save the value to quote

custom-fieldmagento2onepage-checkout

I created a custom attribute for quote and order like this:

    $quote = 'quote';
    $orderTable = 'sales_order';

    $setup->getConnection()
        ->addColumn(
            $setup->getTable($quote),
            'is_dropship',
            [
                'type' => \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
                'comment' =>'Dropship Order'
            ]
        );

    //Order table
    $setup->getConnection()
        ->addColumn(
            $setup->getTable($orderTable),
            'is_dropship',
            [
                'type' => \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
                'comment' =>'Dropship Order'
            ]
        );

    $setup->endSetup();

then i add the custom field with checkbox type like this

Vendor/Module/Plugin/Checkout/Model/Checkout/LayoutProcessor.php

public function afterProcess(
        \Magento\Checkout\Block\Checkout\LayoutProcessor $subject,
        array  $jsLayout
    ) {
        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
        ['shippingAddress']['children']['shipping-address-fieldset']['children']['custom_test'] = [
           'component' => 'Magento_Ui/js/form/element/abstract',
            'config' => [
                'customScope' => 'shippingAddress',
                'template' => 'ui/form/field',
                'elementTmpl' => 'ui/form/element/checkbox',
                'options' => [],
                'id' => 'is_dropship',
            ],
            'dataScope' => 'shippingAddress.is_dropship',
            'label' => 'Send as dropship',
            'provider' => 'checkoutProvider',
            'visible' => true,
            'checked' => true,
            'value' => 1,
            'validation' => [],
            'sortOrder' => 999,
            'id' => 'is_dropship'
        ];
        return $jsLayout;
    }

Vendor/Module/etc/frontend/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\Checkout\Block\Checkout\LayoutProcessor">
        <plugin name="vendor_add_custom_field" type="Vendor\Module\Plugin\Checkout\Model\Checkout\LayoutProcessor" sortOrder="100"/>
    </type>
</config>

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\Checkout\Api\Data\ShippingInformationInterface">
        <attribute code="is_dropship" type="string"/>
    </extension_attributes>
</config>

the checkbox is showing fine.

But, When I check and place the order, the value of is_order in sales_order and quote table remain NULL

Best Answer

Probably the problem lies in misunderstanding the power of extension attributes. I assume you think that if you have added extension_attribute configuration in an xml file + you created additional columns in table schema Magento will do the rest. Unfortunately not.

Extension attributes makes interfaces extensible but handling of the logic for these additional attributes lies in hands of developer.

You must take care on how attributes are kept in object's data and how are saved or processed.

So, you have to do, as additional steps:

  1. handle passing data from a checkout form to your extension attribute
  2. handle saving those data eg. by making a plugin for a quoteRepository::save() method

Implementation depends on you.

What you get by using extension attributes is, among others, the ability to call defined methods like $quote->getExtensionAttributes()->[get/set]YourAttribute()

It helps developers because explicit public interface exists.

Magento's mechanism helps extending iterfaces And developer role is to implement and handle logic of these attributes

And some helpful sources:

Related Topic