0

I have created one custom module, in that module I have created custom attribute, name like "landmark", for frontend and admin customer, this attribute display at frontend customer address section and admin customer address section, now I want to save that attribute value in 3 tables, customer_address_entity, quote_address, sales_order_address,

for that I have do some code,

UpgradeData.php

<?php

namespace My\Customfield\Setup;

use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\UpgradeDataInterface;

class UpgradeData implements UpgradeDataInterface
{
   private $customerSetupFactory;

   public function __construct(\Magento\Customer\Setup\CustomerSetupFactory $customerSetupFactory)
   {
       $this->customerSetupFactory = $customerSetupFactory;
   }

   public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
   {
       $customerSetup = $this->customerSetupFactory->create(['setup' => $setup]);
       //if (version_compare($context->getVersion(), '1.0.1') < 0) {
       if (version_compare($context->getVersion(), '1.2.0', '<')) {
           $customerSetup->addAttribute('customer_address', 'landmark', [
               'label' => 'Landmark',
               'input' => 'text',
               'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
               'size' => 255,
               'length' => 255,
               'source' => '',
               'required' => true,
               'position' => 90,
               'visible' => true,
               'system' => false,
               'is_used_in_grid' => false,
               'is_visible_in_grid' => false,
               'is_filterable_in_grid' => false,
               'is_searchable_in_grid' => false,
               'frontend_input' => 'text',
               'backend' => ''
           ]);

           // Get the attribute instance
           $attribute = $customerSetup->getEavConfig()
                ->getAttribute('customer_address', 'landmark');

           // Add the attribute to the necessary forms
           $attribute->setData('used_in_forms', [
                'adminhtml_customer_address',
                'adminhtml_customer',
                'customer_address_edit',
                'customer_register_address',
                'customer_address',
                'checkout_register',
                'checkout_shipping_address',
                'customer_register_edit',
                'adminhtml_checkout'
            ]);

           // Save the attribute
           $attribute->save();

           // Get the setup connection
           $connection = $setup->getConnection();

           // Add the landmark column to customer_address_entity table
           $connection->addColumn(
               $setup->getTable('customer_address_entity'),
               'landmark',
               [
                   'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                   'size' => 255,
                   'length' => 255,
                   'nullable' => true,
                   'comment' => 'Landmark'
               ]
           );

           // Add the landmark column to quote_address table
           $connection->addColumn(
               $setup->getTable('quote_address'),
               'landmark',
               [
                   'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                   'size' => 255,
                   'length' => 255,
                   'nullable' => true,
                   'comment' => 'Landmark'
               ]
           );

           // Add the landmark column to sales_order_address table
           $connection->addColumn(
               $setup->getTable('sales_order_address'),
               'landmark',
               [
                   'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                   'size' => 255,
                   'length' => 255,
                   'nullable' => true,
                   'comment' => 'Landmark'
               ]
           );
       }
   }
}

app/code/My/Customfield/view/frontend/layout/customer_address_form.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="customer_address_edit" >
           <action method="setTemplate">
              <argument name="template" xsi:type="string">
                 My_Customfield::address/edit.phtml
              </argument>
           </action>
       </referenceBlock>
    </body>
</page>

app/code/My/Customfield/view/frontend/layout/my_customfield_order_view.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="order_info">
            <block class="My\Customfield\Block\Order\Landmark" name="my_customfield_landmark" template="My_Customfield::order/view/landmark.phtml" after="order_payment"></block>
        </referenceBlock>
    </body>
</page>

My/Customfield/view/frontend/templates/address/edit.phtml

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

/** @var \Magento\Customer\Block\Address\Edit $block */
/** @var \Magento\Customer\ViewModel\Address $viewModel */
/** @var \Magento\Framework\Escaper $escaper */
/** @var \Magento\Framework\View\Helper\SecureHtmlRenderer $secureRenderer */
/** @var \Magento\Customer\ViewModel\Address\RegionProvider $regionProvider */
$viewModel = $block->getViewModel();
$regionProvider = $block->getRegionProvider();
?>
<?php $_company = $block->getLayout()->createBlock(\Magento\Customer\Block\Widget\Company::class) ?>
<?php $_telephone = $block->getLayout()->createBlock(\Magento\Customer\Block\Widget\Telephone::class) ?>
<?php $_fax = $block->getLayout()->createBlock(\Magento\Customer\Block\Widget\Fax::class) ?>
<?php $_country_id = $block->getAttributeData()->getFrontendLabel('country_id'); ?>
<?php $_street = $block->getAttributeData()->getFrontendLabel('street'); ?>
<?php $_city = $block->getAttributeData()->getFrontendLabel('city'); ?>
<?php $_region = $block->getAttributeData()->getFrontendLabel('region'); ?>
<?php $_selectRegion = 'Please select a region, state or province.'; ?>
<?php $_displayAll = $block->getConfig('general/region/display_all'); ?>

<?php $_vatidValidationClass = $viewModel->addressGetAttributeValidationClass('vat_id'); ?>
<?php $_cityValidationClass = $viewModel->addressGetAttributeValidationClass('city'); ?>
<?php $_postcodeValidationClass_value = $viewModel->addressGetAttributeValidationClass('postcode'); ?>
<?php $_postcodeValidationClass = $_postcodeValidationClass_value; ?>
<?php $_streetValidationClass = $viewModel->addressGetAttributeValidationClass('street'); ?>
<?php $_streetValidationClassNotRequired = $_streetValidationClass !== null ?
    trim(str_replace('required-entry', '', $_streetValidationClass)) : ''; ?>
<?php $_regionValidationClass = $viewModel->addressGetAttributeValidationClass('region'); ?>
<form class="form-address-edit"
      action="<?= $escaper->escapeUrl($block->getSaveUrl()) ?>"
      method="post"
      id="form-validate"
      enctype="multipart/form-data"
      data-hasrequired="<?= $escaper->escapeHtmlAttr(__('* Required Fields')) ?>">
    <fieldset class="fieldset">
        <legend class="legend"><span><?= $escaper->escapeHtml(__('Contact Information')) ?></span></legend><br>
        <?= $block->getBlockHtml('formkey') ?>
        <input type="hidden" name="success_url" value="<?= $escaper->escapeUrl($block->getSuccessUrl()) ?>">
        <input type="hidden" name="error_url" value="<?= $escaper->escapeUrl($block->getErrorUrl()) ?>">
        <?= $block->getNameBlockHtml() ?>

        <?php if ($_company->isEnabled()): ?>
            <?= $_company->setCompany($block->getAddress()->getCompany())->toHtml() ?>
        <?php endif ?>

        <?php if ($_telephone->isEnabled()): ?>
            <?= $_telephone->setTelephone($block->getAddress()->getTelephone())->toHtml() ?>
        <?php endif ?>

        <?php if ($_fax->isEnabled()): ?>
            <?= $_fax->setFax($block->getAddress()->getFax())->toHtml() ?>
        <?php endif ?>

    </fieldset>
    <fieldset class="fieldset">
        <legend class="legend"><span><?= $escaper->escapeHtml(__('Address')) ?></span></legend><br>
        <div class="field street required">
            <label for="street_1" class="label"><span><?= /* @noEscape */ $_street ?></span></label>
            <div class="control">
                <div class="field primary">
                    <label for="street_1" class="label">
                        <span>
                            <?= $escaper->escapeHtml(__('Street Address: Line %1', 1)) ?>
                        </span>
                    </label>
                </div>
                <input type="text"
                       name="street[0]"
                       value="<?= $escaper->escapeHtmlAttr($block->getStreetLine(1)) ?>"
                       title="<?= /* @noEscape */ $_street ?>"
                       id="street_1"
                       class="input-text <?= $escaper->escapeHtmlAttr($_streetValidationClass) ?>"/>
                <div class="nested">
                    <?php for ($_i = 1, $_n = $viewModel->addressGetStreetLines(); $_i < $_n; $_i++): ?>
                        <div class="field additional">
                            <label class="label" for="street_<?= /* @noEscape */ $_i + 1 ?>">
                                <span><?= $escaper->escapeHtml(__('Street Address: Line %1', $_i + 1)) ?></span>
                            </label>
                            <div class="control">
                                <input type="text" name="street[<?= /* @noEscape */ $_i ?>]"
                                       value="<?= $escaper->escapeHtmlAttr($block->getStreetLine($_i + 1)) ?>"
                                       title="<?= $escaper->escapeHtmlAttr(__('Street Address %1', $_i + 1)) ?>"
                                       id="street_<?= /* @noEscape */ $_i + 1 ?>"
                                       class="input-text
                                        <?= $escaper->escapeHtmlAttr($_streetValidationClassNotRequired) ?>">
                            </div>
                        </div>
                    <?php endfor; ?>
                </div>
            </div>
        </div>

        <?php if ($viewModel->addressIsVatAttributeVisible()): ?>
            <div class="field taxvat">
                <label class="label" for="vat_id">
                    <span><?= /* @noEscape */ $block->getAttributeData()->getFrontendLabel('vat_id') ?></span>
                </label>
                <div class="control">
                    <input type="text"
                           name="vat_id"
                           value="<?= $escaper->escapeHtmlAttr($block->getAddress()->getVatId()) ?>"
                           title="<?= /* @noEscape */ $block->getAttributeData()->getFrontendLabel('vat_id') ?>"
                           class="input-text <?= $escaper->escapeHtmlAttr($_vatidValidationClass) ?>"
                           id="vat_id">
                </div>
            </div>
        <?php endif; ?>
        <div class="field country required">
            <label class="label" for="country">
                <span><?= /* @noEscape */ $block->getAttributeData()->getFrontendLabel('country_id') ?></span>
            </label>
            <div class="control">
                <?= $block->getCountryHtmlSelect() ?>
            </div>
        </div>
        <div class="field region required">
            <label class="label" for="region_id">
                <span><?= /* @noEscape */ $_region ?></span>
            </label>
            <div class="control">
                <select id="region_id" name="region_id"
                        title="<?= /* @noEscape */ $_region ?>"
                        class="validate-select region_id"
                        <?= /* @noEscape */ !$_displayAll ? ' disabled="disabled"' : '' ?>>
                    <option value=""><?= $escaper->escapeHtml(__($_selectRegion)) ?></option>
                </select>
                <input type="text"
                       id="region"
                       name="region"
                       value="<?= $escaper->escapeHtmlAttr($block->getRegion()) ?>"
                       title="<?= /* @noEscape */ $_region ?>"
                       class="input-text validate-not-number-first
                        <?= $escaper->escapeHtmlAttr($_regionValidationClass) ?>"
                        <?= !$_displayAll ? ' disabled="disabled"' : '' ?>/>
            </div>
        </div>
        <div class="field city required">
            <label class="label" for="city">
                <span><?= /* @noEscape */ $block->getAttributeData()->getFrontendLabel('city') ?></span>
            </label>
            <div class="control">
                <input type="text"
                       name="city"
                       value="<?= $escaper->escapeHtmlAttr($block->getAddress()->getCity()) ?>"
                       title="<?= $escaper->escapeHtmlAttr(__('City')) ?>"
                       class="input-text <?= $escaper->escapeHtmlAttr($_cityValidationClass) ?>"
                       id="city">
            </div>
        </div>
        <div class="field zip required">
            <label class="label" for="zip">
                <span><?= /* @noEscape */ $block->getAttributeData()->getFrontendLabel('postcode') ?></span>
            </label>
            <div class="control">
                <input type="text"
                       name="postcode"
                       value="<?= $escaper->escapeHtmlAttr($block->getAddress()->getPostcode()) ?>"
                       title="<?= /* @noEscape */ $block->getAttributeData()->getFrontendLabel('postcode') ?>"
                       id="zip"
                       class="input-text validate-zip-international
                        <?= $escaper->escapeHtmlAttr($_postcodeValidationClass) ?>">
                <div role="alert" class="message warning">
                    <span></span>
                </div>
                <?= /* @noEscape */ $secureRenderer->renderStyleAsTag("display: none;", 'div.message.warning') ?>
            </div>
        </div>
        
    <!-- Landmark Custom Field  -->
        <div class="field">
            <label class="label" for="landmark">Landmark</label>
            <?php $landmarkAttribute = $block->getAddress()->getCustomAttribute('landmark'); ?>
            <input type="text" name="landmark" value="<?php echo $block->escapeHtml($landmarkAttribute ? $landmarkAttribute->getValue() : ''); ?>"/>
        </div>
    <!-- Landmark Custom Field  -->
        
        <?php if ($block->isDefaultBilling()): ?>
            <div class="message info">
                <span><?= $escaper->escapeHtml(__("It's a default billing address.")) ?></span>
            </div>
        <?php elseif ($block->canSetAsDefaultBilling()): ?>
            <div class="field choice set billing">
                <input type="checkbox" id="primary_billing" name="default_billing" value="1" class="checkbox">
                <label class="label" for="primary_billing">
                    <span><?= $escaper->escapeHtml(__('Use as my default billing address')) ?></span>
                </label>
            </div>
        <?php else: ?>
            <input type="hidden" name="default_billing" value="1" />
        <?php endif; ?>

        <?php if ($block->isDefaultShipping()): ?>
            <div class="message info">
                <span><?= $escaper->escapeHtml(__("It's a default shipping address.")) ?></span>
            </div>
        <?php elseif ($block->canSetAsDefaultShipping()): ?>
            <div class="field choice set shipping">
                <input type="checkbox" id="primary_shipping" name="default_shipping" value="1" class="checkbox">
                <label class="label" for="primary_shipping">
                    <span><?= $escaper->escapeHtml(__('Use as my default shipping address')) ?></span>
                </label>
            </div>
        <?php else: ?>
            <input type="hidden" name="default_shipping" value="1">
        <?php endif; ?>
    </fieldset>
    <div class="actions-toolbar">
        <div class="primary">
            <button type="submit"
                    class="action save primary"
                    data-action="save-address"
                    disabled="disabled"
                    title="<?= $escaper->escapeHtmlAttr(__('Save Address')) ?>">
                <span><?= $escaper->escapeHtml(__('Save Address')) ?></span>
            </button>
        </div>
        <div class="secondary">
            <a class="action back" href="<?= $escaper->escapeUrl($block->getBackUrl()) ?>">
                <span><?= $escaper->escapeHtml(__('Go back')) ?></span>
            </a>
        </div>
    </div>
