Problem/Motivation

Followup to #2844917: Create a commerce_profile_select form element and field widget.

If the profile belongs to a user, the form element should provide a dropdown of profiles to choose from, along with Edit and Add new functionality.
We want the Commerce Addressbook 3.x UX here: https://www.drupal.org/files/project-images/Capture%20d%E2%80%99e%CC%81c...

Proposed resolution

Remaining tasks

#106 had a partially working patch.

<snip>
However, I ran into form issues that I could not solve in time.

Apply the patch, enable commerce_order_test, and go to "/commerce_order_test/profile_select_test_form". Click "+ Enter a new address". You will see that clicking the "Return to address selection" does nothing the first time. Under the hook, Drupal assigns the clicks to completely wrong elements. It treats selecting "Enter a new address" as a click to the Cancel button, and the click to the Cancel button as a click to the Edit button. This tells me that the process callback is rebuilding the form too early, but I don't know how to avoid that yet.
</snip>

User interface changes

API changes

Data model changes

CommentFileSizeAuthor
#308 checkbox-same-as-billing-2852207-69-2.6.patch20.3 KBh1nds1ght
#308 57c11175d279fe55db9454b4274608195211aeb8-2.9.patch41.93 KBh1nds1ght
#308 760-2.10.patch37.16 KBh1nds1ght
#298 Schermafbeelding 2018-11-19 om 20.46.33.png193.44 KBnickvanboven
#294 interdiff-285-294.txt1.19 KBandyg5000
#294 commerce-expand_profile_select-2844920-294.patch80.09 KBandyg5000
#293 interdiff-285-291.txt1.14 KBandyg5000
#293 commerce-expand_profile_select-2844920-291.patch80.03 KBandyg5000
#292 interdiff-285-291.txt1.09 KBandyg5000
#292 commerce-expand_profile_select-2844920-291.patch79.99 KBandyg5000
#285 2844920-285.patch79.28 KBs.messaris
#285 interdiff-285-284.txt1.65 KBs.messaris
#284 interdiff-284-279.txt1.81 KBs.messaris
#284 2844920-284.patch79.19 KBs.messaris
#279 2844920-279.patch79 KBmglaman
#278 2844920-278.patch79.23 KBmglaman
#271 2844920-271.patch79.13 KBmglaman
#269 2844920-269.patch78.99 KBmglaman
#268 2844920-268.patch75.79 KBmglaman
#266 2844920-266.patch75.93 KBmglaman
#264 2844920-264.patch72.85 KBmglaman
#264 interdiff-2844920-262-264.txt1.76 KBmglaman
#262 interdiff-2844920-261-262.txt666 bytesmglaman
#262 2844920-262.patch130.05 KBmglaman
#261 2844920-261.patch71.92 KBjosephdpurcell
#260 interdiff-253-260.txt2.63 KBjosephdpurcell
#260 2844920-260.patch71.87 KBjosephdpurcell
#254 2844920-253.patch71.87 KBmglaman
#247 2844920-247.patch63.57 KBmglaman
#246 2844920-246.patch61.56 KBmglaman
#244 2844920-244.patch61.86 KBmglaman
#243 2844920-shipping-fix-do-not-test.patch1.38 KBmglaman
#243 2844920-243.patch42.67 KBmglaman
#240 profile-reuse-edit-btn-UX-2844920.PNG16.93 KBrwanth
#235 2844920-235.patch42.13 KBmglaman
#233 2844920-233.patch38.04 KBmglaman
#231 commerce2x-addressbook4.gif523.4 KBmglaman
#231 2844920-231.patch38.91 KBmglaman
#228 2844920-228.patch53.92 KBKittenDestroyer
#227 2844920-227.patch110.17 KBm.ioannidis
#226 2844920-226.patch85.09 KBmattjones86
#225 2844920-225.patch70.48 KBmattjones86
#224 2844920-224.patch71.8 KBmattjones86
#219 interdiff_218-219.txt5.9 KBs.messaris
#219 2844920-219.patch110.16 KBs.messaris
#218 interdiff-214-218.txt586 bytess.messaris
#218 2844920-218.patch110.18 KBs.messaris
#214 2844920-214.patch110.17 KBheddn
#214 interdiff_212-214.txt1.34 KBheddn
#212 2844920-212.patch110.78 KBheddn
#212 interdiff_210-212.txt2.36 KBheddn
#209 2844920-209.patch110.51 KBheddn
#209 interdiff_206-209.txt11.81 KBheddn
#208 profile_select.gif512.21 KBheddn
#206 interdiff_198-206.txt2.14 KBheddn
#206 2844920-206.patch95.8 KBheddn
#202 choose-existing-profile.png245.53 KBdrugan
#202 default-or-first-profile.png223.6 KBdrugan
#201 Screen Shot 2018-04-30 at 15.17.22.png82.95 KBheddn
#198 interdiff_196_198.txt6.24 KBheddn
#198 2844920-198.patch95.25 KBheddn
#196 2844920-196.patch94.21 KBheddn
#196 interdiff_194-196.txt22.21 KBheddn
#194 2844920-194.patch82.62 KBheddn
#190 Screenshot_2018-04-17_08-40-58.png19.52 KBheddn
#190 interdiff_189-190.txt1.01 KBheddn
#190 2844920-190.patch65.39 KBheddn
#189 interdiff_186-189.txt1.56 KBheddn
#189 2844920-189.patch65.28 KBheddn
#186 2844920-186.patch64.62 KBheddn
#186 interdiff_185-186.txt11.95 KBheddn
#185 interdiff_183-185.txt889 bytesheddn
#185 2844920-185.patch63.76 KBheddn
#183 interdiff_181_183.txt25.05 KBheddn
#183 2844920-183.patch63.76 KBheddn
#181 interdiff_177-181.txt8.46 KBheddn
#181 2844920-181.patch41.36 KBheddn
#177 interdiff_175-177.txt1.46 KBheddn
#177 2844920-177.patch39.93 KBheddn
#175 Drupal_Tests_commerce_order_FunctionalJavascript_ProfileSelectTest-21-91169777.jpg32.18 KBheddn
#175 interdiff_173_175.txt9.04 KBheddn
#175 2844920.patch39.92 KBheddn
#173 interdiff_171_173.txt7.44 KBheddn
#173 2844920-173.patch39.61 KBheddn
#171 2844920-171.patch38.1 KBheddn
#171 interdiff_169-171.txt9.31 KBheddn
#169 interdiff_167-169.txt3.94 KBheddn
#169 2844920-169.patch39.65 KBheddn
#168 2844920-167-interdiff.txt906 bytesharings_rob
#167 2844920-167.patch38.99 KBharings_rob
#167 2844920-167-interdiff.txt54.1 KBharings_rob
#165 Screenshot_2018-03-14_16-27-19.png35.71 KBheddn
#162 2844920-162.patch3.87 KBAlluuu
#161 2844920-161.patch4.26 KBAlluuu
#157 2844920-156.patch38.84 KBheddn
#157 interdiff_155-156.txt10.89 KBheddn
#155 2844920-155.patch38.42 KBericchew
#155 interdiff_152-155.txt2.49 KBericchew
#152 2844920-152.patch38.47 KBericchew
#152 interdiff-150-152.txt5.89 KBericchew
#150 2844920-150.patch36.89 KBheddn
#150 interdiff_147-150.txt38.29 KBheddn
#147 2844920-147.patch41.39 KBheddn
#147 interdiff_143-147.txt9.17 KBheddn
#143 interdiff_142-143.txt5.04 KBheddn
#143 2844920-143.patch39.72 KBheddn
#142 interdiff_140-142.txt1.48 KBheddn
#142 2844920-142.patch41.77 KBheddn
#140 2844920-140.patch41.77 KBheddn
#140 interdiff_139-140.txt528 bytesheddn
#139 interdiff_137_139.txt2.05 KBheddn
#139 2844920-139.patch41.49 KBheddn
#137 interdiff_135-137.txt2.04 KBheddn
#137 2844920-137.patch41.47 KBheddn
#135 interdiff_133-135.txt10.27 KBheddn
#135 2844920-135.patch41.46 KBheddn
#133 2844920-133-broken.patch39.86 KBericchew
#111 2844920-reverse-profileSelect-temp-fix.patch1.24 KBransomweaver
#108 2844920-108.patch38.51 KBjackbravo
#108 2844920-108.diff37.51 KBjackbravo
#106 2844920-106-broken.patch39.99 KBbojanz
#89 commerce-profile_select_ONLY_TESTS-2844920-89.patch5.62 KBczigor
#74 commerce-profile_select_reuse_existing_combined-2844920-74.patch21.66 KBbmcclure
#50 Order information.png16.48 KBchishah92
#47 commerce-profile_select-2844920-47.patch12.42 KBbmcclure
#46 commerce_shipping-Reverse_temporary_profile_change.patch602 bytesbmcclure
#40 Order information.png51.54 KBpadma28
#40 Review.png47.37 KBpadma28
#8 all_in_button.png141.55 KBdrugan
#7 commerce-profile_select-2844920-7.patch10 KBczigor
#3 drupal_address_has_conflict.png153.79 KBdrugan
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

bojanz created an issue. See original summary.

jkuma’s picture

Assigned: Unassigned » jkuma

Let me work on it !

drugan’s picture

@jkuma Check the bojanz latest commit. He works on this right now.

Not sure if it is my specific issue or it is somehow related with the commit. What is interesting (see screenshot's second attempt to update) after manually adding "drupal/address": "1.x-dev" to my composer.json "require-dev" block it reports this:

The requested package drupal/address (locked at 1.0.0-rc3, required as 1.x-dev) is satisfiable by drupal/address[1.0.0-rc3] but these conflict with your requirements or minimum-stability.

And that is despite the fact 1.x-dev version is available for composer to install. (composer info -a drupal/address)

bojanz’s picture

@jkuma
Good luck :)

@drugan
There's no need for you to add address to your composer.json file. "composer update drupal/commerce --with-dependencies" would switch you to -dev automatically.

jkuma’s picture

Assigned: jkuma » Unassigned

@bojan

Sorry for the delay in my reply. Last week-end, I spent quality time to study the way to fetch customer profiles for the current logged user. The problem is, as you may know, there are no such methods to get all customer profiles from an UID. So, we can create a plugin or add a new method in order to do so, but I think it's nasty.

From my perspective, we need to create a customer entity type and gather all related data (customer profiles, customer preferences) on this entity type. We can keep the uid property on order, but each time an order is created, we create or udpate a related customer entity. Using the customer entity, it'll be more easier to fetch profiles, but also to build a "my account" page.

czigor’s picture

Assigned: Unassigned » czigor

Assigning.

czigor’s picture

Assigned: czigor » Unassigned
FileSize
10 KB

The attached patch kind of works. TODO:

1. Cleanup, docs, comments.
2. Fix buggy '+ Enter a new address'
3. Tests
4. PR

drugan’s picture

FileSize
141.55 KB

As for the functionality it looks good and quite similar to the one suggested by bojanz here but I'd like to see this solution rewritten like this:

All in one button

That way we can do all the actions with one button. No +Enter new address and Edit and Return to address selection buttons. When clicked at one of the Select an address options you'd get all the appropriate fields filled in with the information for this address. When clicked at the Continue to review button the new profile is created if some of the existing profile field values were changed. If user wants just to edit existing profile without creating new one, they can go to Address Book in a user profile and do this. It is better because the history of all the address profiles and their ever used revisions are kept and managed in one place.

czigor’s picture

Status: Active » Needs review

@drugan Discussed this with @bojanz and the problem with omitting the buttons is that it's not clear for the user what's going to happen when they edit a profile: is it going to create a new profile or update the old one? So we decided to stick with the buttons.

There's one difference from the 7.x-3.x implementation: when editing a profile the profile will be updated in 8.x, and not a new one created as in 7.x-3.x (which might be a bug there).

My PR is here, still without tests but everything else is fixed:
https://github.com/drupalcommerce/commerce/pull/631

czigor’s picture

Status: Needs review » Needs work

Checkout as anonymous should not offer anonymous profiles.

czigor’s picture

Status: Needs work » Needs review

Fixed the anonymous checkout case, tests are green on the PR.

chishah92’s picture

@czigor : I applied the patch, but when i click to +Enter new address , Add new address and click on proceed to review it gives me WSOD

chishah92’s picture

Status: Needs review » Needs work

The patch is not working , as when i click to +Enter new address , Add new address and click on proceed to review it gives me WSOD

czigor’s picture

Status: Needs work » Needs review

@chishah92 For me it works on a clean drupal commerce 2 install. Can you provide some extra information that helps me to reproduce it?

chishah92’s picture

Status: Needs review » Needs work

@czigor :
I too have a clean drupal commerce 2

1) It works fine when i place the order for the first time where there is no address in the profile

2) But for the second time when you go to checkout and select Enter new address and click to proceed to review it gives WSOD

3) Also if you select the used one's and edit it and click to proceed to review, it gives WSOD

Please Advice,

Let me know if you want more information

chishah92’s picture

Also to add on, I get below error from error.log

