Say i am in checkout and i go to profile and change my mail id. it doesn't reflect in order mail property.
the user entity in order is updated though. so i use getCustomer() and call getEmail() on the user entity and then set order->setEmail() for this.

But yet to find the correct place to change this behaviour in commerce core. Mostly it might be in orderRefresh ???

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

sumanthkumarc created an issue. See original summary.

mglaman’s picture

Title: updating email in user account, doesn't update email in order mail property » Updating email in user account, doesn't update email in order mail property
Category: Bug report » Feature request

Cross posting my thought from #2873685: Order E-Mail is not set when logging in or registering on Login pane.

A feature would be for commerce_order to check if a user has changed their email address. In the event this happens, we load all draft orders which belong to the user and update/sync their email field.

sumanthkumarc’s picture

@matt i actually liked this comment of yours:

so you're suggesting that on order refresh we check if the order has a customer. If it does, then always sync that address. Which fixes issues if an order is re-assigned.

bojanz’s picture

Checked 1.x, and it kept only the cart orders up to date:

/**
 * Implements hook_user_update().
 *
 * When a user account e-mail address is updated, update any shopping cart
 * orders owned by the user account to use the new e-mail address.
 */
function commerce_cart_user_update(&$edit, $account, $category) {
  // If the e-mail address was changed...
  if (!empty($edit['original']->mail) && $account->mail != $edit['original']->mail) {
    // Load the user's shopping cart orders.
    $query = new EntityFieldQuery();

    $query
      ->entityCondition('entity_type', 'commerce_order', '=')
      ->propertyCondition('uid', $account->uid, '=')
      ->propertyCondition('status', array_keys(commerce_order_statuses(array('cart' => TRUE))), 'IN');

    $result = $query->execute();

    if (!empty($result['commerce_order'])) {
      foreach (commerce_order_load_multiple(array_keys($result['commerce_order'])) as $order) {
        if ($order->mail != $account->mail) {
          $order->mail = $account->mail;
          commerce_order_save($order);
        }
      }
    }
  }
}

So some kind of order refresh, Order::preSave() logic would be consistent with that.

steveoliver’s picture

