Problem/Motivation
While a booking workflow runs on a still-pending order, editing that order's basket cancels the workflow, and an emptied order is then treated as a free order. Removing or re-seating a line (through the cart, the seat map or the slot page) releases a held line, and that out-of-band release makes BookingReconciler tear the running instance down as if an operator had settled the booking. If a workflow is then started for the emptied order, BookingWorkflowStarter classifies it as free (no payment due) and routes it to the place-order step, where it dead-letters ("no line of the transaction was in a state to transition") and raises an incident.
Steps to reproduce
Book one or more seats and continue to checkout, so the workflow parks at the payment step. Go back to the seat map or the cart to start a new order and change the basket. The running workflow is cancelled, a second checkout starts a fresh instance on the emptied order, and the place-order step dead-letters.
Proposed resolution
- Stop
BookingReconcilerreacting to a release. A release only ever frees a held booking (BookingManager::release()requires the HELD state), which is the customer's editable basket, so it is a basket edit, not a settlement. An out-of-band confirm, cancel or expire still tears the instance down, and a whole-order cancel is handled by the order-driven bridge. - Make
BookingWorkflowStarterrefuse an order with no held lines. An empty order is not a free order, it is nothing to book, so it must never start a workflow and be routed as free.
Remaining tasks
- Both guards, with kernel tests.
Securing the routing so an emptied order shows a message with a way back to the form, instead of dead-lettering, is a follow-up.
Issue fork yoyaku-3613210
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 #4
mably commented