[Mon Feb 20 13:10:03.244281 2017] [php7:notice] [pid 2094] [client 127.0.0.1:40598] PHP 191. Drupal\\Core\\Form\\FormErrorHandler->setElementErrorsFromFormState() from core/lib/Drupal/Core/Form/FormErrorHandler.php:60, referer:

czigor’s picture

@chishah92 What versions of drupal and commerce are you using?

Safallia Joseph’s picture

I also face the same issue as @chishah92.
I'm using Drupal core 8.2.4 and commerce 8.x-2.x

chishah92’s picture

Drupal core 8.2.4 and commerce 8.x-2.x

czigor’s picture

Status: Needs work » Needs review

Still can't reproduce.

I did the following:
1. Downloaded the 8.2.4. tarball
2. I added the drupal repository to the core composer.json.
3. Ran composer require drupal/commerce.
3a. EDIT: Applied the PR https://github.com/drupalcommerce/commerce/pull/631.
4. Installed drupal through browser using a standard install profile.
5. Enabled commerce, commerce_cart, commerce_checkout, commerce_order, commerce_price, commerce_product, commerce_store.
6. Imported US dollar as currency at /admin/commerce/config/currency.
7. Added a store with random values at /admin/commerce/stores.
8. Added a product with one variation at /product/add/default.
9. Did 2 checkouts with uid1, both times created a new profile.

Is there anything you did differently?

vasike’s picture

i also can't reproduce.

chishah92’s picture

Status: Needs review » Needs work

My version was drupal/commerce 2.x-dev

czigor’s picture

Status: Needs work » Needs review

@chishah92 Mine as well. Added step 3a to the steps above.

Safallia Joseph’s picture

@czigor

It worked. I tested using the wrong patch. Previously I tested by applying commerce-profile_select-2844920-7.patch patch. After applying https://patch-diff.githubusercontent.com/raw/drupalcommerce/commerce/pul... it works!

Safallia Joseph’s picture

Status: Needs review » Reviewed & tested by the community
Safallia Joseph’s picture

The profile selector is not working for the shipping information pane provided with Commerce Shipping Module. Maybe it must be an issue with the commerce shipping module.

czigor’s picture

@Safallia Joseph For me it works. Can you describe what you expect and what happens instead?

Safallia Joseph’s picture

I enabled commerce shipping module and added the Shipping information pane. On checkout, the profile picker dropdown is displayed in the Shipping profile pane. But Selecting a different profile does not replace the current address summary with the new one. I used commerce shipping module version 8.x-2.x-dev.

czigor’s picture

Thanks, I have fixed it. Can you test it?

czigor’s picture

Status: Reviewed & tested by the community » Needs review
Safallia Joseph’s picture

Same PR? Was that issue related with profileSelect?

Safallia Joseph’s picture

Yep! Its working now.
Thanks for the fix

Safallia Joseph’s picture

Status: Needs review » Reviewed & tested by the community
chishah92’s picture

Status: Reviewed & tested by the community » Needs work

@czigor : It works fine for both billing and shipping. But when i updated the 8.x-2.x-dev version of commerce_shipping released on feb 20. The profile selection feature doesnt appear in shipping info and also after add the new address and edit on review, the user has to fill up the shipping info form once again.

czigor’s picture

Status: Needs work » Needs review

@chishah92 This is because of #2852719: Temporarily stop storing shipping profiles in the address book. This has to be fixed in commerce_shipping.

chishah92’s picture

Cool no issues. Thanks for the patch.

chishah92’s picture

Status: Needs review » Needs work

@czigor : I had created issue On editing the shipping info on review page , user has to fill up the form once again. for shipping module but it seems the issue is due to this patch

chishah92’s picture

@czigor : also we are getting same issue for billing address, the once we save an address on review, when we click on edit we get the first address instead of the saved one.

czigor’s picture

@chishah92: Not sure what you mean. Do you need shipping to reproduce this? I have several billing profiles, I select one of them, click Edit and in the form I see the selected profile's values correctly.

padma28’s picture

FileSize
47.37 KB
51.54 KB

@czigor. I also got a same issue. When i click Edit link on review page, the billing and shipping information shows default first address not that we were selected the address.
This is the review page with updated address. I am clicking Edit link here, it goes to order information page
Review Page
After i got the order information page, my selected address is not showing.
Order Information

czigor’s picture

@chishah92 @padma28 Added a fix, can you review it?

padma28’s picture

Status: Needs work » Reviewed & tested by the community

Thank You @czigor. The patch is working fine.

chishah92’s picture

@czigor : Patch works fine. Thankyou so much for a quick update, Appreciated.

czigor’s picture

Status: Reviewed & tested by the community » Needs work

This still needs tests.

csedax90’s picture

patch works like a charm with latest dev

bmcclure’s picture

This patch is working well for me too (from the GitHub PR).

For anyone using this patch and commerce_shipping, you can revert the recent temporary commerce_shipping change that stopped this from working using the patch I'm attaching here. I'm going to hide it since it's not the real patch for this issue, but it works well with the real patch for anyone using commerce_shipping's latest versions.

bmcclure’s picture

Here's a reroll of the patch against the current commerce release with one fix (setting $default_profile_id to NULL by default so it's not unset in case it doesn't get overridden later).

I commented in the PR so hopefully it'll be fixed there, too, but I needed somewhere to patch from in the meantime.

bmcclure’s picture

One thing I've found, this may be a known issue already, but this patch assumes that "address" is the only field that's a part of the profile. For instance, I have a field_phone field which should ideally be shown/hidden along with the address field since it's a part of the profile being reused, however the field is still present when the address is hidden.

czigor’s picture

Thanks @bmcclure, fixed these issues as well. They are in the PR. Tests are still needed.

chishah92’s picture

FileSize
16.48 KB

@czigor : After applying the latest patch from git , when the user enters the address for the first time , The review button get's is disabled

ScreenShot :

Order information

bmcclure’s picture

Currently we have a Quote checkout flow that uses commerce_shipping, but does not have billing information. The shipping profiles are using the profile select element via this patch.

As an anonymous user, when I fill out the profile form, calculate shipping, and then continue to the next step, it works fine, but I also get:

"Notice: Undefined index: pane_shipping_information[shipping_profile] in Drupal\commerce_order\Element\ProfileSelect::submitForm() (line 312 of modules/commerce/modules/order/src/Element/ProfileSelect.php)."

I'm not certain offhand if something is different on my installation causing this, or if this is an issue with the patch. Anyone else experiencing this?

bmcclure’s picture

Simply modifying the conditional from (in_array($storage['pane_' . $pane_id]['mode'], ['new', 'edit'])) to (isset($storage['pane_' . $pane_id]) && in_array($storage['pane_' . $pane_id]['mode'], ['new', 'edit'])) fixes the issue for me. But I don't know why, because it seems like the profile isn't being saved then. However considering it works fine, I'm assuming something else is saving the profile in this anonymous / new profile case.

chishah92’s picture

@bmcclure : I tried to apply the patch #47 , but when i create new profiles , it overrides the previous one instead it should create new ones

Please Advice

bmcclure’s picture

@chichah92 I would recommend using the patch in the GitHub PR instead of mine, as it's been updated since I posted my version. Do you still experience that issue with the latest patch from czigor's PR?

chishah92’s picture

@bmcclure : Yes i have used the patch from czigor's PR , and i facing this issue as stated in #53

chishah92’s picture

@czigor : The Patch Works Fine if i don't have a shipping profile, if i have the same and suppose i edit or create a new profile in my shipping information, it disables the review button.

itamair’s picture

This issue / task sounds really interesting, and needed in its correct implementation, but once applied the latest patch (from GitHub PR) I experience the following bad use cases:

  • Cannot Add a new Customer Profile in the Order checkout / Payment Information State: no Add button present
  • Cannot Save any Edit to the Customer Profile in the Order checkout / Payment Information State: just the “Return to profile selection” button appears in the edit form
  • In the Order edit page/form, the Select & the Edit button on the Profile / Billing Information fieldset don’t work at all.
  • It is not possible to edit (any way) the Billing Information in the Order edit page (as a result of the previous)
  • Once the Order is placed (checkout completed), if the user changes his address_book / customer profile info, than it is changed also in the Order itself. Is this the wanted behavior? or should it be kept (frozen) the data provided in the checkout process? (as it is in the actual core behavior) and edited just in the Order Edit form …
bmcclure’s picture

It's worth noting that I don't experience a couple of the issues you mention.

  • Adding a new profile should be an option within the select list, and that works fine for me
  • Saving the edits happen when you continue to the next step of checkout
  • Admittedly I haven't tested this on the order edit page yet so there may be issues there that I just haven't found (I'm sure our client will)
  • This is just how Commerce works currently. There are several potential issues with entities that are reused, such as payment information and profiles, in that they can be modified or deleted later and then previous orders are no longer accurate. I'm not sure what the status is offhand of this being worked on, but I don't think it's the responsibility of this patch to solve.
chishah92’s picture

The issues that i face after the new patch is applied :
1) Initially when there is no profile, the checkout page does not show the Add new profile select list.
2) Adding two addresses for payment and shipping creates two profiles. But when we go in checkout page once again and add select add new profile for both payment and shipping information, the continue to review button is unset
3) Also when we select the same previous profiles and click to "Continue review" button in review page it shows only payment information with the first profile and When we click on Edit, one more duplicate profile get's created.

Summary : The profile save and edit are not working accordingly, needs rewrite.

itamair’s picture

@bmcclure sorry ... you are right, but I have to still confirm the following issue:

1) In the Order edit page/form, the Select & the Edit button on the Profile / Billing Information fieldset don’t work at all.

and add this, that really seems a mayor bug to me:

2) If I remove an Address / Customer Profile previously associated to a placed Order, that Order is not editable anymore and the site breaks on that attempt: exception thrown (and not catched)

bmcclure’s picture

This patch is actually working pretty great on a production site for us. I'm attempting to figure out what the difference is between our setup and yours. Are you using the latest dev version of commerce and commerce_shipping?

1. For me, when there is no existing profile created, it shows a profile creation form on the checkout page as it should, which then creates a new profile.
2. I'm not experiencing this one either, but that might be because I'm also using a patch for commerce_shipping which auto-calculates shipping and controls the Continue button.
3. I'm not sure I understand what you mean about this one. For me, when I get to the Review page, it shows whichever profiles I have selected for payment and shipping, and clicking Edit next to either of them goes back to the Order Information page with the same profiles still selected. Could you explain a little more how the behavior differs for you?

Note that currently, commerce_shipping forces the shipping profile to be owned by the anonymous user, which prevents a profile select field from ever showing up for shipping (unless you revert that change with another patch).

bmcclure’s picture

@itamair:

#1 seems like a bug that this patch may need to handle.
#2 is a known issue in Commerce unrelated to this patch, that's being handled elsewhere.

bmcclure’s picture

I'm actually not sure where the issue is regarding the fact that profiles should not be deletable when they're in use, but there should be an issue like that for every entity type associated with orders, as mentioned in this issue: https://www.drupal.org/node/2842579

itamair’s picture

tnx @bmcclure ... I confirm that bug is unrelated to this patch, as it happens with the actual core/committed functionalities too

chishah92’s picture

@bmcclure :
2) Even i have added the auto-calculate shipping patch(https://www.drupal.org/node/2849756), yet i face the issue

3) The senario is i have already two profiles in my address-book. When i place my order again, in checkout page i get to select any of the profiles. But if i select new profile for payment and select the old profile in shipping , the review page shows only payment information. And when i click to edit, it goes back to order information, but here one more duplicate profile gets created.

Can you guide me for which patch needs to be applied to revert it ?

bmcclure’s picture

Just had a quick chat with @chishah92 in Slack and realized that I'm experiencing the same issue as his scenario #3 above. I just visited my address book and there's a ton of duplicate addresses existing--I just didn't notice because all seems fine while going through checkout.

chishah92’s picture

Any updates on this one ?

bmcclure’s picture

I've incorporated all of the changes in the previous patch from czigor here, along with #reuse_profile options added for the ability to show a checkbox that copies another profile, and have been committing a few small changes to this functionality there.

The credit for this profile select functionality still goes to czigor, but as this is an alternate way to get this same patch if you also want to use the "Billing address same as shipping" functionality, and I may continue to make modifications/fixes to it there, I figured I would post it here as well:

https://github.com/drupalcommerce/commerce/pull/715

bmcclure’s picture

In reference to my previous message, just wanted to note that I'm in the process of revamping some of how my code in PR 715 works to try and eliminate a couple issues I've been running into (duplicate profiles that keep getting created being the main one, among a couple of logic bugs I introduced when changing things around to support profile reuse). I'll have the PR updated today if anyone else happens to be using it and experiencing any issues.

bmcclure’s picture

Status: Needs work » Needs review

I've updated PR 715, including refactoring and modifying some of the logic behind the functionality of selecting existing profiles, and reorganizing a lot of code in the element.

https://github.com/drupalcommerce/commerce/pull/715

