Magento 2.2 – Add New Address Type to Customer

customer-addressmagento2.2quotesales-order

I want to Create a new address type "neighbors address / alternate address " . To assign it to customer i have created new customer attribute ( just like "default_shipping" and "default_billing" ) "alternate_address" and saved address_id against it . But how to integrate it with Quote and order . They only save a string "shipping or billing" in address_type column . Where i would like to have it as alternate

Best Answer

To solve the issue i created a plugin

<type name="Magento\Sales\Model\Order\Address\Validator">
    <plugin  name="Mycompany_Sales_after_validator" sortOrder="10" type="MyCompany\Sales\Plugin\Magento\Sales\Model\Order\Address\Validator"/>
</type>

And in plugin class

namespace MyCompany\Sales\Plugin\Magento\Sales\Model\Order\Address;

use Magento\Sales\Model\Order\Address;
use Magento\Sales\Model\Order\Address\Validator as parentValidator;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Validator\EmailAddress;

/**
 * Class Validator
 * @package MyCompany\Sales\Plugin\Magento\Sales\Model\Order\Address
 */
class Validator
{
    const REGISTRED_ADDRESS = 'alternate';
    /**
     * @var array
     */
    protected $required = [
        'parent_id' => 'Parent Order Id',
        'postcode' => 'Zip code',
        'lastname' => 'Last name',
        'street' => 'Street',
        'city' => 'City',
        'email' => 'Email',
        'country_id' => 'Country',
        'firstname' => 'First Name',
        'address_type' => 'Address Type',
    ];


    /**
     * @param Address\Validator $subject subject
     * @param callable          $proceed Closure
     * @param Address           $address Address
     * @return array
     * @throws LocalizedException
     * @throws \Zend_Validate_Exception
     */
    public function aroundValidate(
        parentValidator $subject,
        callable $proceed,
        Address $address
    ) {
        $warnings = [];
        foreach ($this->required as $code => $label) {
            if (!$address->hasData($code)) {
                $warnings[] = sprintf('%s is a required field', $label);
            }
        }

        if (!\Zend_Validate::is($address->getEmail(), EmailAddress::class)) {
            $warnings[] = 'Email has a wrong format';
            throw new LocalizedException(__('Please enter a valid email address.'));
        }
        if (!in_array($address->getAddressType(), [
                                                   Address::TYPE_BILLING,
                                                   Address::TYPE_SHIPPING,
                                                   self::REGISTRED_ADDRESS,
            ])) {
            $warnings[] = 'Address type doesn\'t match required options';
        }

        return $warnings;
    }//end aroundValidate()


}//end class

This is old implementation(In after plugin there were no input parameter) and might not be best implementation. Try if you can avoid around plugin and also call proceed .

Related Topic