is there a way to prevent Billing Address modification by all users?
After entering billing address in registration i don't want to let users modificate it.
Thank you very much.
Disable Billing Address Edit in Magento
addressbilling-addresscustomercustomer-accountedit
Related Solutions
I think you are asking two questions. I'll try to answer the first one. This is how I tried to always use the default billing address:
As far as I know a billing address is tied to the chosen payment method. In order to disallow the customer to change the billing address, I made two changes:
- Configure the payment method not to use a billing address
- Add an interceptor plugin to the setBillingAddress function of the \Magento\Quote\Model\Quote class which always inserts the default billing address The interceptor is needed, because the standard shipping address is still used instead of the standard billing address.
1.
This can be accomplished by overriding the isBillingAddressRequired property of the checkout layout. For example when using the Magento_OfflinePayments module as a payment option: Copy the xml code of magento2ce/vendor/magento/module-offline-payments/view/frontend/layout/checkout_index_index.xml to /app/design/frontend/{YOUR_VENDOR}/{YOUR_THEME}/Magento_OfflinePayments/layout/checkout_index_index.xml and set the true booleans to false. This
2.
I used http://alanstorm.com/magento_2_object_manager_plugin_system as a guide for setting up the Interceptor:
<?php
namespace {YOUR_VENDOR}\{YOUR_MODULE}\Model\Quote;
use Magento\Customer\Api\AddressRepositoryInterface;
use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Customer\Api\Data\CustomerInterface;
use Magento\Customer\Model\Address;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Exception\LocalizedException;
use Magento\Quote\Api\Data\AddressInterface;
use Magento\Quote\Model\Quote\Interceptor;
class Plugin
{
/** @var CustomerRepositoryInterface */
private $_customerRepository;
/** @var AddressRepositoryInterface */
private $_addressRepository;
/**
* Plugin constructor.
* @param CustomerRepositoryInterface $customerRepository
* @param AddressRepositoryInterface $addressRepository
*/
public function __construct(
CustomerRepositoryInterface $customerRepository,
AddressRepositoryInterface $addressRepository
) {
$this->_customerRepository = $customerRepository;
$this->_addressRepository = $addressRepository;
}
/**
* Interceptor which always sets the default billing address of a customer as the quote/order billing address
* @param Interceptor $subject
* @param AddressInterface $address
* @return $this
*/
public function beforeSetBillingAddress(Interceptor $subject, AddressInterface $address = null)
{
$customerId = $address->getCustomerId();
/** @var CustomerInterface $customer */
$customer = $this->_customerRepository->getById($customerId);
/** @var Address $defaultAddress */
$defaultAddressId = $customer->getDefaultBilling();
/** @var \Magento\Customer\Api\AddressRepositoryInterface $addressRepository */
try {
//This is our Customer Address
$defaultBillingAddress = $this->_addressRepository->getById($defaultAddressId);
//Convert the Customer Address to a Quote Address
//Using the ObjectManager is bad practice, use DI instead, but how?
$objectManager = ObjectManager::getInstance();
/** @var \Magento\Quote\Model\Quote\Address $quoteBillingAddress */
$quoteBillingAddress = $objectManager->create('Magento\Quote\Model\Quote\Address');
$quoteBillingAddress->importCustomerAddressData($defaultBillingAddress);
$address = $quoteBillingAddress;
} catch (LocalizedException $e) {
//Address not found?
}
return [$address];
}
}
I feel this solution is still sub optimal. I hope an interceptor won't be necessary, but maybe this is of use to anyone.
Add This code on your header
<script type="text/javascript">
require(['jquery'],function($){
$(document).ready(function () {
$(document).ajaxComplete(function () {
if($('input#billing-address-same-as-shipping-shared').prop("checked") == true){
}else{
$('input#billing-address-same-as-shipping-shared').trigger('click');
}
});
});
});
</script>
<style type="text/css">
.field._required[name="shippingAddress.city"],.box.box-address-billing { display: none!important; }
.checkout-billing-address { display: none; }
/*.checkout-billing-address { pointer-events: none; display: none; }
input#billing-address-same-as-shipping-shared { opacity: .5; }*/
</style>
Best Answer
Notice
What you're asking for becomes tricky when you consider how Magento manages the billing address. Any address can be a billing address. A customer can simply select it from a menu component at various points in the system (ie: checkout, address book screen).
Even if you restrict editing on the "default billing address," this too creates some overhead for you, given that Magento enables you to set any address in your address book as the default billing address. In other words, a customer could edit a "non-billing" address, then set it as the default billing address. It would be cumbersome for you to write code to manage this.
And are you using any third-party extensions which provide address editing on the front-end? There's a lot to think about here.
A Solution
With the disclaimer out of the way, you can simply prevent the ability to edit an address by modifying 2 templates:
See line 9; here we simply comment out the link to edit the address. Not secure, but gives you a place to start.
Below the title, we add some additional logic that checks if the address being edited is the default billing. If so, it will not render the edit form and instead display a generic message.