Problem/Motivation

On admin forms that use the customer_profile inline form with the "Save" button, you can edit a billing address and click "Save", but the old address is shown again. One example is the order's Add payment form (/admin/commerce/orders/{order}/payments/add) when adding a new payment method. This happens whenever the profile type does not allow multiple profiles per user (multiple: false, which is the default for the customer profile type on many sites).

CustomerProfile::submitInlineForm() correctly stores the edited profile in form state as ofile'] and rebuilds the form. buildInlineForm() then sets $use_saved_profile = TRUE, butit only applies $saved_profile inside this branch:

if ($allows_multiple && !$customer->isAnonymous()) {
  ...
  if ($use_saved_profile) {
    $address_book_profile = $saved_profile;
  }

When the profile type is single-profile, this branch is skipped. The form is rebuilt from the original $this->entity, and the saved changes are silently discarded.

There is a related problem in the same code path. For single-profile types, and also when the address book is empty, the select_address element is never built or is not accessible. As a result,
select_address is never part of the submitted user input. Clicking "Edit" after a "Save" :

Warning: Undefined array key "select_address" in
Drupal\commerce_order\Plugin\Commerce\InlineForm\CustomerProfile->buildInlineForm()

Because of the missing key, $use_saved_profile evaluates to FALSE, and the original profile is shown again.

Steps to reproduce

1. Make sure the customer profile type does not allow multiple profiles (profile.type.customer:multiple: false).
2. Have an order with a billing profile, and enable an onsite payment gateway that collec
3. As an admin, go to /admin/commerce/orders/{order}/payments/add and pick the option to add a new payment method (e.g. "Credit card").
4. Click Edit on the billing information, change the street address and click Save.
5. The rendered billing information still shows the old address.
6. Click Edit again. The form shows the old values, and the "Undefined array key "select_d.

Proposed resolution

In CustomerProfile::buildInlineForm():

- Treat a missing select_address in the user input as _original. If the dropdown is absencurrent or saved profile.
- Apply $saved_profile when $use_saved_profile is TRUE even if the profile type doesn't allow multiple profiles. Add an elseif next to the existing single-profile branch so the existing "copy field values
from the address book profile" logic fills the form from the saved profile.

-        'select_address', 'edit_button' => $user_input['select_address'] === '_original'
+        'select_address', 'edit_button' => ($user_input['select_address'] ?? '_original') === '_original',

+    elseif ($use_saved_profile) {
+      // A single address book profile is allowed, and a profile was saved
+      // via the "Save" button, use it to pre-fill the profile form.
+      $address_book_profile = $saved_profile;
+    }
     elseif (!$customer->isAnonymous() && $this->entity->isNew()) {

Remaining tasks

- Review the patch/MR.
- Add a FunctionalJavascript test to CustomerProfileTest (or OrderAdminTest) that covers Save → rendered address and Save → Edit for a single-profile type.

Issue fork commerce-3625384

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

vmarchuk created an issue. See original summary.

vmarchuk’s picture

Assigned: vmarchuk » Unassigned
Status: Active » Needs review

tbkot made their first commit to this issue’s fork.

tbkot’s picture

Status: Needs review » Reviewed & tested by the community