Problem/Motivation
When editing a shipment on an order that was placed by an anonymous customer clicking the "Recalculate shipping" button causes the shipping address to be blanked out. This bug was introduced in version 2.2, specifically #3242737: Shipping profile element doesn't work with recalculate on admin shipping form
Steps to reproduce
Have at least commerce_shipping version 2.2 installed
Create an order assigned to anonymous. Create a shipment for that order and save it. Go back to edit the shipment. Click the "Recalculate shipping" button. The shipping address disappears. Saving the shipment saves an empty address. Abandoning the changes and coming back to the shipment edit screen the address is present so the underlying profile is not being modified until saving the shipment.
Proposed resolution
Currently doing further debugging to determine the cause, though I suspect it's because the form is being rebuilt and for whatever reason the code path that sets an empty address is being triggered instead of reusing the existing profile like what happens when the form is initially loaded.
Comment | File | Size | Author |
---|---|---|---|
#4 | 3350321-recalculate-blanks-shipping-address-in-admin-4.patch | 885 bytes | rhovland |
|
Issue fork commerce_shipping-3350321
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
rhovland CreditAttribution: rhovland commentedI've tracked this down to the following code block being removed.
https://git.drupalcode.org/project/commerce_shipping/-/commit/3f492dc441...
If I restore that then the regression goes away.
Comment #3
rhovland CreditAttribution: rhovland commentedThe issue is that for whatever reason $address is empty even where there is a shipping profile already attached to the shipment. This happens when the order is owned by anonymous. Oddly this does not happen when the order is owned by a user, even if they have no shipping addresses in their address book and it's only the address stored on the shipment.
This is also a problem if a shipping profile is attached to the shipment during building of the form (via custom code) and the address is blown away by the recalculate button regardless of ownership of the order.
Comment #4
rhovland CreditAttribution: rhovland commentedHere's a patch that "fixes" the problem by not touching the profile if the address is NULL.
The real fix will be figuring out why $address is empty and fixing that.
Comment #7
tBKoT CreditAttribution: tBKoT at Lemberg Solutions commentedThis patch is only to check failing test
Comment #8
tBKoT CreditAttribution: tBKoT at Lemberg Solutions commentedComment #9
tBKoT CreditAttribution: tBKoT at Lemberg Solutions commentedComment #10
jsacksick CreditAttribution: jsacksick at Centarro commented@tBKoT: Please update an existing test, no need to define a new one, let's just expand ShipmentAdminTest. Besides, the tests-only patch doesn't seem to apply.
Comment #11
tBKoT CreditAttribution: tBKoT at Lemberg Solutions commentedComment #12
rhovland CreditAttribution: rhovland commentedAfter spending time in the debugger and testing different scenarios I'm pretty sure I know what is wrong and needs to be fixed.
Setting the selected_profile_id for anonymous users technically works but is the wrong approach here. We only need to trigger the code that updates the current shipment profile when the selected profile changes. Since an anonymous order will never have a choice of profiles to select there is no reason to update the profile.
What does need to happen is if the user clicks the edit button and changes the address. The shipment profile does need to be updated with the changes before rate recalculation or you won't see updated rates. This will not happen because that was what `if ($address !== NULL) {$shipment->getShippingProfile()->get('address')->setValue($address);}` was intended to do and invoking the profile selection path will wipe out those changes.
So the following code will update the shipment profile if an address has been entered or edited in the address form.
If the address edit form is not open ($address is NULL) then it moves on to the next check where it looks at the selected profile id. If there is a selected profile id it updates the shipment address using that. It will be NULL on anon orders and users with only one profile because there is no select_address form. There is no need to update the shipment profile in that case, because it is already current.
Tested with the following scenarios:
Any scenarios I missed?
Comment #13
rhovland CreditAttribution: rhovland commentedOops I left in some commented out code in that sample. This part needs to be removed
Comment #14
tBKoT CreditAttribution: tBKoT at Lemberg Solutions commentedComment #16
jsacksick CreditAttribution: jsacksick at Centarro commentedCommitted, thanks everyone!