I have a billing and a shipping pane on checkout, both of which have a commerce_addressbook field. When I select an existing profile for billing, the fields are properly populated when the ajax call returns. However, the same cannot be said for shipping. When I select an existing profile for shipping, the fields remain blank (or retain whatever value they had before). If I refresh the checkout form, the fields are populated with the profile that I selected. I removed the billing pane to determine if the issue is specific to multiple panes and I receive the same behavior, so it appears to be an issue with shipping profiles.

CommentFileSizeAuthor
#1 1328630_1.patch1.17 KBczigor
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

czigor’s picture

Status: Active » Needs review
FileSize
1.17 KB

I had the same problem. Attached is a patch that solves the issue for addressfields.

czigor’s picture

Apparently it works for non-addressfield fields, too. I don't know why.

BassistJimmyJam’s picture

Status: Needs review » Needs work

The patch applied cleanly but did not change the behavior for me. It still loads in the shipping address empty via ajax, yet the fields are populated correctly if I refresh the page.

czigor’s picture

Do you have
1. One customer profile type with 2 addressfields in it (billing and shipping)
or
2. 2 customer profile types (billing and shipping) with one addressfield in each?

BassistJimmyJam’s picture

I have two customer profiles (billing and shipping), with a single addressfield in each.

czigor’s picture

OK, then we had two different setups. The patch is for more addressfields in one customer profile.

I will try to have a look at your case. Is this the shipping customer profile type shipped by the commerce_shipping module?

BassistJimmyJam’s picture

Yes, we are using the customer profile type included in commerce_shipping.

BassistJimmyJam’s picture

I'm still trying to track this down, but I have found a difference between selecting an existing address for shipping vs. billing. When I choose a billing address, $form_state['addressfield'][$element_key] in addressfield_field_widget_form() is null. But when I choose a shipping address, $form_state['addressfield'][$element_key] is already set with empty values for each of the elements. I'm not sure yet where this is getting set/cleared, but that seems to be the cause of this issue.

BassistJimmyJam’s picture

After some more digging I found that the address should be cleared from $form_state by commerce_addressbook_saved_addresses_validate(), which appears to be working correctly. Yet, there is still an address in $form_state for shipping when commerce_customer_profile_pane_checkout_form() is called. However, if I choose a billing address $form_state is empty for the billing address in commerce_customer_profile_pane_checkout_form().

czigor’s picture

Yes, you're right, the $form_state['addressfield'][$element_key] has to be unset for every addressfield. That's what my patch does at least. I don't know why the shipping profile addressfield does not get unset, I haven't had time to look at it.

BassistJimmyJam’s picture

It appears that commerce_addressbook is unsetting it, but something else is setting it again later in the process. I'm stepping through with a debugger to determine what's going on.

czigor’s picture

For me it works fine with the commerce_shipping module, too.

I enabled the shipping module, added a shipping customer profile. Added a product to my shopping cart, went to checkout. I selected a billing customer profile and then a shipping customer profile. All the fields got populated correctly.

Can you reproduce your behavior on a clean install?

BassistJimmyJam’s picture

My problem appears to have something to do with a difference in how the validation functions are run for each field. For the billing it runs in the following order:

  1. addressfield_standard_country_validate()
  2. commerce_addressbook_saved_addresses_validate()

However, for shipping it runs in the opposite order:

  1. commerce_addressbook_saved_addresses_validate()
  2. addressfield_standard_country_validate()

The addressfield_standard_country_validate() function will add the address back into $form_state, after commerce_addressbook_saved_addresses_validate() has removed it. So the question is, why are the orders different? The field is the same, just a different instance (since it's on a different bundle), and I find any difference between the two.

BassistJimmyJam’s picture

I was able to get the validations to run in the correct order by modifying the weight of the fileds. However, it seems like it is not safe to rely on the order of the validate functions and an alternative method of handling this may be necessary.

svendecabooter’s picture

Title: Shipping address does not populate via ajax » Address might not populate via ajax, depending on validation function order

Thanks czigor & BassistJimmyJam for debugging this problem in depth.
The conclusion in #14 is spot on. Now we only need a fix for it :)

I will look into the patch provided in #1. This is another issue, but support for multiple addressfields in one entity should be provided if possible. I'll check what the consequences are...

meaton’s picture

Hello, I am having the same issue with my shipping fields. My billing fields are populating correctly. I have different profiles for shipping and for billing. It looks as though the $form_state['addressfield'][$element_key] values are not being unset in the commerce_addressbook_saved_addresses_validate() function only for the shipping fields. Anyone have any input on this?

mr.moses’s picture

@BassistJimmyJam: what fields did you adjust and what weights did you use?

I've been trying to track down whats causing this, but haven't found anything yet. This was working for me around Dec 15 and I'm pretty sure I had the latest of everything at that time (Drupal 7.8, commerce, commerce_addressbook, commerce_shipping, etc.).

BassistJimmyJam’s picture

I modified the weight of the addressbook field on the shipping profile to be 0 while the address field is 1.

mr.moses’s picture

Disabling the Addressbook module and re-enabling it worked for me; changing the weights did not make a difference, but maybe I wasn't doing it the same way as BassistJimmyJam.

To disable the Addressbook module, remember you first have to delete the addressbook_saved_profiles fields from the billing and/or shipping profile types.

Here is my understanding of why this worked:

The validators were run in a different order because the elements in the form array were actually in a different order.

customer_profile_billing
commerce_customer_address
addressbook_saved_profiles
customer_profile_shipping
addressbook_saved_profiles
commerce_customer_address

If you disable the Addressbook module, the arrays will look like this:

customer_profile_billing
commerce_customer_address
customer_profile_shipping
commerce_customer_address

Re-enabling the Addressbook module puts the addressbook_saved_profiles field after commerce_customer_address for both profile types.

If the Shipping module is enabled after the Addressbook module (or they are enabled at the same time), the Addressbook module seems to add its field (addressbook_saved_profiles) before the commerce_customer_address field is added, which means the commerce_customer_address country validator runs after addressbook_saved_profiles validator.

Maybe just deleting the addressbook_saved_profiles field from the shipping profile and re-adding it would have worked too.

This is just another workaround, but hopefully the information will help someone figure out a fix.

svendecabooter’s picture

I tried to reproduce this in various ways, but couldn't get the addressfield_standard_country_validate() to run after the addressbook validation function...

I tried:
* Installing Commerce Addressbook and then Shipping
* Adding a higher weight to the Saved addresses field on admin/commerce/customer-profiles/types/shipping/fields
* Giving a higher weight to the addressfield module in the {system} table

None of those actions made the addressfield_standard_country_validate() run after the addressbook one.
If anyone has more ideas on how to reproduce this, let me know...

Sven

mr.moses’s picture

I had installed/enabled the Commerce Addressbook and Shipping modules (along with all the core commerce modules) all at once. Try starting with a fresh Drupal 7 standard install, then enable them all at the same time.

Or try removing the commerce_customer_address field from the shipping profile, leaving just the addressbook_saved_profiles. Then re-add the commerce_customer_address field.

bojanz’s picture

Status: Needs work » Closed (won't fix)

The 7.x-2.x branch of Addressbook should not have this problem. The 7.x-1.x branch is no longer supported.
I suggest you apply the #1311470: Provide missing uninstall code patch to your 7.x-1.x installs, uninstall 7.x-1.x (and report in that issue that everything went well), then install 7.x-2.x
and live happily ever after :)

All customer profiles will be kept, the only thing lost between uninstalls is the information on which profile is the default, which is a minor detail compared to getting a functioning module.