</form>
<script type="text/x-magento-init">
    {
        "#form-validate": {
            "addressValidation": {
                "postCodes": <?= /* @noEscape */ $block->getPostCodeConfig()->getSerializedPostCodes() ?>
            }
        },
        "#country": {
            "directoryRegionUpdater": {
                "optionalRegionAllowed": <?= /* @noEscape */ $_displayAll ? 'true' : 'false' ?>,
                "regionListId": "#region_id",
                "regionInputId": "#region",
                "postcodeId": "#zip",
                "form": "#form-validate",
                "regionJson": <?= /* @noEscape */ $regionProvider->getRegionJson(); ?>,
                "defaultRegion": "<?= (int) $block->getRegionId() ?>",
                "countriesWithOptionalZip": <?= /* @noEscape */ $viewModel->dataGetCountriesWithOptionalZip(true) ?>
            }
        }
    }
</script>

My/Customfield/view/frontend/templates/order/view.phtml

<?php
    // Retrieve the shipping address from the order
    $shippingAddress = $_order->getShippingAddress();
    if ($shippingAddress) {
        // Retrieve the landmark attribute value
        $landmark = $shippingAddress->getCustomAttribute('landmark');
        if ($landmark) {
            // Display the landmark value
            echo "<div class='landmark'>";
            echo "<strong>Landmark:</strong> " . $block->escapeHtml($landmark->getValue());
            echo "</div>";
        }
    }
