On a placement (seatmap) slot, a category's "free" comes from its own quota (the slot_category capacity) only, which ignores that several price categories share the same physical grade. Two categories pricing the same grade (for example "Plein tarif - Catégorie 1" and "Tarif jeune - Catégorie 1", both grade "Catégorie 1", 825 seats) each show their own free, so booking 4 seats leaves the first at 821 but the second still at 825, overstating real availability.
The free value for a category on a slot should be the minimum of two bounds: the remaining category quota (capacity minus its consuming bookings), and the free physical seats in the grade(s) the category prices (shared across every category pricing that grade). In the example both "Catégorie 1" rows would then read 821.
The engine BookingManager::availability() is currently physically blind: it bounds by tier quota and slot capacity only, and the seatmap is enforced solely at place selection. Proposed fix: add an availability-bound seam (a tagged service that, given a slot and category, returns an optional cap), have availability() and availabilityMap() take the min of the quota bound and every provider bound, and let yoyaku_placement register a provider returning the free seats of the category grades (with a batch variant for availabilityMap). The slot overview then shows this honest number and keeps its own aggregate only for the confirmed/completed/held breakdown. This also makes the booking flow availability truthful. Builds on #3613133.
Issue fork yoyaku-3613137
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 #3
mably commentedComment #5
mably commented