Problem/Motivation
I have 2 variations for each event: online and in-person. It makes sense to have them as 2 variations, linked to 2 registration types, because they need different fields.
Unfortunately I can be sure that soon enough some user is going to want to change their mind about which variation they want to be, after they have completed checkout and registered. This seems like a pretty common requirement.
Proposed resolution
Phase 0: What works already
The good news is that we can set the existing registration on a new order item, and the registration checkout panes look like they will behave reasonably well; for example, RegistrationProcess won't create a new registration if one is already set on the order item.
Phase 1: Changing the registration type
A. Add a method updateRegistrationHost(RegistrationInterface $registration, EntityInterface $host_entity, $delete = TRUE){} to RegistrationManager. This method clones the existing registration as a new registration of the appropiate registration type, copying across all fields we can, optionally deletes the old registration, and returns the new registration.
B. In the RegistrationInformation pane's getItemRegistration() method we need to change it so that if the existing registration on the current order item is referenced from another (old) order item with a different purchased entity that references a different registration type, then we invoke RegistrationManager::updateRegistrationHost().
Phase 2: UI for initiating change of type
When viewing or editing an registration, it would be good to offer a way to change the registration variation. For one's own registration, that would initiate a new order to go through the checkout with a new item referencing the existing registration as above; for someone else (i.e. for staff managing registrations) it would need to streamline editing the new registration and deleting the old one, without initiating a checkout.
This is tricky. The best solution I can think of is:
A. Add a RegistrationHostUpdateForm and route that takes an old registration and new host as parameters, and then allows editing a new registration that is a clone prepared by RegistrationManager::updateRegistrationHost(). When the form is saved, the old registration is deleted.
B. Add an extra field to the form display that shows a select list of hosts to choose between.
C. Fire an event to gather options for this select list. Commerce registration could subscribe to this event and add the other variations of the same product.
D. For each host option, determine whether it has a different registration type to the current host; if it does, prepend an underscore to the option name.
E. If the extra field is present and the user selects an option prepended with a underscore, use #states to hide all other fields and buttons except a "Change registration type" button.
F. Pressing that button takes you to the form in A (for staff) or checkout (for customers).
Phase 3: Extra payments and refunds
If you change the variation you've registered for, mayb you need to pay more, or maybe you need a refund. I'm not familiar with how best to handle this stuff in commerce and it sounds tricky.
I'm happy to work on phase 1, and phase 2, but not phase 3. I think phase 1 and 2 are good improvements on their own.
Remaining tasks
Decide on approach.
Create subissues.
Code.
User interface changes
TBD
API changes
TBD
Data model changes
TBD
Issue fork commerce_registration-3379085
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
jonathanshawComment #3
jonathanshawComment #4
jonathanshawI have started working on a submodule registration_change_host adding basic APIs for supporting this use case, will share when it's more ready.
Comment #5
john.oltman commentedThanks Jonathan!
Since this will live in the registration module, and is a duplicate of https://www.drupal.org/project/registration/issues/2503273, would you be able to copy your notes to that issue and ultimately post the MR or patch to that issue? I would then close this one as a duplicate. If that makes sense to you.I linked the related issue in the Registration module, please post the MR or patch to that issue for the piece that will live there, and an MR or patch here for the Commerce Registration piece.Comment #6
john.oltman commentedIf commerce registration gets an MR or patch also, then maybe we keep both open. Re-reading your issue, it looks like CR will also get some code for an event subscriber eventually.
Comment #7
jonathanshawYes, this needs an event subscriber using registraton_change_host.
Comment #9
jonathanshawComment #10
john.oltman commentedCode looks good generally - the branch is old, can you merge 3.1.x into it, that should help get the pipeline to succeed.
Comment #11
jonathanshawThe residual issue I'm aware of here is I'm not sure what cacheability I need to add for $host_entity->isConfiguredForRegistration().
This may be a good example of why #3497735: HostEntity should implement CacheableDependencyInterface is helpful.
Comment #12
jonathanshawComment #13
john.oltman commentedLet's rework this to follow the existing pattern of having its own submodule, dependent on registration_change_host in its .info file. This is cleaner and allows more separation of its tests, its own README etc. I changed the Version on this issue to 3.4.x, but ultimately it should be able to merge into both 3.1.x and 3.4.x of Commerce Registration.
Comment #14
john.oltman commentedComment #17
john.oltman commented