Craft CMS Asked on April 13, 2021
I want to try and stop Commerce 3 creating a new customer address if it’s a duplicate of an existing one.
As an example, a store selling digital products has a checkout form that simply asks for the customer’s country, no other address info is required. All we need is one select field for the country (pre-checked if we already have that info). We could add radio buttons to select any previously saved addresses as well as a field to select a (new) country. However, even if we do that, there’s still a chance the user opts to enter a new address and actually submits a duplicate.
I’ve created a plugin that catches a duplicate address and then tries to set the cart’s billingAddressId so a new address isn’t created. What I have so far though doesn’t work. It doesn’t successfully update the billingAddressId
. If I use Craft::$app->getElements()->saveElement($cart)
it results in a loop in this case.
How can I complete this to update the cart, or perhaps the post data in this case, with the matched billingAddressId
?
Event::on(Address::class, Address::EVENT_BEFORE_VALIDATE, function (Event $e) {
$sentCountryId = $e->sender->countryId;
$currentUser = Craft::$app->user;
$cart = craftcommercePlugin::getInstance()->getCarts()->getCart();
$addresses = $cart->customer->addresses;
$match = 0;
// Only check against saved addresses if currentUser has any
if ($currentUser and $addresses) {
// If true, loop saved address to check for a country match
foreach($addresses as $address) {
// Loop until a match is found
if ($match == 0) {
$savedCountryId = $address->countryId;
if ($sentCountryId == $savedCountryId) {
$match = $address->id;
}
}
};
// If there’s a match set the cart’s billingAddressId
// to stop a new address being created:
if ($match) {
$cart->billingAddressId = $match; // This doesn’t work on it’s own
// Craft::$app->getElements()->saveElement($cart); // Results in a loop
$e->handled = true;
}
}
});
If I am reading you right you are wanting to update the shipping address on the order rather than create a new one.
You should be able to do that right now:
{% set cart = craft.commerce.carts.cart %}
{% set flashNotice = craft.app.session.getFlash('notice') %}
{% if flashNotice %}
<div class="bg-blue-500 text-white">
<div class="flash container mx-auto px-6 py-4">
{{ flashNotice }}
</div>
</div>
{% endif %}
{% set flashError = craft.app.session.getFlash('error') %}
{% if flashError %}
<div class="bg-red-500 text-white">
<div class="flash container mx-auto px-6 py-4">
{{ flashError }}
</div>
</div>
{% endif %}
//meat and potatoes:
{{ cart.number }}<br>
Shipping Address ID: {{ cart.shippingAddressId }}
<form method="post">
<input type="hidden" name="action" value="commerce/cart/update-cart"/>
<input type="hidden" name="cartUpdatedNotice" value="The address was updated.">
{{ redirectInput('shop/address') }}
{{ csrfInput() }}
<!-- THIS IS WHAT WILL UPDATE THE ADDRESS VS ADDING A NEW ONE -->
{% if cart.shippingAddress.id %}
<input type="hidden" name="shippingAddress[id]" value="{{cart.shippingAddress.id}}"/>
{% endif %}
First Name:
<input name="shippingAddress[firstName]" value="{{cart.shippingAddress.firstName ?? ''}}"/>
<button type="submit">Update</button>
</form>
As demonstrated above, using an input with name="shippingAddress[id]"
with the address ID set as the value will update the address with that ID on the commerce/cart/update-cart
controller action just fine.
You would only use name="shippingAddressId"
if you wanted to let the user select an existing one.
Answered by Luke Holder on April 13, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP