Issue #3614127: Reshape the slot booking page around tariff and grade
Two parts, both on this branch. Part 1 is pushed; part 2 is in progress.
Part 1: the basket says what it contains (pushed)
SlotBookingForm::orderSummary() built its own item_list of bare place labels,
so a line read "A15" with no tariff, no area and no price, and the only total was
a bare paragraph. Worse, a printed place is unique only within its area, so on a
real venue several different seats all read "A15" and the line identified nothing.
It now renders through TransactionSummary, which already describes each line by
tariff, seat, area (added by yoyaku_placement through its summary alter) and
price, via the yoyaku_summary / yoyaku_summary_event /
yoyaku_summary_ticket theme hooks a site can override. The context
slot_booking is passed so a theme can style the basket on this page alone.
The total comes with it: pricing fills the summary through
hook_yoyaku_summary_alter(), so orderTotal() and its hand-rolled bcadd loop
are gone. An unpriced order still shows no total, exactly as before.
heldItems() stays: it names the "Held: ..." status message, a different
surface. It has the same "A15" weakness, and part 2 is the right place for it.
Part 2: the accordion (in progress)
One collapsible panel per category group, collapsed by default with one open; one card per seating grade inside; price large and right-aligned; a minus/value/plus stepper instead of a number spinner, which also removes the silently enforced maximum.
This needed a model decision first. yoyaku_placement already gives
yoyaku_category a multi-value grade reference, so "one card per grade" is
buildable today. Nothing grouped the categories themselves: what separates "Full
price" from "Youth" when both price the same grades lived only inside the
category label, and parsing labels would have invented a convention.
So part 2 adds yoyaku_category_group (key, translatable label, weight),
referenced from yoyaku_category, which is how Grade and Section are already
modeled and gives the panels a translatable heading and an explicit order.
Named a group rather than a "tariff family" on purpose: category appears 1747
times in this codebase and 128 times in the docs, and the entity labels itself
"Category". tariff appears 58 times and never as an entity name. A fourth noun
next to category, tier and grade would have cost more than it bought.
Booking fees stay out: no model behind them yet, filed as #3614129.