It still works very similarly to czigor's patch, but supports the latest changes to the commerce 2.x dev branch, and I think it resolves the profile duplication issues.

Looking for feedback on this. Does it work well for others? If so, is there anything more needed in the element for it to be fully functional?

Note: This PR also includes code to resolve a related commerce_shipping issue (https://www.drupal.org/node/2852207)

itamair’s picture

#bmcclure I am not able to apply https://github.com/drupalcommerce/commerce/pull/715.patch to any actual version of Drupal commerce (both 2.0-beta6 and
2.x-dev).

bmcclure’s picture

@itamair: GitHub seems to have some sort of really long term caching or something on PR .patch links, sadly. Several days after I updated the PR, that patch link is still outdated.

I found that using .diff instead of .patch showed me an updated link, but that might just be because that wasn't cached yet so your mileage may vary.

The PR itself applies to the latest version of commerce, it's just that particular patch link that doesn't.

bmcclure’s picture

Note to anyone using this patch: https://www.drupal.org/node/2872823 is related and might be affecting this functionality within the payment gateway form profile select element.

bmcclure’s picture

I've also updated the PR with a couple of fixes and some refactored code again. Here's a patch, since there seems to be an issue with GitHub returning the latest patch files.

Berdir’s picture

Note that .patch and .diff is not the same thing. .patch is actually a patch-per-commit thingy that can't really be applied and results in strange merge conflicts and so on. .diff always works fine for me and I never have caching issues.

bmcclure’s picture

Thanks for clarifying that! That definitely explains my confusion.

itamair’s picture

@Berdir @bmcclure tnx to both of you ... ;-)

itamair’s picture

Ok @bmcclure ... tnx!
the "https://github.com/drupalcommerce/commerce/pull/715.diff seem to apply correctly into the "drupal/commerce": "2.x-dev",
BUT ...
I face the following error/exception when I try to edit an existing Order (also if still in the Cart):

InvalidArgumentException: The commerce_profile_select element requires the #default_value property. in Drupal\commerce_order\Element\ProfileSelect::processForm() (line 99 of modules/contrib/commerce/modules/order/src/Element/ProfileSelect.php).

That might happen in this 2 possibile user/administrator scenarios:

A - (quite improbable, but anyway possibile) I try to edit the Order when it is still in the Cart and the User didn't attach any billing info to it yet (at Payment Info Panel);

B - I remove an existing Billing Profile and I try to edit the Order that was previously filled with that profile ... (a real possibile scenario). I understand that Drupal Commerce itself is keeping into the Order the reference to the Customer profile address, but I think this is really risky: Order info (once placed) should be independent by Customer Address Book info, and anyway persistent;

Further more I still experience this other bug (already by me mentioned in some previous comment):

C - Billing Info / Customer Address is not editable from the Order edit back-end (the edit submit button don't work).

bmcclure’s picture

@itamair:

Regarding the exception, did you perhaps experience that same exception before using this patch? The #default_value validation was always done in the ProfileSelect element, this patch doesn't change that I don't believe.

Regarding point B above, Commerce should be disallowing the deletion of addresses, especially if they're in use anywhere. Commerce needs to implement a "soft delete" feature that simply hides the address once it's removed but allows it to still be referenced.

Regarding C, I haven't looked into that issue at all yet, have been focused on the customer UX so far. What should the actual behavior be for editing from an admin? Should an admin be able to edit a customer's profile from within the order, affecting all other orders that profile is used, when editing the order? Seems like we either need to fix the behavior of the button on that form, or remove it if it shouldn't be there.

itamair’s picture

@bmcclure

A - yes ... may be. I remember @Boianz already said there is not a logic to block the deletion of used entities. And this affects all the Drupal Commerce areas (and is a very major vulnerability and problem of the system)

B - ... but IMO Commerce shouldn't even directly reference the user profiles entities into the Order, but just add a detached copy of that (the profile address), so that it might be changed/edited in the Order backend independently (might be needed, after a Customer request ... or whatever), without the consequent update of the original profile, and its instances in different/other Orders ...

C - The Customer address / Billing Info profile Edit button don't work (in my case) in all its recurrences: both the Order edit backend (where it is present) and also in the Order information checkout pane itself ... (just placing the Cart Order)

bmcclure’s picture

A - True, it's pretty major in my opinion. Nothing we can do about it in this patch, however I hope that it gets some attention soon.

B - I see what you mean. I can definitely see how it could be useful, but I think it's a larger issue that extends beyond this patch to how orders are structured and processed overall. Perhaps a separate issue should be created to open this up for further discussion. I think the ability to select an existing profile is going to be useful either way, as that copying of the profile to the order could could still happen either way.

C - You're right, I'm noticing the same issue as well. It works fine in the Shipping Information pane for me but fails in the payment information pane. I'm working on some more fixes yet again for this and trying to simplify how complex it's gotten as much as possible, hoping the edit button will work in all contexts once I'm done with that.

bmcclure’s picture

Status: Needs review » Needs work

I've been playing around with the patch code a lot again today, and I've discovered that, with the recent fix by Berdir, there might be some unnecessary code that was previously used to avoid the issues with the ProfileSelect field.

Moving back to Needs Work, because the new version is going to be simpler and work better, I think. Refactoring, tweaking, and testing, and I'll have a new patch up ASAP tomorrow.

itamair’s picture

@bmcclure tnx ... yes, I agree that on the B matter we would need a new issue open.
And I just opened it (Protecting Customer/Billing Profiles against changes)
I am minding may be entity revisions, instead of entity reference, would be a good way to go ...

bmcclure’s picture

Status: Needs work » Needs review
czigor’s picture

Status: Needs review » Needs work

@bmcclure Thanks for working on this!

We will need tests.

Eric Heydrich’s picture

I installed the Patch from #85 and get the following error. On the checkout form there is no form for adding billing information.

TypeError: Argument 1 passed to Drupal\commerce_payment\Entity\PaymentMethod::setBillingProfile() must implement interface Drupal\profile\Entity\ProfileInterface, null given

bmcclure’s picture

@eric-haydrich: What version of commerce? Can you possibly post a full stack trace from that error? Thanks!

Eric Heydrich’s picture

@bmcclure Here's the stack trace. Current commerce dev-Version with patch 715 from #84 on Drupal 8.3.2.

TypeError: Argument 1 passed to Drupal\commerce_payment\Entity\PaymentMethod::setBillingProfile() must implement interface Drupal\profile\Entity\ProfileInterface, null given, called in [ROOT_PATH]/web/modules/contrib/commerce/modules/payment/src/PluginForm/PaymentMethodAddForm.php on line 112 in Drupal\commerce_payment\Entity\PaymentMethod->setBillingProfile() (line 152 of [ROOT_PATH]/web/modules/contrib/commerce/modules/payment/src/Entity/PaymentMethod.php) #0
[ROOT_PATH]/web/modules/contrib/commerce/modules/payment/src/PluginForm/PaymentMethodAddForm.php(112): Drupal\commerce_payment\Entity\PaymentMethod->setBillingProfile(NULL) #1
[ROOT_PATH]/web/modules/contrib/commerce/modules/payment/src/Element/PaymentGatewayForm.php(118): Drupal\commerce_payment\PluginForm\PaymentMethodAddForm->submitConfigurationForm(Array, Object(Drupal\Core\Form\FormState)) #2 [internal function]: Drupal\commerce_payment\Element\PaymentGatewayForm::submitForm(Array, Object(Drupal\Core\Form\FormState)) #3
[ROOT_PATH]/web/modules/contrib/commerce/src/Element/CommerceElementTrait.php(95): call_user_func_array(Array, Array)#4
[ROOT_PATH]/web/modules/contrib/commerce/src/Element/CommerceElementTrait.php(88): Drupal\commerce_payment\Element\PaymentGatewayForm::executeElementSubmitHandlers(Array, Object(Drupal\Core\Form\FormState)) #5
[ROOT_PATH]/web/modules/contrib/commerce/src/Element/CommerceElementTrait.php(88): Drupal\commerce_payment\Element\PaymentGatewayForm::executeElementSubmitHandlers(Array, Object(Drupal\Core\Form\FormState)) #6
[internal function]: Drupal\commerce_payment\Element\PaymentGatewayForm::executeElementSubmitHandlers(Array, Object(Drupal\Core\Form\FormState)) #7
[ROOT_PATH]/web/core/lib/Drupal/Core/Form/FormValidator.php(83): call_user_func_array(Array, Array) #8
[ROOT_PATH]/web/core/lib/Drupal/Core/Form/FormValidator.php(270): Drupal\Core\Form\FormValidator->executeValidateHandlers(Array, Object(Drupal\Core\Form\FormState)) #9
[ROOT_PATH]/web/core/lib/Drupal/Core/Form/FormValidator.php(119): Drupal\Core\Form\FormValidator->doValidateForm(Array, Object(Drupal\Core\Form\FormState), 'commerce_checko...') #10
[ROOT_PATH]/web/core/lib/Drupal/Core/Form/FormBuilder.php(571): Drupal\Core\Form\FormValidator->validateForm('commerce_checko...', Array, Object(Drupal\Core\Form\FormState)) #11
[ROOT_PATH]/web/core/lib/Drupal/Core/Form/FormBuilder.php(314): Drupal\Core\Form\FormBuilder->processForm('commerce_checko...', Array, Object(Drupal\Core\Form\FormState)) #12
[ROOT_PATH]/web/core/lib/Drupal/Core/Form/FormBuilder.php(212): Drupal\Core\Form\FormBuilder->buildForm('commerce_checko...', Object(Drupal\Core\Form\FormState)) #13
[ROOT_PATH]/web/modules/contrib/commerce/modules/checkout/src/Controller/CheckoutController.php(94): Drupal\Core\Form\FormBuilder->getForm(Object(Drupal\commerce_checkout\Plugin\Commerce\CheckoutFlow\MultistepDefault), 'order_informati...') #14
[internal function]: Drupal\commerce_checkout\Controller\CheckoutController->formPage(Object(Drupal\Core\Routing\RouteMatch)) #15
[ROOT_PATH]/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array) #16
[ROOT_PATH]/web/core/lib/Drupal/Core/Render/Renderer.php(574): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() #17
[ROOT_PATH]/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure)) #18
[ROOT_PATH]/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) #19
[internal function]: Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() #20
[ROOT_PATH]/vendor/symfony/http-kernel/HttpKernel.php(144): call_user_func_array(Object(Closure), Array) #21
[ROOT_PATH]/vendor/symfony/http-kernel/HttpKernel.php(64): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1) #22
[ROOT_PATH]/web/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #23
[ROOT_PATH]/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #24
[ROOT_PATH]/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #25
[ROOT_PATH]/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(50): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #26
[ROOT_PATH]/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #27
[ROOT_PATH]/web/core/lib/Drupal/Core/DrupalKernel.php(656): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #28
[ROOT_PATH]/web/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request)) #29
{main}.
czigor’s picture

I started working on writing just the tests, here they are. I think we need tests for the following:

I. Anonymous
I.1. The profile select should not appear, only the address.
I.2. Submitting the form creates a uid=0 profile.
II. Authenticated without profile
II. 1. No select, only address
II. 2. Submitting the form creates a profile for the user.
III. Authenticated user having 2 profiles already
III. 1. Select appears.
III. 2. Selecting another profile refreshes the displayed profile summary.
III. 2. a. Submitting the form does not change the selected profile.
III. 3. Clicking Edit works properly: the profile summary disappears, a prefilled form appears instead with a 'Return to profile selection without saving' button
III. 3. a. Submitting the form updates the existing profile, does not create a new one.
III. 4. Selecting '+ Enter a new profile' displays an empty profile form. No 'Return to profile selection without saving' button.
III. 4.a. Submitting the form creates a new profile.

We also need to test the same when there are two ProfileSelect form elements in the same form.

The attached patch contains I. and II. and the very beginning of III.

czigor’s picture

Updated my PR at https://github.com/drupalcommerce/commerce/pull/631/files.

Improvements:
- Has tests
- Uses proper form API (no form_state storage and not depending on pane ids)

Known bugs:
- Clicking "Edit" does not populate form with profile field values.
- Does not create new profiles, always overwrites the last profile.
- When validation fails (because of a wrong zip code for example) the form goes back to the state where it's first loaded.

I have not run tests.

bmcclure’s picture

Cool! Test coverage is awesome. I'm anxious to try this out, but it seems like it's broken functionally at the moment. Using the form API more closely seems like a good way to go, though I believe all 3 current known bugs were introduced with this latest patch.

I'll keep using my previous patch for the time being so that the profile select functionality works properly on our site, but I'll be monitoring this issue and will be sure to test any further patches that are at least functionally equivalent to the previous ones.

mglaman’s picture

Assigned: Unassigned » mglaman

I'm running with this for a bit. Since maintainer, I can push to czigor's fork on GitHub for the PR. Already found an issue when country code changes, the element mode reverts back to View and not New/Edit.

mglaman’s picture

I've pushed some fixes. More are needed. When you save from edit, the mode gets kicked back to view and all form values are gone

bojanz’s picture

Assigned: mglaman » Unassigned

