Issue #3616324: Make a booker acknowledge places that are not side by side

Adds the acknowledgement described in the issue, with two departures from the summary that came out of design review and that the summary now needs to reflect.

Where it is asked. On the cart page, inside each event's own card, immediately above the Checkout button. Not at the payment step: that page comes after the registration form, so a question there would have the booker fill their details in and only then learn their seats are apart, and a booking that owes nothing never reaches a payment step at all.

How a rule asks. One interface in the engine, CheckoutInteractionInterface. A constraint policy that needs the booker to answer something implements it, and AttachedPolicies — moved up from yoyaku_placement and now the one reader for every seam a policy publishes — finds it from the cached plugin definitions, so a basket of ordinary bookings builds no plugin at all. Attaching the policy is the switch: being asked and being enforced are one setting.

Per session, not per order. The rule hangs on a resource, so a basket holding two evenings in two houses may be asked about one of them, about both in different words, or about neither, and a booker seated apart at two houses ticks two boxes. Apart is PlaceGeometry::fragments(), the grouping the seating strategies already use, so the picker's notice and the cart's question cannot mean different things.

The button is held back with core's #states, never #disabled: core ignores a disabled element's posted value, and a button disabled server-side would lock out a booker with no JavaScript for good. The conditions key on each control's own wrapper class rather than on an input name, because where in the form tree a card puts it is the surface's business. With no JavaScript the button stays live and #required refuses it on the server.

The seat map loses its own Checkout, along with the op, the endpoint method and the library behind it. The cart is the one place a basket is committed, because it is the one place a rule gets to stand in the way, and a second way to commit would be a way around it. That also ends yoyaku_placement's reach into yoyaku_cart's event class, part of #3616250.

Provisional: the question renders white on red, from a component stylesheet keyed on one class with the two colors in custom properties, so a theme overrides it on order alone. Marked as provisional in the file and deletable in one edit.

Docs and the French translation are in the same commit. Tests: PlacesApartTest (the measurement, per session), PlacesApartPolicyTest (the question and ask_chosen), CartPlacesApartTest (the real cart page, including two evenings giving two boxes). Every new test was seen to fail against unfixed code first; breaking the per-session grouping fails two of them in both directions.

Merge request reports

Loading