Updated version! Maybe late, but in Magento 2.3.5 they still haven't fixed it. So here my code. Little bit bulky but its works!
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Customer\Controller\Address\FormPost" type="Vendor\Customer\Controller\Address\FormPost" />
</config>
namespace Vendor\Module\Controller\Address;
/**
* Class FormPost
* @package Vendor\Module\Controller\Address
*/
class FormPost extends \Magento\Customer\Controller\Address\FormPost
{
/**
* @var \Magento\Customer\Model\CustomerFactory
*/
private $_customerFactory;
/**
* @var \Magento\Customer\Model\AddressFactory
*/
private $_addressFactory;
public function __construct(
Context $context,
Session $customerSession,
FormKeyValidator $formKeyValidator,
FormFactory $formFactory,
AddressRepositoryInterface $addressRepository,
AddressInterfaceFactory $addressDataFactory,
RegionInterfaceFactory $regionDataFactory,
DataObjectProcessor $dataProcessor,
DataObjectHelper $dataObjectHelper,
ForwardFactory $resultForwardFactory,
PageFactory $resultPageFactory,
RegionFactory $regionFactory,
HelperData $helperData,
\Magento\Customer\Model\CustomerFactory $customerFactory
) {
parent::__construct(
$context,
$customerSession,
$formKeyValidator,
$formFactory,
$addressRepository,
$addressDataFactory,
$regionDataFactory,
$dataProcessor,
$dataObjectHelper,
$resultForwardFactory,
$resultPageFactory,
$regionFactory,
$helperData
);
$this->_customerFactory = $customerFactory;
}
/**
* Extract address from request
*
* @return \Magento\Customer\Api\Data\AddressInterface
*/
protected function _extractAddress()
{
$existingAddressData = $this->getExistingAddressData();
unset($existingAddressData['id']);
/** @var \Magento\Customer\Model\Metadata\Form $addressForm */
$addressForm = $this->_formFactory->create(
'customer_address',
'customer_address_edit',
$existingAddressData
);
$addressData = $addressForm->extractData($this->getRequest());
$attributeValues = $addressForm->compactData($addressData);
$this->updateRegionData($attributeValues);
$billingParam = $this->getRequest()->getParam('default_billing');
$shippingParam = $this->getRequest()->getParam('default_shipping');
$customerId = $this->_getSession()->getCustomerId();
$customer = $this->_customerFactory->create()->load($customerId);
if ($shippingParam) {
$addressDataObject['attributeValues'] = $attributeValues;
if ($customer->getDefaultShippingAddress() && $customer->getDefaultShippingAddress()->getId() != $customer->getDefaultBillingAddress()->getId()) {
$addressDataObject['default_shipping'] = $this->addressDataFactory->create()->setId($customer->getDefaultShippingAddress()->getId());
} else {
$addressDataObject['default_shipping'] = $this->addressDataFactory->create();
}
$shippingData = array_merge($existingAddressData, $attributeValues);
$addressDataObject['default_shipping']->getId();
$this->dataObjectHelper->populateWithArray(
$addressDataObject['default_shipping'],
$shippingData,
\Magento\Customer\Api\Data\AddressInterface::class
);
$addressDataObject['default_shipping']->setCustomerId($this->_getSession()->getCustomerId())
->setIsDefaultShipping(
$this->getRequest()->getParam(
'default_shipping',
isset($existingAddressData['default_shipping']) ? $existingAddressData['default_shipping'] : false
)
);
}
if ($billingParam) {
$addressDataObject['attributeValues'] = $attributeValues;
if ($customer->getDefaultBillingAddress() && $customer->getDefaultShippingAddress()->getId() != $customer->getDefaultBillingAddress()->getId()) {
$addressDataObject['default_billing'] = $this->addressDataFactory->create()->setId($customer->getDefaultBillingAddress()->getId());
} else {
$addressDataObject['default_billing'] = $this->addressDataFactory->create();
}
$billingData = array_merge($existingAddressData, $attributeValues);
$this->dataObjectHelper->populateWithArray(
$addressDataObject['default_billing'],
$billingData,
\Magento\Customer\Api\Data\AddressInterface::class
);
$addressDataObject['default_billing']->setCustomerId($this->_getSession()->getCustomerId())
->setIsDefaultBilling(
$this->getRequest()->getParam(
'default_billing',
isset($existingAddressData['default_billing']) ? $existingAddressData['default_billing'] : false
)
);
}
if (!$shippingParam && !$billingParam) {
$addressDataObject = $this->addressDataFactory->create();
$this->dataObjectHelper->populateWithArray(
$addressDataObject,
array_merge($existingAddressData, $attributeValues),
\Magento\Customer\Api\Data\AddressInterface::class
);
$addressDataObject->setCustomerId($this->_getSession()->getCustomerId())
->setIsDefaultBilling(
$this->getRequest()->getParam(
'default_billing',
isset($existingAddressData['default_billing']) ? $existingAddressData['default_billing'] : false
)
)
->setIsDefaultShipping(
$this->getRequest()->getParam(
'default_shipping',
isset($existingAddressData['default_shipping']) ? $existingAddressData['default_shipping'] : false
)
);
}
return $addressDataObject;
}
/**
* Process address form save
*
* @return \Magento\Framework\Controller\Result\Redirect
*/
public function execute()
{
$redirectUrl = null;
if (!$this->_formKeyValidator->validate($this->getRequest())) {
return $this->resultRedirectFactory->create()->setPath('*/*/');
}
if (!$this->getRequest()->isPost()) {
$this->_getSession()->setAddressFormData($this->getRequest()->getPostValue());
return $this->resultRedirectFactory->create()->setUrl(
$this->_redirect->error($this->_buildUrl('*/*/edit'))
);
}
try {
$address = $this->_extractAddress();
if (array_key_exists('attributeValues', $address)) {
if (array_key_exists('default_shipping', $address['attributeValues'])) {
if (array_key_exists('default_billing', $address)) {
$this->_addressRepository->save($address['default_billing']);
}
if (array_key_exists('default_shipping', $address)) {
$this->_addressRepository->save($address['default_shipping']);
}
}
else {
if (array_key_exists('default_shipping', $address)) {
$this->_addressRepository->save($address['default_shipping']);
}
if (array_key_exists('default_billing', $address)) {
$this->_addressRepository->save($address['default_billing']);
}
}
} elseif (!array_key_exists('default_shipping', $address) && !array_key_exists('default_billing', $address)) {
$this->_addressRepository->save($address);
}
$this->messageManager->addSuccessMessage(__('You saved the address.'));
$url = $this->_buildUrl('*/*/index', ['_secure' => true]);
return $this->resultRedirectFactory->create()->setUrl($this->_redirect->success($url));
} catch (InputException $e) {
$this->messageManager->addErrorMessage($e->getMessage());
foreach ($e->getErrors() as $error) {
$this->messageManager->addErrorMessage($error->getMessage());
}
} catch (\Exception $e) {
$redirectUrl = $this->_buildUrl('*/*/index');
$this->messageManager->addExceptionMessage($e, __('We can\'t save the address.'));
}
$url = $redirectUrl;
if (!$redirectUrl) {
$this->_getSession()->setAddressFormData($this->getRequest()->getPostValue());
$url = $this->_buildUrl('*/*/edit', ['id' => $this->getRequest()->getParam('id')]);
}
return $this->resultRedirectFactory->create()->setUrl($this->_redirect->error($url));
}
}