This functionality is almost ready. I made some tweaks to the labels and moved the code to https://github.com/drupalcommerce/commerce/pull/760

Unfortunately, I ran into incompatibilities with shipping, which prevented me from committing this in time for RC1.
There's always RC2 though :)

zenimagine’s picture

Subscribe

JeroenT’s picture

Tried the code in PR posted in comment #94.

When I go to checkout/../order_information i immediately get the following error:

The website encountered an unexpected error. Please try again later.
Recoverable fatal error: Object of class Drupal\profile\Entity\Profile could not be converted to string in Drupal\Core\Entity\ContentEntityStorageBase->buildCacheId() (line 722 of core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php).
Drupal\Core\Entity\ContentEntityStorageBase->buildCacheId(Object) (Line: 614)
Drupal\Core\Entity\ContentEntityStorageBase->getFromPersistentCache(Array) (Line: 396)
Drupal\Core\Entity\Sql\SqlContentEntityStorage->doLoadMultiple(Array) (Line: 242)
Drupal\Core\Entity\EntityStorageBase->loadMultiple(Array) (Line: 212)
Drupal\Core\Entity\EntityStorageBase->load(Object) (Line: 176)
Drupal\commerce_order\Element\ProfileSelect::processForm(Array, Object, Array)
call_user_func_array(Array, Array) (Line: 982)
Drupal\Core\Form\FormBuilder->doBuildForm('commerce_checkout_flow_multistep_default', Array, Object) (Line: 1045)
Drupal\Core\Form\FormBuilder->doBuildForm('commerce_checkout_flow_multistep_default', Array, Object) (Line: 1045)
Drupal\Core\Form\FormBuilder->doBuildForm('commerce_checkout_flow_multistep_default', Array, Object) (Line: 557)
Drupal\Core\Form\FormBuilder->processForm('commerce_checkout_flow_multistep_default', Array, Object) (Line: 314)
Drupal\Core\Form\FormBuilder->buildForm('commerce_checkout_flow_multistep_default', Object) (Line: 212)
Drupal\Core\Form\FormBuilder->getForm(Object, 'order_information') (Line: 94)
Drupal\commerce_checkout\Controller\CheckoutController->formPage(Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 574)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
call_user_func_array(Object, Array) (Line: 144)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 64)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 99)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 78)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 50)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 656)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
johnhuang0808’s picture

The error in comment #96 occurs by the commerce_shipping module. Because commerce_shipping uses commerce_profile_select form element, it should be updated to follow the new array structure.

Current commerce_profile_select type in commerce_shipping module:

$pane_form['shipping_profile'] = [
  '#type' => 'commerce_profile_select',
  '#default_value' => $shipping_profile,   // If the shipping profile is empty, it should be null
  '#default_country' => $store->getAddress()->getCountryCode(),
  '#available_countries' => $available_countries,
];

commerce_profile_select type in PR#760 and code snippet is here.

$form['billing_profile'] = [
  '#type' => 'commerce_profile_select',
  '#default_value' => $profile,
  '#default_country' => 'FR',
  '#available_countries' => ['US', 'FR'],
  '#profile_type' => 'customer',
  '#owner_uid' => \Drupal::currentUser()->id(),
];
johnhuang0808’s picture

If PR #760 will be accepted and release in RC2 #2895339: Release Commerce 2.0-rc2, a new issue for working on the shipping profile should also be added into RC1 #2902683: Create a 8.x-2.0-rc1 release.
I can try to work on it.

johnhuang0808’s picture

I enhanced the PR#760 on the commit. And it is ready for review. The discussion is also on the Github PR#760.

ransomweaver’s picture

@JeroenT and others, johnHuang has a commit on his fork of drupalcommerce/commerce_shipping that makes this work. my composer.json looks like this:

"drupal/commerce": {
                "reuse profiles": "https://patch-diff.githubusercontent.com/raw/drupalcommerce/commerce/pull/760.diff",
                "reuse profiles enhanced": "https://github.com/fliegen/commerce/commit/57c11175d279fe55db9454b4274608195211aeb8.diff"
              },
 "drupal/commerce_shipping": {
                "profile select enhancement": "https://github.com/fliegen/commerce_shipping/commit/797b5ef351851d60b2cb6c1a55837501c2a036a5.diff",
            }

@bojanz, can we bump this issue to major? It seems to me that profile reuse is a requirement of a full release, and therefore an RC, and there's getting to be too much code scattered in different folks' git branches. I think it needs to be reviewed and brought into the master branches so that people can get onto the RCs.

johnhuang0808’s picture

Hi @ransomweaver, thanks for your testing. The commerce_shipping doesn't complete, because the multiple shipment testing in commerce_shipping module doesn't pass.

ransomweaver’s picture

I have added a patch to this issue: https://www.drupal.org/node/2852207#comment-12250322 "Billing same as Shipping" which gets it working with PR 760 instead of the obsolete PRs 714/715

ransomweaver’s picture

Related issue for Commerce Shipping: https://www.drupal.org/node/2908683

bojanz’s picture

Assigned: Unassigned » bojanz

Took me a crazy amount of time to finish the related #2890858: Default Country for the Payment Information form not inherited which incorporated 5 different bugs.
Now to finish and merge this one.

JeroenT’s picture

Status: Needs work » Needs review
bojanz’s picture

Status: Needs review » Needs work
FileSize
39.99 KB

Unfortunately, I was unable to get this code functional in time for 2.0, despite spending almost 2 days on it.
Attach my current progress.

The main problem with the PR we started with is that it changes ProfileSelect to be a FormElement, and uses a valueCallback() to process input. This causes a number of issues with the embedded entity form, so it had to be changed. However, changing that requires rewriting the entire flow.

Also, the UX of the PR did not match the UX of commerce_addressbook 3.x, opening the edit/add mode needed to hide the dropdown (otherwise we get an Address dropdown right above the Country dropdown, which looks confusing), and we needed a "Return to address selection" cancel button below it.

As others noticed, we had duplicate #name keys which didn't take $element['#parents'] into account, and clashes in $form_state itself for the form flag.

Finally, we had no revision handling that would protect entities against changes.

I fixed all of these problems, reviewed the UX with the Commerce Guys team, and the internal implementation with several core contributors. However, I ran into form issues that I could not solve in time.

Apply the patch, enable commerce_order_test, and go to "/commerce_order_test/profile_select_test_form". Click "+ Enter a new address". You will see that clicking the "Return to address selection" does nothing the first time. Under the hook, Drupal assigns the clicks to completely wrong elements. It treats selecting "Enter a new address" as a click to the Cancel button, and the click to the Cancel button as a click to the Edit button. This tells me that the process callback is rebuilding the form too early, but I don't know how to avoid that yet.

P.S. Opened the missing followup for profile copy functionality: #2910193: Allow reusing profile values from another inline form ("Billing same as shipping").

Jons’s picture

It would be great if we could add into the mix the ability to override the list of billing and shipping addresses, so as to create a set of addresses for specific users - hook_xxx_alter().

In our case - we're supporting some B2B - where a designated coordinator can set a range of addresses for linked purchasers (eg central office to deliver to a range of their shops, where someone in the shop can do the ordering, but billing goes to central office and goods go to only a pre-set address/list of addresses).

We sort out the registration and approval of the various parties and want to be able to set the appropriate addresses at checkout.

jackbravo’s picture

Status: Needs work » Needs review
FileSize
37.51 KB
38.51 KB

There is a PR in github by @jigish.addweb that solves this issue, and doesn't have the issue that @bojanz is describing. https://github.com/drupalcommerce/commerce/pull/796

This is the .diff pf that PR.

johnhuang0808’s picture

Hi @bojanz, I have no idea how to enable commerce_order_test module, since the drush and Drupal modules page don't find the commerce_order_test module. Could you help me to enable it?

ptmkenny’s picture

@johnhuang0808 You need to enable the extension_discovery_scan_tests in settings.local.php on your local dev environment to see the test modules.

ransomweaver’s picture

For anyone who would like to get to 2.0 or the current dev and also have a functioning profile reuse with shipping/billing, here's my solution until this issue has been resolved.

The obstacle to applying PR 760 as a patch is merely that there was a small change made to ProfileSelect to check that the specified default country is actually available. The attached patch reverses that commit so that PR 760 can apply. If this check on the default country is important to you, I suggest making your own patch and putting it on gist to apply after PR 760 has been applied.

Here is some composer.json that puts this all together, including checkbox same as billing and auto-recalculate shipping:

"drupal/commerce": {
      "reverse profileSelect change to allow PR 760": "https://www.drupal.org/files/issues/2844920-reverse-profileSelect-temp-fix.patch",
      "reuse profiles": "https://patch-diff.githubusercontent.com/raw/drupalcommerce/commerce/pull/760.diff",
      "reuse profiles enhanced": "https://github.com/fliegen/commerce/commit/57c11175d279fe55db9454b4274608195211aeb8.diff",
      "checkbox same as billing": "https://www.drupal.org/files/issues/checkbox-same-as-billing-2852207-69.patch",
  }
  "drupal/commerce_shipping": {
      "profile select enhancement": "https://github.com/fliegen/commerce_shipping/commit/797b5ef351851d60b2cb6c1a55837501c2a036a5.diff",
      "profile in shipping method widget fix": "https://www.drupal.org/files/issues/profile-reuse-enhanced-2908683-1.patch",
      "auto-recalculate shipping": "https://www.drupal.org/files/issues/commerce_shipping-autorecalculate-2849756-35.patch"
  }
Lukas von Blarer’s picture

@ransomweaver wow, this comment is a life saver! Thank you!

Anonymous’s picture

@ransomweaver Thank you for your composer patches collection.

Lukas von Blarer’s picture

@ransomweaver Those patches combined have one issue: If I adnavce in the checkout until the review step and then navigate back to the step where my shipping information pane is, I get the following error:

TypeError: Argument 1 passed to Drupal\commerce_tax\TaxZone::match() must implement interface CommerceGuys\Addressing\AddressInterface, null given, called in /var/www/drupal/public_html/web/modules/contrib/commerce/modules/tax/src/Plugin/Commerce/TaxType/LocalTaxTypeBase.php on line 278 in Drupal\commerce_tax\TaxZone->match() (line 138 of /var/www/drupal/public_html/web/modules/contrib/commerce/modules/tax/src/TaxZone.php) #0 /var/www/drupal/public_html/web/modules/contrib/commerce/modules/tax/src/Plugin/Commerce/TaxType/LocalTaxTypeBase.php(278)

After that the shipping address fields are cleared. The user has to edit the shipping profile and re-enter all information.

I'm still trying to find out what is causing this. Can anyone reproduce this behavior?

bmcclure’s picture

I've been struggling with an issue using this patch combination where the shipping fields don't seem to have been saved to the profile by the time shipping is calculated. So, for example, in FedEx, the code $shipment->getShippingProfile()->address->isEmpty() returns TRUE and no rate request is attempted.

Is anyone else running into this? It must be some sort of conflict between either patch versions or commerce and commerce_shipping versions it seems like, but I don't yet know why. I'm on the latest dev version of both currently.

Lukas von Blarer’s picture

Yes, I have the same issue when moving back in the checkout process. In my case this happens when moving to the login step and choosing the guest checkout option. After that the shipping profile fields are empty and I get the error I mentioned in #114.

Which patch is causing this to happen?

jeetmail72’s picture

Component: User experience » Commerce
Category: Task » Feature request

Hi

Please use this Drupal 8 module. I think it will full fill your requirement. This module allows reusing the existing address in the checkout form.

https://www.drupal.org/project/address_checkout

ransomweaver’s picture

Category: Feature request » Task
ptmkenny’s picture

I'm using the patches suggested in #111.

With these patches, "New address" appears to be selected by default.

I think it makes more sense to select the default customer profile address (if the customer has already made an order and input an address) since in many cases, the person probably is using the same billing address/having goods sent to the same place.

ransomweaver’s picture

@ptmkenney #119 I'm not seeing that. I have the following:

1 - new user creates account prior to entering checkout info page
2 - user enters shipping info and cc card info, billing same as shipping or enters separate billing address
3 - completes order
4 - adds another item to cart and goes to checkout
5 - user lands on checkout info page with a) previous shipping address selected in the "select a profile" dropdown b) previous payment method selected by radio button "visa ending in ...."

I can't make any more fixes to this, as its now a dead end. See @bojanz in #106 for the way forward. This issue is at the top of the commerce roadmap issue list: https://www.drupal.org/project/commerce/issues/2913801

ptmkenny’s picture

Status: Needs review » Needs work
Related issues: +#2844920: Allow customer profiles to be reused

@ransomweaver Ok, it's an issue with my configuration then. I didn't realize your patch was a dead end because the issue was set to "Needs review". I'm adding the new issue as a related issue to make it easier for people who are searching for this to find.

flocondetoile’s picture

For info, the patches collection from #111 still applied well on commerce 2.2 :-)

Joao Sausen’s picture

#111 looks fine, but everything here breaks the hook_commerce_shipping_methods_alter() since the $shipment in the hook will be a blank shipment, so you can't compare it to the methods in order to custom show/hide it.