?>

/My/Customfield/view/base/ui_component/customer_address_form.xml

<?xml version="1.0"?>
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <fieldset name="custom_fields">
        <field name="landmark" sortOrder="100" formElement="input">
            <settings>
                <visible>true</visible>
                <label translate="true">Landmark</label>
            </settings>
        </field>
    </fieldset>
</form>

/My/Customfield/view/adminhtml/layout/sales_order_view.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="content">
            <referenceBlock name="order_tab_info">
                <referenceBlock name="order_info">
                    <container name="shipping_address" as="shipping_address" label="Shipping Address" htmlTag="div" htmlClass="shipping-address order-address">
                        <block class="My\Customfield\Block\Order\View\Landmark" name="order_shipping_view_landmark" template="My_Customfield::order/view/landmark.phtml" before="-">
                            <arguments>
                                <argument name="title" xsi:type="string" translate="true">Landmark</argument>
                                <argument name="order_data" xsi:type="string">shipping_address</argument>
                            </arguments>
                        </block>
                    </container>
                </referenceBlock>
            </referenceBlock>
        </referenceContainer>
    </body>
</page>

/My/Customfield/view/adminhtml/templates/order/view/landmark.phtml

<?php $landmarkAttribute = $block->getOrder()->getShippingAddress()->getCustomAttribute('landmark'); ?>
<?php if ($landmarkAttribute): ?>
    <div class="admin__field">
        <strong class="admin__field-label"><?= __('Landmark') ?>:</strong>
        <div class="admin__field-value"><?= $block->escapeHtml($landmarkAttribute->getValue()) ?></div>
    </div>
<?php endif; ?>

this code saves the attribute value in customer_address_entity_text table not the other 3 table, please help me with this, what mistake I do here?

2 Answers 2

0

you can check below reference for add custom field in customer address section.

1
  • i have already added custom attribute, but its value not saved in the database. Jun 27, 2023 at 11:48
0

Attribute value saves into quote_address and sales_order_address during the checkout process. Select the address from the checkout page then select the address data set in the quote_address table After the quote converts into order the address data is set into the sales_order_address table.

Please check after place order

7
  • thanks for your answer, but in customer_address_entity table store value when customer save the address from frontend, that is also not saves the value. Jun 27, 2023 at 8:47
  • When saving the customer address from the frontend, It will not affect the quote and sales tables.
    – MP Raj
    Jun 27, 2023 at 9:13
  • yes right, but my question is, in my code what I have done mistake, that not saved the value in customer_address_entity table after save address customer side? Jun 27, 2023 at 9:15
  • Can you please check this link : integerbyteblog.in/magento/…
    – MP Raj
    Jun 27, 2023 at 9:18
  • i have checked this, but did not understand exactly. Jun 27, 2023 at 9:19

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.