1

I am trying to add a custom field in shipping information however the field is not stored in address_quote table where I have created the column. Can someone guide me through?

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="address_type" type="Demo\CustomAddressField\Plugin\Block\Checkout\LayoutProcessor" sortOrder="100"/>
    </type>
    <type name="Magento\Checkout\Model\ShippingInformationManagement">
        <plugin name="save_to_quote_table" type="Demo\CustomAddressField\Plugin\Checkout\Model\ShippingInformationManagement" sortOrder="10" />
    </type>
</config>

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\Quote\Api\Data\AddressInterface">
        <attribute code="address_location_type" type="string" />
    </extension_attributes>
    <extension_attributes for="Magento\Sales\Api\Data\OrderAddressInterface">
        <attribute code="address_location_type" type="string" />
    </extension_attributes>
    <extension_attributes for="Magento\Customer\Api\Data\AddressInterfacee">
        <attribute code="address_location_type" type="string" />
    </extension_attributes>
    <extension_attributes for="Magento\Checkout\Api\Data\ShippingInformationInterface">
        <attribute code="address_location_type" type="string" />
    </extension_attributes>
</config>

fieldset.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:DataObject/etc/fieldset.xsd">
    <scope id="global">
        <fieldset id="sales_convert_quote_address">
            <field name="address_location_type">
                <aspect name="to_order_address" />
                <aspect name="to_customer_address" />
            </field>
        </fieldset>
    </scope>
</config>

Demo\CustomAddressField\Plugin\Block\Checkout\LayoutProcessor.php

<?php

namespace Demo\CustomAddressField\Plugin\Block\Checkout;

use Magento\Checkout\Block\Checkout\LayoutProcessor as CheckoutLayoutProcessor;

class LayoutProcessor{
    
    public function afterProcess(CheckoutLayoutProcessor $subject, array $jsLayout)
    {

        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
        ['shippingAddress']['children']['shipping-address-fieldset']['children']['address_location_type'] = [
            'component' => 'Magento_Ui/js/form/element/select',
            'config' => [
                'customScope' => 'shippingAddress.custom_attributes',
                'template' => 'ui/form/field',
                'elementTmpl' => 'ui/form/element/select',
                'id' => 'address_location_type',
                'tooltip' => [
                    'description' => 'Select the type of address',
                ],
            ],
            'dataScope' => 'shippingAddress.custom_attributes.address_location_type',
            'value' => "Please Select Address Type",
            'options' =>  [
                '1' => [
                    'value' => 'home',
                    'label' => 'Home'
                ],
                '2' => [
                    'value' => 'office',
                    'label' => 'Office'
                ]
            ],
            'label' => 'Address Type',
            'provider' => 'checkoutProvider',
            'visible' => true,
            'validation' => [
                'required-entry' => false
            ],
            'sortOrder' => 252,
            'id' => 'address_location_type'
        ];
        return $jsLayout;
    }

}

Demo\CustomAddressField\Plugin\Checkout\Model\ShippingInformationManagement.php

<?php

namespace Demo\CustomAddressField\Plugin\Checkout\Model;

use Magento\Quote\Model\QuoteRepository;
use \Psr\Log\LoggerInterface;

class ShippingInformationManagement{
    
    protected $quoteRepository;
    protected $logger;

    public function __construct(QuoteRepository $quoteRepository,  LoggerInterface $logger) {
        $this->quoteRepository = $quoteRepository;
        $this->logger = $logger;
    }

    public function beforeSaveAddressInformation(
        \Magento\Checkout\Model\ShippingInformationManagement $subject,
        $cartId,
        \Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation
    ) {
        if(!$extAttributes = $addressInformation->getExtensionAttributes())
        {
            return;
        }

        $quote = $this->quoteRepository->getActive($cartId);

        $quote->setAddressLocationType($extAttributes->getAddressLocationType());
    }
}

UpgradeSchema.php

<?php

namespace Demo\CustomAddressField\Setup;

use Magento\Framework\Setup\UpgradeSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\DB\Ddl\Table;

class UpgradeSchema implements UpgradeSchemaInterface
{
    /**
     * {@inheritdoc}
     */
    public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();

        if(version_compare($context->getVersion(), '1.0.0', '<')){
            $connection = $setup->getConnection();

            $connection->addColumn(
                $setup->getTable('quote_address'),
                'address_location_type',
                [
                    'type' => Table::TYPE_TEXT,
                    'length' => 255,
                    'nullable' => true,
                    'default' => '',
                    'comment' => 'Address Location Type'
                ]
            );
            
            $connection->addColumn(
                $setup->getTable('sales_order_address'),
                'address_location_type',
                [
                    'type' => Table::TYPE_TEXT,
                    'length' => 255,
                    'nullable' => true,
                    'default' => '',
                    'comment' => 'Address Location Type'
                ]
            );
        }
        
        $setup->endSetup();
    }
}

view/frontend/web/js/set-shipping-information-mixin.js

/*jshint browser:true jquery:true*/
/*global alert*/
define([
    'jquery',
    'mage/utils/wrapper',
    'Magento_Checkout/js/model/quote'
], function ($, wrapper, quote) {
    'use strict';

    return function (setShippingInformationAction) {

        return wrapper.wrap(setShippingInformationAction, function (originalAction) {
            var shippingAddress = quote.shippingAddress();
            if (shippingAddress['extension_attributes'] === undefined) {
                shippingAddress['extension_attributes'] = {};
            }

            var attribute = shippingAddress.customAttributes.find(
                function (element) {
                    return element.attribute_code === 'address_location_type';
                }
            );
            
            shippingAddress['extension_attributes']['address_location_type'] = attribute.value;
            // pass execution to original action ('Magento_Checkout/js/action/set-shipping-information')
            return originalAction();
        });
    };
});

payload-extender-mixin.js

define([
    'jquery',
    'mage/utils/wrapper'
], function (
    jQuery,
    wrapper
) {
    'use strict';

    return function (processor) {
        return wrapper.wrap(processor, function (proceed, payload) {
            payload = proceed(payload);

            var shippingAddress =  payload.addressInformation.shipping_address;
            var addressLocationType = jQuery('[name="custom_attributes[address_location_type]"]').val();

            if(addressLocationType == "" || addressLocationType == null){
                if(shippingAddress.customAttributes == "undefined" || shippingAddress.customAttributes == null){
                    addressLocationType = null;
                } else {
                    if(shippingAddress.customAttributes.address_location_type == "undefined" || shippingAddress.customAttributes.address_location_type == null) {
                        addressLocationType = null;
                    } else {
                        addressLocationType = shippingAddress.customAttributes.address_location_type.value;
                    }
                }
            }

            console.log(addressLocationType);

            var goneExtentionAttributes = {
                'address_location_type': addressLocationType
            };
    
            payload.addressInformation.extension_attributes = _.extend(
                payload.addressInformation.extension_attributes,
                goneExtentionAttributes
            );

            return payload;
        });
    };
});

requirejs-config.js

var config = {
    config: {
        mixins: {
            'Magento_Checkout/js/action/set-shipping-information': {
                'Demo_CustomAddressField/js/action/set-shipping-information-mixin': true
            },
            'Magento_Checkout/js/model/shipping-save-processor/payload-extender': {
                'Demo_CustomAddressField/js/model/shipping-save-processor/payload-extender-mixin': true
            }
        }
    }
};

The field is rendered at checkout and the values are flowing well. However, the value is not stored in quote_address table. It stores NULL over there. Can someone guide me what I am doing wrong?

2 Answers 2

1

This line will save data in the quote table:

$quote->setAddressLocationType($extAttributes->getAddressLocationType());

If you want to save in the shipping address table, then try the following way:

$address = $addressInformation->getShippingAddress();
$address->setAddressLocationType($extAttributes->getAddressLocationType());

Check more detail on saveAddressInformation method

1
  • Thank you, I am able to save the value in quote, However, I am not sure how to retrieve it in my observer file. Its not available in quote, can you guide how to fetch value from quote_address and store it in sales_order_address?
    – Dexter
    Jul 12, 2021 at 13:36
0

Step 1. Create your_module_name/view/frontend/requirejs-config.js

var config = {
config: {
mixins: {
‘Magento_Checkout/js/action/set-shipping-information’: {
‘/js/action/set-shipping-information-mixin’: true
}
}
}
};

Step 2. Create your_module_name/js/action/set-shipping-information-mixin.js

define([
‘jquery’,
‘mage/utils/wrapper’,
‘Magento_Checkout/js/model/quote’
], function ($, wrapper, quote) {
‘use strict’;
return function (setShippingInformationAction) {
return wrapper.wrap(setShippingInformationAction, function (originalAction) {
var shippingAddress = quote.shippingAddress();
if (shippingAddress[‘extension_attributes’] === undefined) {
shippingAddress[‘extension_attributes’] = {};
}
shippingAddress[‘extension_attributes’][‘custom_field’] = shippingAddress.customAttributes[‘custom_field’];
// pass functionality to original action (‘Magento_Checkout/js/action/set-shipping-information’)
return originalAction();
});
};
});

Step 3. Create your_module_name/etc/extension_attributes.xml

To access your data on backend you can use:

$value = $address->getExtensionAttributes()->getCustomField();

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.