flocondetoile’s picture

Experienced similar issue as described in #123. In a custom shipping method, the shipping profile was not set on the shipment, preventing to make comparisons. Something must be wrong in the ajax request. Didn't find time to explore this issue. I finally removed patchs #111.

dionsj’s picture

@ransomweaver: The patches you mentioned does indeed make it all work for me, with one major problem:

If I add a new field to the profile (CVR field, just a plain text field) it does not get saved properly in the form during checkout if I make modifications to it there, whereas the default profile fields do get saved (when editing an existing profile).

I would like to have a look at solving this myself, and am currently looking into how to do that, but if you (or anyone) know where the problem is likely occuring in code, that would save me some time.

heddn’s picture

Issue summary: View changes

Updating IS and seeing what the difference is between the PR in #108 and the patch in #106.

heddn’s picture

106 applies, but 108 needs a re-roll. It also looks like the PR in #108 won't work with the current code base based on https://github.com/drupalcommerce/commerce/pull/796#issuecomment-333904322.

So that means we need to figure out the click assignment issue from the early process callback.

heddn’s picture

I spent a little time looking into this. I was hoping I would be able to move this along, but alas, I cannot. The ajaxRefresh call returns the form and state using the fall through of element state mode = form. Because the form is built prior to calling ajax. We need to return the form as if the element state mode = view. But we don't have a good way to trigger on that because the FormBuilder (around lines 1095) defaults to setting the trigger_element to the first button in the form, even on first paint of the form. When there isn't any button pressing. I tried adding a (hidden) dummy button on the page so the first button is something else so we can trigger on a valid pressed button. But that didn't work either for some reason. I couldn't even get the form to print on refresh.

TLDR; No further progress. But I'm happy to review anyone's work that is able to fix the problem. The patch in #106 works pretty well otherwise.

heddn’s picture

I wonder if we can use the same approach that is used by commerce_shipping's re-calculate shipping button on the shipping info checkout pane.

  • Use a button. Important
  • Set a form state flag in the submit or validate handler signaling which element state form mode to use.
  • Then re-execute the logic in the element build logic using the form_state flag to determine what form elements to return
Lukas von Blarer’s picture

The patches still work great for me on Commerce 2.3, except for the issue I described in #114. Somehow the existing profile is lost if an anonymous user navigates back and forth in the checkout process. Can anyone else reproduce this?

Here is an issue that tries fixing the WSOD, but the issue remains: #2925470: Address variable should be optional in TaxZone::match().

JeroenT’s picture

Priority: Normal » Major
s.messaris’s picture

The method in #111 no longer works for commerce 8.x-2.4.

ericchew’s picture

Here is the patch from #106 applied to commerce 8.x-2.4

heddn’s picture

Assigned: bojanz » heddn

Going to start plugging away at this with my comments from #129 as the start.

heddn’s picture

There's still an issue with form state getting stale. But otherwise, this is much further along.

Status: Needs review » Needs work

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

heddn’s picture

Assigned: heddn » Unassigned
Status: Needs work » Needs review
FileSize
41.47 KB
2.04 KB

This resolved the issue in #135. So now we have a fully functional widget. Next is to fix up tests. If someone gets to that first, great. Un-assigning for now.

Status: Needs review » Needs work

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

heddn’s picture

FileSize
41.49 KB
2.05 KB

Just fixing phpcs findings before I forget about it.

heddn’s picture

FileSize
528 bytes
41.77 KB
StijnStroobants’s picture

Thanks for this great patch!
Working perfectly for the Payment information.

I tried to use it in combination with commerce_shipping, but the following error occurs:

The website encountered an unexpected error. Please try again later.
TypeError: Argument 1 passed to Drupal\Core\Entity\EntityViewBuilder::view() must implement interface Drupal\Core\Entity\EntityInterface, null given, called in /Users/stijn/websites/test-commerce/www/modules/contrib/commerce/modules/order/src/Element/ProfileSelect.php on line 214 in Drupal\Core\Entity\EntityViewBuilder->view() (line 110 of core/lib/Drupal/Core/Entity/EntityViewBuilder.php).

Maybe this is a commerce_shipping issue. This evening I will try to debug further.

commerce 8.x-2.4
commerce_shipping 8.x-2.0-beta4

heddn’s picture

Status: Needs work » Needs review
FileSize
41.77 KB
1.48 KB

I cannot seem to get phantomjs to run and store my user session, so local running of tests are falling on their face. Hopefully the testbot is more merciful. Here's an attempt at getting the first anonymous test to pass.

heddn’s picture

The last submitted patch, 142: 2844920-142.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 143: 2844920-143.patch, failed testing. View results

StijnStroobants’s picture

I fixed the error in #141 by patching the commerce_shipping module. (https://www.drupal.org/project/commerce_shipping/issues/2948954)

Now I can use the functionality for both fields. Only issue I have now is that the AJAX-functionality for editing the profile is only working on the first widget on that page.

heddn’s picture

Status: Needs work » Needs review
FileSize
9.17 KB
41.39 KB

Status: Needs review » Needs work

The last submitted patch, 147: 2844920-147.patch, failed testing. View results

heddn’s picture

So, after some actual attempts to implement the above patch. I think it won't work. See https://twitter.com/lucashedding/status/971083165895970817

Let's see if we can do this another way.

heddn’s picture

Status: Needs work » Needs review
FileSize
38.29 KB
36.89 KB

Not sure how helpful the interdiff is going to be. This is an entire new approach by loading the entity add and edit forms in a modal. The UX is mostly OK. Tests are probably not passing yet. But things work and we get around the previous buggy problems.

Status: Needs review » Needs work

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

ericchew’s picture

Nice work Heddn. I've made a few additions

  • If no profiles exist, the user is presented with the "add new profile" link by itself. I modified the patch so that it shows the default profile form if no profiles exist.
  • I added the 'button' CSS class to make the links prettier

One issue I have found is when editing a profile, the user can choose to delete the profile. After deleting, the redirect breaks and you are shown AJAX command info instead of going back to the checkout page.

One issue I have found is that in checkout, when you already have an existing credit card, then click create new credit card, the add and edit buttons destination parameter is messed up:?destination=/checkout/1/order_information%3Fajax_form%3D1%26_wrapper_format%3Ddrupal_ajax

JeroenT’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

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

ericchew’s picture

Changed the AJAX wrapper to wrap the entire element so that the edit button is updated properly when switching profiles. I modified the destination parameter to get the path a different way so that AJAX parameters aren't included.

heddn’s picture

Status: Needs work » Needs review

Here's some more refactoring and accounts for anonymous cart checkout. For anonymous, we cannot really use a select widget as we cannot load a list of previous profiles.

heddn’s picture

Status: Needs review » Needs work

The last submitted patch, 157: 2844920-156.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Eric Heydrich’s picture

The last patch didn't work. I get the following error:

InvalidArgumentException: The commerce_profile_select #profile_type property must be provided. in Drupal\commerce_order\Element\ProfileSelect::validateElementProperties() (Line 90 in root/web/modules/contrib/commerce/modules/order/src/Element/ProfileSelect.php).

ericchew’s picture

@Eric Heydrich -- The reason you are getting that error is because you have something that is depending upon the old ProfileSelect element. If you use the patch in #157, you'll have to patch everything that utilizes the ProfileSelect element...such as the shipping information CheckoutPane (Issue # 2948954)

Alluuu’s picture

Hi,

This is my proposed approach for doing the reusable profiles in a way that shouldn't breaking anything, even as a temporary solution until something better comes along.

Basically I'm just adding a select options field to the element with an ajax onChange callback and would see that the fields could be pre-populated with corresponding profiles values, if any of the values were to be changed, a new profile would be created anyway and just in case for easier UX understanding I'd also add a "add new" option to the select list options, which would empty the fields but it shouldn't matter.

The code isn't finished, I still need to implement the changes to the actual form fields. As there seems to be an increasing demand for some sort of solution to this, I'm hoping this could be of any help or a considerable viable temporary solution. If it's of any interest I could finish the rest tomorrow ( I hope )

Best,

Alari

Alluuu’s picture

Sorry, I seem to have forgotten to declare a correct root folder for the patch, I'll upload again.

EDIT:
Apparently I don't know how to create a decent patch file :(

drugan’s picture

@Aluuu

Do this from inside commerce folder:

git diff > my.patch

heddn’s picture

Re: the continued work for #157, I wonder if we can drop the CRUD operations entirely to add or edit a profile. What I saw on amazon.com was only a select list. It was empty if there were no addresses. Then at the top of the page, there were links to the profile section of amazon to add/edit/delete (manage) profiles. We don't have to go that extreme, but we could copy it spirit.

What if we did the similar. Just print a select list of all profiles, then had another link widget or something to link folks to the profile collection route to manage profiles. This link wouldn't be apart of the select widget at all. But would be listed on the billing and shipping steps of a checkout. If the user is anonymous or doesn't have any profiles already created we could still give them the initial profile form directly on the page. But if they do have profiles, then just display them in the select list. And leave up to the user to find the link on the page to manage profiles if they want to add anything more than add the first/initial profile.

I arrived at this just now when working on a multiple destination shipping solution. The page looks UGLY when I give them a select list /and/ the buttons to manage their profiles. I'd much prefer just a simple select list and links at the top of the page to manage my profiles.

heddn’s picture

Issue summary: View changes
FileSize
35.71 KB

Here's a screenshot of how messy it looks. I want to hide the edit/add buttons. And move them to the top of the page.

ChandeepKhosa’s picture

Issue tags: +Needs usability review

@heddn #164 'I wonder if we can drop the CRUD operations entirely to add or edit a profile' I agree this would be a better user experience. Borrowing from Amazon is bound to be a good idea :)

I've added the 'Needs usability review' tag to this issue as I think it would be helpful.

In the meantime if anyone has a little time to move the add/edit buttons higher, and write a patch that would be awesome!

harings_rob’s picture

Not sure if dropping it would be a good approach. Maybe we can give 2 options?

Anyway a decision needs to be made at some point, but I often order something online, and I would not want to get redirected away from the checkout to modify my address.

As for the patches: 2844920-156.patch works great, but I found today that the profile type is hardcoded.

This should instead be taken from to profile type field.

I have rerolled te patch on top of latest dev. And I have also removed a hardcoded profile bundle from the widget.

harings_rob’s picture

FileSize
906 bytes

That interdiff doesnt look right.

heddn’s picture

Here's a quick hide of the operation buttons for billing. It isn't intended for use anywhere yet. Just to get a feel how hard it would be to hide it. It seems pretty easy actually.

heddn’s picture

FileSize
9.31 KB
38.1 KB

Here we fix up the first of the tests. More to come later.

fotograafinge’s picture

I keep getting these errors:

The website encountered an unexpected error. Please try again later.InvalidArgumentException: The commerce_profile_select element requires the #default_value property. in Drupal\commerce_order\Element\ProfileSelect::processForm() (line 80 of modules/contrib/commerce/modules/order/src/Element/ProfileSelect.php).

Not sure if it's caused by this patch (#171) or by the related issue #2948954: Commerce_profile_select reusable profiles

=> my mistake, solved

heddn’s picture

Status: Needs work » Needs review
FileSize
39.61 KB
7.44 KB

And here we are a little closer on tests. I think they are pretty close now. If someone with more FunctionalJavascript experience wanted to look at things, this might be able to wrap up pretty easily.

Status: Needs review » Needs work

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

heddn’s picture

Issue summary: View changes
Status: Needs work » Needs review
FileSize
39.92 KB
9.04 KB
32.18 KB

I'm almost able to get tests passing. But the modal button is off-screen and isn't clickable in phantomjs.

Status: Needs review » Needs work

The last submitted patch, 175: 2844920.patch, failed testing. View results

heddn’s picture

Status: Needs review » Needs work

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

Joao Sausen’s picture

I'm still following this issue, thanks for all the work heddn.

heddn’s picture

heddn’s picture

Status: Needs work » Needs review
FileSize
41.36 KB
8.46 KB

It was green on local. Let's see if we can make it pass on the bots too.

Status: Needs review » Needs work

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

heddn’s picture

Status: Needs work » Needs review
FileSize
63.76 KB
25.05 KB

Status: Needs review » Needs work

The last submitted patch, 183: 2844920-183.patch, failed testing. View results

heddn’s picture

Status: Needs work » Needs review
FileSize
63.76 KB
889 bytes
heddn’s picture

FileSize
11.95 KB
64.62 KB

The last submitted patch, 185: 2844920-185.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 186: 2844920-186.patch, failed testing. View results

heddn’s picture

FileSize
65.28 KB
1.56 KB

Something in here is causing the tests to hang. I'm moving on to other stuff, perhaps someone else with a new set of eyes can figure out what is going on.

heddn’s picture

Issue summary: View changes
FileSize
65.39 KB
1.01 KB
19.52 KB

Here's an option to hide the profile preview. Combined with hiding the operation buttons, it makes it possible to do the following:

No further improvements on tests. I'm blocked.

drugan’s picture

@heddn++

You are a real fighter! Great work!

the only notice is that I have a profile marked as default but when the checkout payment information pane is loaded I see another profile preselected which is not default but just the very first in the list of my profiles

UPDATE: sorry it was my custom hack on profiles now it works as expected :)

F_D_E’s picture

There is an insecure direct object reference on selected profile which is not trapped by Drupal permission.

The access right to the selected profile id (=selected_option) is not checked at the server side.
Finally, a malicious user can easily access to personal data about others users.

alexpott’s picture

+++ b/modules/order/tests/modules/commerce_order_test/src/Form/ProfileSelectTestForm.php
index 9476000..104a404 100644
--- a/modules/order/tests/src/Functional/OrderAdminTest.php

--- a/modules/order/tests/src/Functional/OrderAdminTest.php
+++ b/modules/order/tests/src/Functional/OrderAdminTest.php

This needs to move to the FunctionalJavascript folder. And then the test runner should work again.

heddn’s picture

Status: Needs work » Needs review
FileSize
82.62 KB

Let's see how that fares.

Status: Needs review » Needs work

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

heddn’s picture

Status: Needs work » Needs review
FileSize
22.21 KB
94.21 KB

Hmm, let's see if this fixes any failures. I know there will be some, just curious what is left.

Status: Needs review » Needs work

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

heddn’s picture

Status: Needs work » Needs review
FileSize
95.25 KB
6.24 KB

Status: Needs review » Needs work

The last submitted patch, 198: 2844920-198.patch, failed testing. View results

rwanth’s picture

In order for this to be mobile responsible, we should not be using a modal for new profile entry. "Enter a new profile" should be part of the "Select a Profile" dropdown, which should trigger an inline form when selected.

heddn’s picture

Issue summary: View changes
FileSize
82.95 KB

While doing an inline form would be ideal for many reasons, it isn't necessary for mobile responsive experience. For the last hundred or so comments, we've been basically saying that doing inline isn't really working.

Here's a recent screenshot of the modal on a simulated S5 display port. Doesn't look bad to me. Are you seeing it differently on your site?

drugan’s picture

in my mind we should return to the solution suggested in the parent issue:

https://www.drupal.org/node/2841813#comment-11857677

How it works:

on a payment (billing, shiiping) information checkout pane user sees a regular profile form automatically populated with values from a profile which is marked as default OR, if there is no default profile, the very first profile in the list of a user profiles.

default

In the dropdown user may choose another profile OR, clicking at the - New information - option get an empty profile form with address fields for a default country. Obviously that changing a country or a profile with different country will change address fields which are specific for this country.

choose

No any additional buttons are needed. Clicking at the Continue to review button user will either:

  • save changes on an existing pre-selected profile OR, just resave it if there is no changes.
  • save a new profile if the appropriate option was chosen.

I've re-roled the patch from the above link and use it on my dev site right now and even have a thought to create a module for the feature if the current issue will not be fixed in a reasonable amount of time.

rlangille’s picture

IMHO modals are not the way to go with this. Mobile + modals are always a bad combination, and I can't see them playing well with usability or accessibility.

What we have here essentially an entity reference field with an inline entity form and we're saying that's a dead end? I find that rather hard to believe considering all of the places these have been successfully used in the past and all the cases they cover.

If we need to move this up to a higher level and resolve this in the flow as Bojanz mentioned, or by changing how the data is used and referenced, then my vote is for that over introducing more complexity in the UI here.

enorby’s picture

When going through checkout as an anonymous user, shipping rates are not being displayed when hitting the "Recalculate shipping" button. Rates are returned correctly when trying to submit the form without first fetching the rates, but attempting to fetch rates returns nothing and submitting the form gives the "An illegal choice has been detected" error.

Patch #162 worked fine. I installed patch #167, updated the commerce_profile_select form element in ShippingInformation to reflect the changes in ProfileSelect, and that is when this problem was introduced for me.

jonnyeom’s picture

For patch #198, I am seeing a bug where when I change the Shipping Profile, the shipping rates are retrieved with the initial/default shipping_profile that was loaded when the page loaded.

Example.
1. Order_Information pane loads with profile 1.
2. Shipping rates retrieved for profile 1.
3. User chooses profile 2.
4. On the Ajax call, shipping rates retrieved for profile 1.

If I press "Go to Review", the rates for profile 1 is used.
However, If I then go back to the order_information pane, the rates are now correctly loaded with the profile 2 rates.

Thoughts guys?
Maybe, the form_state is saved in a strange way for these multi pane forms?

heddn’s picture

Let see if chromedriver is any better than phantom.

Status: Needs review » Needs work

The last submitted patch, 206: 2844920-206.patch, failed testing. View results

heddn’s picture

Issue summary: View changes
FileSize
512.21 KB

Attaching an animated gif of the usage of the form element in use. Hopefully that will make it easier for driveby reviews.

There's lots of place we use profile_select, so instead of getting all the tests to pass green again, let's be sure we are doing the right thing...

heddn’s picture

This passed tests on local against 8.6. Let's see how the testbot likes things.

heddn’s picture

Status: Needs review » Needs work

The last submitted patch, 209: 2844920-209.patch, failed testing. View results

heddn’s picture

Status: Needs work » Needs review
FileSize
2.36 KB
110.78 KB

Status: Needs review » Needs work

The last submitted patch, 212: 2844920-212.patch, failed testing. View results

heddn’s picture

Status: Needs work » Needs review
FileSize
1.34 KB
110.17 KB

Seems we lost some element validation. Not sure where that got dropped. Let's see what happens when we re-add it.

Status: Needs review » Needs work

The last submitted patch, 214: 2844920-214.patch, failed testing. View results

rgpublic’s picture

Hm. I'm using patch #214 and the shipping bugfix mentioned in #100. I have a profile selector for billing. But I don't see any profile selector for shipping. It used to work back then, and now that I've come back on a project and updated Drupal commerce, got new patches etc, the shipping selector just disappeared :-( Any hints on how to disentangle this maze of interdependent patches is much appreciated...

Lukas von Blarer’s picture

Does anyone have a patch compatible with #2852207: Billing same as shipping?

s.messaris’s picture

The patch in #214 does not get the default billing profile correctly, because of an error in the sorting logic. Here is a fix.

s.messaris’s picture

Changing all uses of self:: to static:: in ProfileSelect class to allow classes extending it to override specific functions without problem.

Lukas von Blarer’s picture

Status: Needs work » Needs review

Lets run the tests.

The last submitted patch, 218: 2844920-218.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 219: 2844920-219.patch, failed testing. View results

mattjones86’s picture

The latest patch doesn't seem to apply to commerce 2.8, is it easy re-roll the patch for that?

mattjones86’s picture

Nevermind, checked it myself and it wasn't a major change. 8.x-2.x-dev compatible patch attached.

mattjones86’s picture

FileSize
70.48 KB

Another go... hopefully tests pass on this one.

Gah, somehow I missed the AdminOrderTest file.

mattjones86’s picture

FileSize
85.09 KB

3rd time lucky... if this doesn't work I'll wait for someone who knows a bit more about the patch to look at it!

m.ioannidis’s picture

Please, see revised #219 patch.
It properly loads the profile using revision id instead of profile id.

KittenDestroyer’s picture

Taking as base #219 patch I've added fix for using default value if no user input present. The problem was that when you go back from review to order information, there was other value selected.

KittenDestroyer’s picture

Status: Needs work » Needs review

Updating status

mglaman’s picture

Assigned: Unassigned » mglaman

Let's pause this for a minute. Since #214 patches have been added but don't apply. No interdiffs. And no discussion on fixes usability problems (modals causing page refresh).

mglaman’s picture

The primary goals of this issue were to implement the user experience developed in the 3.x branch of the Addressbook module. See https://www.drupal.org/files/project-images/Capture%20d%E2%80%99e%CC%81c...

We ran into Form API issues due to the way AJAX is handled on buttons vs non-buttons, leading to weird states after AJAX operations. That's about where we ended up in #106.

This patch brings us back to #106. Amazon is not a good example of UX, and core's current support for modals and their styling is lacking. We cannot have a modal cause a page refresh during checkout. With this patch we have a select list which shows the profile, allows clicking "edit" to modify values, or changing to create a new profile.

Instead of relying on Form API to change from "view" to "edit" and "cancel", we can just use some client-side JavaScript to show and hide elements. In hindsight, I wish I would have stepped back enough previously to recognize this.

Here is a patch which builds on #106. Continues revision support, and the UX.