Then aside from carts, @bojanz would the recommendation for this situation be to "reassign" the order to the updated customer (user)? (If you don't know about it already, see the "Reassign" operation, available on the Orders page.)

steveoliver’s picture

Title: Updating email in user account, doesn't update email in order mail property » Updating email in user account, doesn't update email in order (cart) mail property

Disregard my last comment, I see the OP is only concerned with carts, not placed orders.

joachim’s picture

Category: Feature request » Bug report

This is a corner case, granted, but it's surely a bug:

1. user creates a cart
2. user changes their email in their account
3. user completes checkout, and doesn't receive a receipt.

joachim’s picture

Furthermore, this is going to have an effect on recurring orders from Commerce Recurring, where it's definitely NOT a corner case, since an order stays in draft for the whole billing period, which could be something like a year.

vasike’s picture

Status: Active » Needs review
FileSize
3.35 KB

Here is patch for this

Following Bojan's suggestions: Update emails for all not placed orders of the user.

Also removed !$this->getEmail() for updating order

    if (!$this->getEmail() && $customer = $this->getCustomer()) {
      $this->setEmail($customer->getEmail());
    }

And update the Kernel Entity Order test for these changes.

p.s. Not sure about Commerce Recurring cases.

Status: Needs review » Needs work

The last submitted patch, 9: update_customer_user_email-2873526-9.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

joachim’s picture

> p.s. Not sure about Commerce Recurring cases.

Commerce Recurring keeps recurring order in the 'draft' state and with placed = NULL until they are charged to the customer, so the approach in #9 looks ok to me for that case.

vasike’s picture

Status: Needs work » Needs review

It seems the tests fails because of "!$this->getEmail()" removal update.
So we need other approach:
For example extra check for customer mail

    if ($customer = $this->getCustomer()) {
      if ($customer->getEmail()) {
        $this->setEmail($customer->getEmail());
      }
    }

seems to work for CheckoutOrderTest::testGuestOrderCheckout
Could it be this what's needed here?

vasike’s picture

Here is a new patch that should fix the broken test - check directly about the customer email when updating an order.

Status: Needs review » Needs work

The last submitted patch, 13: update_customer_user_email-2873526-13.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

vasike’s picture

Status: Needs work » Needs review
FileSize
3.62 KB

Here is a new updated patch the should fix the tests.

Broken CouponRedemptionPaneTest it should be solved by another patch from other issue.
See #2884210-8: Hide the coupon redemption form behind a link

Status: Needs review » Needs work

The last submitted patch, 15: update_customer_user_email-2873526-15.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

vasike’s picture

Status: Needs work » Needs review

The test fail is not related with an issue.
So i think we're in "Needs review" for now.

joachim’s picture

+++ b/modules/order/commerce_order.module
@@ -57,6 +57,28 @@ function commerce_order_local_tasks_alter(&$definitions) {
+    $order->setEmail($user->getEmail());

Minor optimization: set the user email in a variable rather than keep getting it.

vasike’s picture

@joachim thanks for suggestions.
Here is a new update for the patch : use variable for (customer) user mail value

Status: Needs review » Needs work

The last submitted patch, 19: update_customer_user_email-2873526-19.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

vasike’s picture

Status: Needs work » Needs review

The test fail is not related with an issue.
So i think we're in "Needs review" for now.

jeroendegloire’s picture

Status: Needs review » Needs work

The last submitted patch, 22: update_customer_user_email-2873526-22.patch, failed testing. View results

unrealauk’s picture

Status: Needs review » Needs work

The last submitted patch, 24: update_customer_user_email-2873526-24.patch, failed testing. View results

Neograph734’s picture

I accidentally stumbled upon this issue, but I wanted to shine another light on this issue.

Doesn't commerce fill this data too early? Wouldn't it make sense to copy the customer mail only just before completing the checkout (I understand that potentially interfere with some events).
I also noticed that IP addresses do not update. The IP used during order creation is logged (could even be the admin's), but if I then login to another computer the initial IP address remains in place.

Isn't the data during order checkout more relevant than the data during creation?

It might also be an option to include the email in the profile, that would keep all customer data in one place and visible and easy editable during checkout?

xamount’s picture

I tested the patch at #24 on an install using Commerce recurring. The draft order was successfully updated with the new email. But the original order's email was not.

drupal786’s picture

I have tested #24 and found its throwing error in the hook_ENTITY_TYPE_update for the argument passed, so i have updated the patch slightly to specify exact type of argument and now its working fine for me.

xamount’s picture

See child issue here to update all orders upon customer email change: #3200326: Updating email in Drupal user account doesn't update email in completed orders details

xamount’s picture

Patch in #28 has worked for me (for all commerce recurring draft orders). Thanks!

To get ALL orders updated, in addition to #28 patch, I applied patch from #3200326: Updating email in Drupal user account doesn't update email in completed orders details and it works.

xamount’s picture

Status: Needs work » Needs review
samuhe’s picture

I can confirm the patch in #28 is working.

jsacksick’s picture

Updated the patch to query only for "draft" orders.

Also, querying orders that don't already have the right email.
Fixed the tests.

The only thing I'm wondering is whether this code belong to the cart module (Since the order assignment logic lives there)... But I guess it can stay in the order module as we don't check the "cart" flag.

jsacksick’s picture

FileSize
4.94 KB
1.44 KB

hm... actually, I'm not sure about the order presave change... As this could update the order email of placed orders...

And.. This would actually prevent an actual update from the UI as the value set on the customer would always override the order email.

I think we should either remove the order presave change, or limit it to draft orders.

The attached patch is maintaining the order email only for draft orders. Once an order is no longer a draft, it shouldn't be magically updated...

The last submitted patch, 33: 2873526-33.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 34: 2873526-34.patch, failed testing. View results

mglaman’s picture

  1. +++ b/modules/order/commerce_order.module
    @@ -115,6 +116,33 @@ function commerce_order_field_formatter_info_alter(array &$info) {
    +/**
    + * Implements hook_ENTITY_TYPE_update() for user entities.
    + */
    +function commerce_order_user_update(UserInterface $user) {
    +  // Maintain the email up to date for orders that aren't placed.
    +  if (empty($user->original) || $user->getEmail() == $user->original->getEmail()) {
    +    return;
    +  }
    +
    

    I feel like this could go wrong in many ways. If we have orders ensuring the email is fresh, let's ditch this hook.

    Checkout causes an order to be saved whenever the step changes, or whenever its even refreshed.

  2. +++ b/modules/order/src/Entity/Order.php
    @@ -677,9 +677,14 @@ class Order extends CommerceContentEntityBase implements OrderInterface {
    +    if ($customer->isAuthenticated()) {
    +      if (!$this->getEmail() ||
    +        // Keep the order email updated for draft orders.
    +        ($this->getEmail() != $customer->getEmail() && $this->getState()->getId() === 'draft')) {
    +        $this->setEmail($customer->getEmail());
    +      }
    

    We could move this to a refresh to ensure it's always up to date. But I think draft orders get saved enough that it'll catch user email changes.

Test failure:

1) Drupal\Tests\commerce_promotion\Kernel\Entity\CouponTest::testAvailability
Failed asserting that false is true.

I bet this email update sync shows a test with bad data, that's why it failed.

jsacksick’s picture

Status: Needs work » Needs review

So what about this instead?

The only potential problem I see with this is potentially reverting an intentional change made to the email address (e.g if a checkout pane allows explicitly specifying an email address for example)...

jsacksick’s picture

Better with the patch. The other problem I see with this approach is that until the order is refreshed, the order email is potentially wrong.

mglaman’s picture

The other problem I see with this approach is that until the order is refreshed, the order email is potentially wrong.

Yeah. The only time I could see an issue is if the admin placed the order for the customer. Otherwise, the order refreshes pretty often when a customer is using it. Like every checkout step save.

jsacksick’s picture

So, are we good with this approach?

  • jsacksick committed 8d3dcbc on 3.0.x
    Issue #2873526 by vasike, jsacksick, unrealauk, jeroendegloire,...

  • jsacksick committed 2be4f5b on 8.x-2.x
    Issue #2873526 by vasike, jsacksick, unrealauk, jeroendegloire,...
jsacksick’s picture

Status: Needs review » Fixed

In the absence of feedback, committed the fix.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

xamount’s picture

Version: 8.x-2.x-dev » 3.0.x-dev

I removed patch #28 and updated Drupal commerce (that now includes the fix in #39) but commerce recurring draft orders are not updated if the user changes their email. Patch #28 was working for me though but I cannot use it anymore as I updated Drupal commerce.

xamount’s picture