Remaining items:
- Verify testProfileSelectAuthenticatedEdit passes (local was fighting over it, wouldn't complete)
- Test revision support
- Test revision support in context of a placed order
- MOAR TESTS!

Here is a crude demo.

Addressbook demo

Status: Needs review » Needs work

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

mglaman’s picture

This patch fixes some fatal errors which were causing the failures. To ease any breaking changes, I want to still support #default_value but also #profile_type and #profile_uid. This patch is still a blend, but more test fixes.

I'd also like to use getValue() from the form state properly, but persist #profile to prevent breaking changes (ie: shipping.)

If curious for interdiffs, see https://github.com/mglaman/commerce/commits/addressbook3x. I'm making various commits along the way and posting progress here.

Status: Needs review » Needs work

The last submitted patch, 233: 2844920-233.patch, failed testing. View results

mglaman’s picture

Status: Needs work » Needs review
FileSize
42.13 KB

This should fix the order admin test.

Next things:

- Test revision support
- Test revision support in the context of a placed order
- Look into @todo AJAX on the order item IEF shouldn't cause read mode on profile.
- Implement profile_type and profile_uid instead of just relying on default_value (and update commerce implementations) (and implement BC handling in validateElementProperties?)

jonnyeom’s picture

Status: Needs review » Needs work

Thanks for the patch @mglaman.
Here are the issues I am currently seeing with the latest patch (235)

  1. Recalculate Shipping button is not able to extract any updated form values. Basically, it uses the address that was initially selected or attached to the shipment and recalculates the rate for that address over and over.
  2. I'm sure this is related to the first one. After editing an address and Recalculating Shipping (There is no Save button so I am assuming recalculating should auto save/update the address), the address fails to update.

Side Note: If I proceed to the next Checkout step and come back to this step, The Shipping is recalculated with the proper address. Therefore, I am pretty sure that the Shipment object is not being properly updated before being sent to the Shipping Rate Plugins.

I feel like some update should be getting triggered between the following lines: web/modules/contrib/commerce_shipping/src/Plugin/Commerce/CheckoutPane/ShippingInformation.php:277 - 282

      $shipment = clone $pane_form['shipments'][$index]['#shipment'];
      $form_display = EntityFormDisplay::collectRenderDisplay($shipment, 'default');
      $form_display->removeComponent('shipping_profile');
      $form_display->removeComponent('title');
      $form_display->extractFormValues($shipment, $pane_form['shipments'][$index], $form_state);
      $form_display->validateFormValues($shipment, $pane_form['shipments'][$index], $form_state);

I have not been able to confirm.

Overall UI/UX wise, no problems.

mglaman’s picture

Assigned: mglaman » Unassigned

jonnyeom thanks for testing! I have not tried testing it with shipping at all, yet. So I appreciate that.

Recalculate Shipping button is not able to extract any updated form values. Basically, it uses the address that was initially selected or attached to the shipment and recalculates the rate for that address over and over.

I think this makes sense, user input is our problem here. The form rebuilds the state from user input.

I'm sure this is related to the first one. After editing an address and Recalculating Shipping (There is no Save button so I am assuming recalculating should auto save/update the address), the address fails to update.

Ugh, I'd wish it didn't save changes, but preserved them in the user input. So if we fix the first, we should fix this one as well.

Overall UI/UX wise, no problems.

🙌🙌🙌

Jons’s picture

Hi
I tried creating an order with an existing profile with address, then repeating but clicking Edit and changing the customer name and completing the order.
The new values get saved on the profile and this gets assigned to the order. The changes also appear on previous order.
Would it be better if orders reflect the address at the time of the order - rather than an updated version?
Could revisions be used internally to achieve this, or should we stop edits?
I can see that revisions are used in the code but dont seem to be in this scenario?

Jons’s picture

We have a use-case where only a pre-defined set of profile addresses should be used by some users which would be pre-assigned to user, so we would not want the _new option or the edit button.

I tried to influence via HOOK _field_widget_form_alter() or HOOK_field_widget_multivalue_form_alter() or HOOK_form_alter() but could only see single address widget data not 'commerce_profile_select'

rwanth’s picture

Minor UX problem, the edit profile button always appears immediately after the first field. If a site config has additional fields on the profile, like a telephone number, it appears after the button. Still functions properly.

mglaman’s picture

Not sure why you hid my patch in #235. Putting it back.

+++ b/modules/order/src/Element/ProfileSelect.php
@@ -91,12 +110,173 @@ class ProfileSelect extends RenderElement {
+    $element['profile_view']['edit'] = [
+      '#type' => 'button',
+      '#value' => t('Edit'),
+      '#limit_validation_errors' => [],
+      '#attributes' => [
+        'class' => ['edit-profile'],
+      ],
+      '#access' => $default_profile->isDefaultRevision(),
+    ];

I thought there was a weight here! Specifying the weight to 100 should fix the reported UX issue.

mglaman’s picture

Assigned: Unassigned » mglaman

Working on this during downtime at Decoupled Days.

mglaman’s picture

Status: Needs work » Needs review
FileSize
42.67 KB
1.38 KB

Here's an update.

Included is a shipping patch as well, we'll need this fix and this patch to address #236

Adds fix reported in #240

These still stand:
- Test revision support
- Test revision support in the context of a placed order
- Look into @todo AJAX on the order item IEF shouldn't cause read mode on profile.
- Implement profile_type and profile_uid instead of just relying on default_value (and update commerce implementations) (and implement BC handling in validateElementProperties?)

mglaman’s picture

Okay, so this adds a lot of test coverage to the element, especially revisions.

Next step is

- Test revision support in the context of a placed order
- Look into @todo AJAX on the order item IEF shouldn't cause read mode on profile.

Status: Needs review » Needs work

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

mglaman’s picture

Status: Needs work » Needs review
FileSize
61.56 KB

phpcs + functional javascript test

mglaman’s picture

Updated OrderAdminTest to test the profile select.

mglaman’s picture

Actually I want a test for #238

The new values get saved on the profile and this gets assigned to the order. The changes also appear on previous order.
...
Could revisions be used internally to achieve this, or should we stop edits?

We do use revisions. I just realized what the problem is. If someone makes a change within the profile select element we need to flag it as a new revision on save. We're respecting the editing of old revisions, but nothing to ensure a new revision is created after edit and ensuring previous data.

EDIT: I looked at the patch and we have:

    // If the profile was modified, enforce a new revision.
    // When the _existing option is chosen, there will be no changes reported
    // preventing an accidental flag for the revision.
    if ($selected_available_profile->hasTranslationChanges()) {
      $selected_available_profile->setNewRevision();
      $selected_available_profile->save();
    }

We need a test, though.

We have a use-case where only a pre-defined set of profile addresses should be used by some users which would be pre-assigned to user, so we would not want the _new option or the edit button.

The profile select element isn't respecting permissions at this time. We can tie in permissions for the create and edit functionality.

s.messaris’s picture

Hi, thanks for your work @mglaman looks very nice. Only think I don't like is the getting of available and default profiles. If that happened in a different method, someone that needs custom logic for removing the option for new address or excluding some profiles could do that by overriding that function instead of the whole processElement() .

Jons’s picture

thanks
I'll test new patch in general
I did come across the setting for revisions to be switched on/off here: admin/config/people/profiles/types/manage/customer and mine was off (the default), now on

codedrill’s picture

It works well but i get javascript error on form submit if i do not change the dropdown value. The previously saved address is selected by default.

Uncaught Error: Quick Edit could not associate the rendered entity field markup (with [data-quickedit-field-id="profile/1/address/und/default"]) with the corresponding rendered entity markup: no parent DOM node found with [data-quickedit-entity-id="profile/1"]. This is typically caused by the theme's template for this entity type forgetting to print the attributes.

An invalid form control with name='payment_information[billing_information][address][0][address][given_name]' is not focusable.

It's because the address fields are required but there is no form to fill. So browser tries to highlight the required fields but it could not find them.

If i select Enter new address and then select back the saved address, it works fine.

mglaman’s picture

Okay, #249 I moved some of that logic to a method. There are some things we should abstract to make customizations easier.

Huh! For #250 I thought we had this enabled. This patch will do that.

For the JavaScript console errors in #251. That's going to be tricky. QuickEdit always has random errors when rendering elements and logged in as an admin. But the required element and focusing will need a trick, possibly. The usual workaround is #ajax, but we can't do that here.

bojanz’s picture

For QuickEdit we just need to make sure it's disabled for products. We already applied a similar trick to product variations.

mglaman’s picture

Assigned: mglaman » Unassigned
FileSize
71.87 KB

Here is a patch which addresses #249 and #250.

I need not debug #251, yet. That is just some normal JavaScript trickery we'll need to do.

This will fail testing because of revisions. ::testElementSubmission tests that editing an existing profile creates a new revision. However, at least in the kernel test, the revision IDs are the same. I don't know if this would work properly in a Functional test or not, I did not have time to write one. Kernel test was just faster. In \Drupal\Tests\commerce_order\FunctionalJavascript\ProfileSelectTest we should verify that anytime we edit a profile from profile_select a new revision is generated for those changes.

I'm going on vacation this week (and leaving the laptop behind!) so here is a summary:

  1. We need to review why a new revision is not being created whenever we save. We flag it as a revision, but the revision IDs always match
  2. Test the widget in a FunctionalJavascript test for orders. AJAX operations elsewhere on the page should not reset (or save) the profile_select element
  3. When the form is hidden, the element's JavaScript should toggle the required filter, much like the core Form API state does for required.
  4. Feature / follow up: Swapping elements is near impossible unless you swap the element manager. We need an Event that allows providing the profiles for the element to use. Like the FilterVariations event.

Thank you everyone who has reviewed and tested the work thusfar. We're getting pretty close.

EDIT: For the hidden I am assuming we could do this in the JavaScript. I think the :hidden selector will grab them since the parent is hidden.

(function ($, Drupal) {
  Drupal.behaviors.profileSelect = {
    attach: function (context) {
      var $selects = $(context).find('.profile-select').once();
      if ($selects.length > 0) {
        $selects.each(function (index, el) {
          var $profileSelect = $(el);
          // WORK WITH THIS.
          $profileSelect.find(':hidden').each(function (el) {
            el.required = false;
          });

          $profileSelect.find('.edit-profile').once().click(function (event) {
            event.preventDefault();
            // WORK WITH THIS.
            $profileSelect.find(':hidden').each(function (el) {
              el.required = true;
            });
            $profileSelect.toggleClass('editing');

            $profileSelect.find('.cancel-edit-profile').once().click(function (event) {
              event.preventDefault();
              $profileSelect.toggleClass('editing');
              // WORK WITH THIS.
              $profileSelect.find(':hidden').each(function (el) {
                el.required = false;
              });
            });
          });
        });
      }
    }
  };
})(jQuery, Drupal);

Status: Needs review » Needs work

The last submitted patch, 254: 2844920-253.patch, failed testing. View results

mglaman’s picture

Assigned: Unassigned » mglaman

Back from vacation and will continue on this.

ayalon’s picture

I cannot apply the patch in #254 to Commerce 2.8.0, also not applicable to commerce 2.x-dev. For which version is this patch meant?

ayalon’s picture

Ok. I was able to apply the patch to drupal 2.8.0. My bad.

My major question is: Did you take into account this issue?
https://www.drupal.org/node/2852207

At the moment I don't see a possibility, how these to implementations can work together.

But to have the same shipping address as the billing address is the most common usecase.

Do you think of solving this aswell?

mglaman’s picture

Cleaning up displayed files, so that the issue summary shows latest patch and required shipping patch.

josephdpurcell’s picture

FileSize
71.87 KB
2.63 KB

Attached takes patch 253 and changes the permission name from "create profile" to "create customer profile". The reason for this, is I was only seeing administrators as having the ability to add a new profile during checkout.

josephdpurcell’s picture

FileSize
71.92 KB

Whoops! I didn't create the 260 patch correctly. Re-uploading as 261.

mglaman’s picture

Status: Needs work » Needs review
FileSize
130.05 KB
666 bytes

Fixed the revision test. It was a written test error, which was caused the form to default to a new form each time instead of having a proper default value.

Copying my todos

  1. We need to review why a new revision is not being created whenever we save. We flag it as a revision, but the revision IDs always match
  2. Test the widget in a FunctionalJavascript test for orders. AJAX operations elsewhere on the page should not reset (or save) the profile_select element
  3. When the form is hidden, the element's JavaScript should toggle the required filter, much like the core Form API state does for required.
  4. Feature / follow up: Swapping elements is near impossible unless you swap the element manager. We need an Event that allows providing the profiles for the element to use. Like the FilterVariations event.

Status: Needs review » Needs work

The last submitted patch, 262: 2844920-262.patch, failed testing. View results

mglaman’s picture

Status: Needs work » Needs review
FileSize
1.76 KB
72.85 KB

Whoops. bad patch before. This new patch adds the JavaScript trick for handling required fields, and ensuring fields modified then canceled are restored to their original value.

  1. Test the widget in a FunctionalJavascript test for orders. AJAX operations elsewhere on the page should not reset (or save) the profile_select element
  2. When the form is hidden, the element's JavaScript should toggle the required filter, much like the core Form API state does for required.
  3. Feature / follow up: Swapping elements is near impossible unless you swap the element manager. We need an Event that allows providing the profiles for the element to use. Like the FilterVariations event.

Status: Needs review » Needs work

The last submitted patch, 264: 2844920-264.patch, failed testing. View results

mglaman’s picture

Status: Needs work » Needs review
FileSize
75.93 KB

* Fixes tests broken by permission checks
* Tests that editing a profile, changing a value, and then cancelling does not cause unexpected data change.

Status: Needs review » Needs work

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

mglaman’s picture

Status: Needs work » Needs review
FileSize
75.79 KB

Add a guard against deleted user. Also, found some permission bugs when editing an order.

Remaining task is FunctionalJavascript of editing a user to test the edit/select functionality.

mglaman’s picture

Assigned: mglaman » Unassigned
FileSize
78.99 KB

Updated patch which tests the order create/edit within FunctionalJavaScript.

Status: Needs review » Needs work

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

mglaman’s picture

🤦🏼‍♂️ totally forgot to annotate my new test, hence the failure.

mglaman’s picture

Status: Needs work » Needs review

The last submitted patch, 261: 2844920-261.patch, failed testing. View results

s.messaris’s picture

Status: Needs review » Needs work

I see some leftover console.logs in profile-select.js.

console.log(field);
console.log($profileSelect.find('[name="' + field['name'] + '"]').val());

Also, when having a profile field that references an old revision, I can't save any changes to the entity, I keep getting an error

The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.

I am not sure this is not a problem with my setup though, I will investigate it further and comment again if I find something.

s.messaris’s picture

I was able to reproduce the problem I mentioned in #274 on a clean installation. This is a serious bug, since it completely breaks order administration when an address is an old revision.

Steps to reproduce:

  1. Install commerce with the patch in 271. Only commerce_order, commerce_checkout and their dependencies are needed to reproduce this.
  2. Create a store and a product.
  3. As a logged in user buy the product, completing the checkout normally, resulting in order #1.
  4. Buy it again, this time you will see your previously entered address in the checkout. Click edit and make some changes and complete the order, resulting in order #2.
  5. As an admin, edit order #1 (e.g try to add an adjustment). You will get an error "The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.".
mglaman’s picture

s.messaris thanks! We have some tests around this - but not in functional (I think only kernel). We'll need toupdate the tests!

Thank you for testing.

mglaman’s picture

Found another bug where the Address module causes a loss of data on "edit"

    // The #value has the new values on #ajax, the #default_value otherwise.
    $value = $element['#value'];

This causes the address to clear our its values in the following scenario

* User has an existing payment method
* User opts to add a new payment method
* User's default billing profile displays in READ properly
* Click edit and the address is blank
* Change to "+ New" and then back to default address
* Address is populated (because #value is OK?)

mglaman’s picture

This patch is a quickly addresses #274 and #277.

I need to write a test for #275 and #277.

mglaman’s picture

+++ b/modules/order/src/Element/ProfileSelect.php
@@ -107,8 +294,9 @@ class ProfileSelect extends RenderElement {
+      // @todo resolve problem with \Drupal\address\Element\Address::processAddress
+      $widget_element['address']['#value'] = $widget_element['address']['#default_value'];

Wow, that broke a lot! Removing.

s.messaris’s picture

I found another issue here, if I go through an anonymous checkout, in a flow where there is a step after the one that contains the billing info, and go back I cannot edit the info, since anonymous users don't have the "edit own profiles" permission. Giving that permission to anonymous users really isn't an option, since with it they are able to edit any anonymous user's profiles.

mglaman’s picture

re: #280. Shoot. If this is the case, I would rather remove any permissions on the element and try to figure that out later.

mattjones86’s picture

Please ignore -- I thought I had another issue here but it was actually with #2948954: Commerce_profile_select reusable profiles #27

s.messaris’s picture

Hi there, any progress on #275 and/or #280?

s.messaris’s picture

I think simply trying to save the order in the end of OrderAdminTest::testEditOrder() will brink up #275. Here is a patch that should fail on that.

s.messaris’s picture

Issue tags: +Needs tests
FileSize
1.65 KB
79.28 KB

I don't know why #284 test passes, the method I described in #275 reproduces the problem. :/

I think the attached patch solves both #275 and #280, but we are still missing tests so I am leaving this as needs work.

andyg5000’s picture

It looks like the last few patches hose shipping recalculation (even with unpatched commerce_shipping-2.xdev).

The rate collection methods fire and the shipment is empty.

heddn’s picture

See the latest patch in #2948954: Commerce_profile_select reusable profiles. That should fix things.

andyg5000’s picture

@heddn was correct. Please disregard my comment in #286.

_dcre_’s picture

There seems to be a bug in the latest patch (#285)

It looks like, it clones the default (selected/saved) profile and clears its field values, or something similar.
This process has a flaw, at least on my implementation.

I have appended the default commerce 'customer' profile with a paragraph of mine.
This paragraph contains some extra fields i need to have on the profile.

Problem is that when i hit the '+ Enter a new address' select option, the new profile that is created somehow preserves the same target_id of my custom paragraph, as the already selected one.
This has as a result that although multiple profiles can be created, they all reference the same paragraph.
When a new profile is created, a new paragraph should also be created and its new target_id should be applied on the new profile.

trickfun’s picture

the patch 285 cannot be apply to 2.x-dev current version.

why is so hard to complete this feature?
and why this form element doesn't work with ajax_callback?

andyg5000’s picture

After reports of address values being overwritten unintentionally, I've determined that the patch in #285 doesn't work for the admin order interfaces and can lead to data loss. Looks like the JavaScript that fires to copy values from profile select option list to the actual form elements is only built to work on checkout forms. Will report back if I can figure out a fix for that.

Update:

The issue on admin forms appears to be in FAPI and related to #parents being set properly before the following is called.

$form_display->buildForm($default_profile, $element['profile_form'], $form_state);

If you expose the 'profile_form' element on the admin order edit form (remove visible-on classes), you'll see the form values don't update. No problem on checkout form.

andyg5000’s picture

Not sure this is the best approach to fix the issue, but gets to the point and solves #291. Leaving as needs work.

andyg5000’s picture

andyg5000’s picture

3rd time is a charm. Realized the previous patch only worked on `shipping_profile`

corentin.crouvisier’s picture

@andyg5000 #294 patch not working on last drupal commerce (dev-2.x f75e72f)
Thank you for your job.

andyg5000’s picture

I just rolled it on 89416888f03e18063b4a665a9b2ae54f2d061745. Should be fine if you fetch latest.

corentin.crouvisier’s picture

I confirm that patch is well applied on 8941688.
I have a required field form error for all my address fields in combination with commerce_stripe when I choose a new payment mode credit card (even though I already have saved cards that are offered) if I insert card informations and I submit form without changing default address.
That returns a required field form error message for all my address fields.

Edit:
The commerce_profile_select render element is empty for all address fields exept the country but extra fields from profile are completed.
If I change the billing_profile and after I select the default profile, address is entirely loaded.

nickvanboven’s picture

Tested the patch and if everything is filled correct it goes well, The problem i have know i have 2 profiles that are already in use, if i chose to create a new 1 and forget the phone number field for example or postcode i get an error which is good but the form goes away.
the select input stays on: + Enter a new address and i get an overview of my default address, if i unhide the form i see the values and the errors

Looks like the code below could be the problem it never returns a selected profile not initial and not on form submit

     // Handle a form rebuild and grab the selected profile value.
    $selected_available_profile = $form_state->getValue(array_merge($element['#parents'], ['available_profiles']));

     //something like this fixes the isseu for me with this specific form but i am sure this isnt the way to go

    $input = $form_state->getUserInput();
    $selected_available_profile = $input["payment_information"]["billing_information"]["available_profiles"];
Thomas Cys’s picture

The latest patch does not work with commerce_shipping and when you registered a new account during checkout. You constantly get an "Illegal choice has been detected" error and cannot proceed.
See https://www.drupal.org/project/commerce_shipping/issues/2948954#comment-...

bojanz’s picture

Title: Expand the commerce_profile_select form element with the ability to reuse profiles » Allow customer profiles to be reused
Assigned: Unassigned » bojanz
Category: Task » Feature request

The many problems encountered around completing this patch forced us to rethink our general approach.
The result of that has been #3003121: Add an InlineForm API, stop using complex form elements, which just landed after a full week of work.
That means that we won't use a form element anymore, we'll use an inline form plugin.

I will be rebuilding the patch from this issue in the upcoming days.
For now, I suggest staying on a patch that works for you, coupled with Commerce 2.11 or an older -dev.

Two other related issues:
#3007444: Add a way to duplicate an entity bundle
#3007446: Introduce a helper for renaming an entity bundle
This will allow us to split the "customer" profile type into "billing" and "shipping" profile types, for more flexibility.

Joao Sausen’s picture

great to hear @bojanz, thats a good decision.

s.messaris’s picture

This will allow us to split the "customer" profile type into "billing" and "shipping" profile types, for more flexibility.

Won't this make work on https://www.drupal.org/project/commerce_shipping/issues/2852207 harder? It is a much needed feature that has already been floating for quite some time.

rgpublic’s picture

> This will allow us to split the "customer" profile type into "billing" and "shipping" profile types, for more flexibility.

I also stumbled upon this sentence and I wonder what consequences that might have. Apart from the "Use shipping as billing (or vice-versa)" functionality that s.messaris mentioned, there might e.g. also be issues with the customer area / address management. Currently, each customer can easily manage their stored addresses, delete some of them, add new ones. I think it would be very inconvenient to have completely separate management for billing and shipping addresses with lots of duplicated addresses, because they usually tend to overlap, right?

mglaman’s picture

RE: #302: This actually allows us to follow the paradigms from 1.x, where this is implemented. So I do not think it makes it harder.

RE: #303: That is a valid question. But two types also solves the question of "How do I ask for a shipping phone number?" Most users seem to want it as a shipping profile field versus a shipment field.

rgpublic’s picture

Hm, although I understand why people like to attach a phone number in case of shipping problems etc, there are obviously other solutions to that (adding it, as you said, as a shipment field, or simply using the billing field, because AFAICT usually people tend to have one phone number for all questions etc.). OTOH, completely separating the profiles makes the address management a mess in terms of usability. Lots of duplicated addresses etc. To be honest, I guess the best ("gold standard") solution would be: Allow profile fields to be configurable (show only for billing, show only for shipping, show for both). This would bring together the best of both worlds...

drupalnesia’s picture

Does this patch care about "Allow multiple profiles=No" in Profile settings?
If user set Single Profile then Commerce must automatically fill the form, no need to choose any Profile.

matthieuscarset’s picture

Thanks everyone for the effort put into this issue.

I have gone throught the whole comment threads and I also try to read the attached patchs.
It is unfortunately not clear which patch(s) is(are) necessary as of today.
Could you please clarify?

Also, I'd like to understand why are we updating the Form values throught Javascript ?
This doesn't sounds a bullet-proof solution to me, as we can't rely on CSS class to populate the form... can we?
I think we need to consider that developers might need to use the `commerce_profile_select` in their own modules/own checkout panes with custom markup.

h1nds1ght’s picture

Hi,

I also used the old patches for reuse profile and the same as billing checkbox. Unfortunately they didn't apply anymore on commerce >= 2.4. Therefore I tried one of the new patches for both, but they didn't work - my site crashed. Since I have code which is dependend on these patches I had to made a decision. Either keep it or remove it. I decided to give rerolling a chance and finally I got these old patches to work with commerce >= 2.10. What I did was increasing the commerce version step by step and crossing fingers patches would apply. If not I took a look on the reject files and implemented the non applying parts again. In my first tests everything works as before with commerce 2.11. I have included them with composer this way:

            "drupal/commerce": {
                "reverse profileSelect change to allow PR 760": "https://www.drupal.org/files/issues/2844920-reverse-profileSelect-temp-fix.patch",
                "reuse profiles": "https://www.drupal.org/files/issues/2019-01-19/760-2.10.patch",
                "reuse profiles enhanced": "https://www.drupal.org/files/issues/2019-01-19/57c11175d279fe55db9454b4274608195211aeb8-2.9.patch",
                "checkbox same as billing": "https://www.drupal.org/files/issues/2019-01-19/checkbox-same-as-billing-2852207-69-2.6.patch"
            },

I hope this helps someone else having the same problems.

s.messaris’s picture

Hi all, any news on this?

csedax90’s picture

is there any news about the implementation? we have to launch an ecommerce shortly and we would like to understand whether to apply the latest patches or wait for the final implementation...

themic8’s picture

Issue: that after anonymous users check out and admin updates the order. The billing address disappears. Only for anonymous users/orders. Each time the order is saved a new billing profile is created. This does not occur with users that have an account or non-anonymous users.

Current commerce 8.x-2.11 version. Not sure which version the project started on.
Patches:

 "drupal/commerce": {
                "reverse profileSelect change to allow PR 760": "https://www.drupal.org/files/issues/2844920-reverse-profileSelect-temp-fix.patch",
                "reuse profiles": "https://www.drupal.org/files/issues/2019-01-19/760-2.10.patch",
                "reuse profiles enhanced": "https://www.drupal.org/files/issues/2019-01-19/57c11175d279fe55db9454b4274608195211aeb8-2.9.patch",
                "checkbox same as billing": "https://www.drupal.org/files/issues/2019-01-19/checkbox-same-as-billing-2852207-69-2.6.patch"
            },

Looks like this might be a different issue. Each time I save the order the billing profile gets set:
$element['#value'] == '_new'

jwwj’s picture

I could not get the patches suggested in #308 to apply on commerce 8.x-2.12 or 2.x-dev. Tried applying them all at once and one by one, but none of them got applied. The combination of my other dependencies blocks me from installing 2.11 and trying to apply these patches to see if the change happened between 2.11 and 2.12 ...

Is there some command that can tell me more details about why a patch does not get applied, what the conflict was?

s.messaris’s picture

@bojan, is this issue being worked on, now that the issues you mentioned in #300 have all been solved?

Jons’s picture

h1nds1ght’s picture

@themic8: Not sure if these patches ever catched the case of reusing anonymous profiles, since a profile should be always connected with a uid. I always used it with authenticated users and this still works in 2.11

@jwwj: The patches in #308 wont work in commerce >= 2.12. Commerce implemented inline form API in 2.12. So I think this will be EOL for these patches and we have to wait until something similiar will be available on future releases of commerce (see also #300)

bgronek’s picture

@bojanz How is this issue coming along? Is there anything we can help with?

Thank you so much for your work on this.

Martijn de Wit’s picture

I think all/partly work is done here: #3022850: [Addressbook, part 1] Rework the ownership model for customer profiles. (and it's follow up's)
Just as @jons already mentioned here above.
See also the issues that are referencing to this post.

bojanz’s picture

As most of you have seen by now, the work was split into multiple issues.

The main one landed on May 14th: #3022850: [Addressbook, part 1] Rework the ownership model for customer profiles.
We followed up with several API improvements:
#3055035: Finalize the AddressBookManager service
#3065400: Allow AddressBook::copy() to update address book profiles
We also tagged Address 1.7 (June 4th) and Profile 1.0-rc5 (June 7th) with needed bug fixes and improvements.

The next patch is now up at: #3053165: [Addressbook part 2] Complete the UI by allowing choice between multiple addressbook profiles. It represents weeks of effort. Please review the screenshots and test the code if you can.
We're also working on improved user pages in #3059633: Provide a better addressbook UI for the user pages. Both of these should land soon and be included in the 2.14 release.

bojanz’s picture

Status: Needs work » Fixed

I am marking this issue as fixed because all relevant issues have been fixed:
#3053165: [Addressbook part 2] Complete the UI by allowing choice between multiple addressbook profiles
#3072083: Allow any profile type to be used as a "customer" profile type
#3059633: Provide a better addressbook UI for the user pages
#3060433: Provide a way to collect all order profiles (billing, shipping, etc)
#3075282: Introduce alter hooks for inline forms
And unlike the D7 address book, this UI is fully available in the admin pages as well, which took a ton of additional time.
The 2.14 release will be out within 24h, along with a blog post. Last chance to find a bug!

Do note that you'll need to update Profile, Shipping, and possibly your payment gateway (e.g. Authorize.net / Stripe / Braintree).
The payment gateway update will also give you access to the per-gateway setting for not collecting billing information.

Since July 8th we've done numerous followups and fixes to the implementation.
The profile module has also seen an RC6 and finally a 1.0 release.
The Shipping module has been updated to support the address book, and now allows specifying a profile type per shipment type.

This means that you can continue to use the "customer" profile type for both billing and shipping (which is still the primary and more common use case), or you can go to admin/config/people/profile-types, click Duplicate and create a customer_shipping profile type, then select it for your shipment type. The "Address book" tab will automatically update to show separate fieldsets for billing and shipping information.

Thanks to everyone who helped this long and hard effort.

EDIT: Created a change record here: https://www.drupal.org/node/3078258

rgpublic’s picture

Absolutely amazing that this is finally fixed. IMHO literally one of the most important "bug" fixes in recent years. I lost track on how many gray hairs I got due to this. After every minor Drupal Commerce upgrade: patches, patches that didn't work, more patches for Commerce shipping which were incompatible with other patches. Nightmare on patch street (TM). Thank you so much @bojanz for working on this. *Fireworks*

Status: Fixed » Closed (fixed)

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