Problem/Motivation

A venue section can only be sold as numbered places. Selling the same section unreserved (free seating, or standing) is a common case: a hall plays one event with an assigned parterre and another with a standing floor, while its balconies stay seated in both. Today the only way to express that is a second venue, which duplicates the whole inventory.

The axis is not posture, it is whether positions are assigned. An unreserved seated section and a standing hall behave identically for booking: a capacity, and no named place. So the mode is placed or pooled, and whether people stand or sit is prose for the buyer. Keeping "standing" out of the schema also avoids a name that dates the first time an unreserved seated balcony is modelled.

Proposed resolution

The mode is a property of the event, not of the venue, since the same section is placed for one event and pooled for another. It therefore belongs on the configuration, the entity that already carries per-event layout.

  • A configuration stores its deviations as section settings (yoyaku_configuration_section): one decision per area, addressed at a whole section or one subsection of it, saying placed, pooled or closed, plus a pool capacity and a pool grade. This replaces closed_sections and closed_subsections, whose "section id:number" string format only existed because there was no per-area record to hang the number on.
  • Section gains an optional default mode, so a normally standing hall states it once instead of in every configuration. The mode of an area is resolved, most specific first: the setting for its own subsection, else the section-wide setting, else the section default, else placed.
  • A pool's capacity is the one its setting declares, else the number of places the area holds. A declared capacity is only needed where the places were never modelled, a true standing hall.
  • A pool's grade is the one its setting declares, else the grades of its places. A tariff prices grades, so this is what lets a tariff price a pool: an area holding no places can only be priced by declaring one, and a declared capacity covering places of several grades requires it.
  • The placement provider grows one branch: places for a placed area, lines carrying the section (and the subsection when the pool is one slice) and no place for a pooled one. A mixed venue produces both in one booking, places first.
  • Availability gains a pool bound: the capacity minus everything consuming that area.
  • PlaceBookable correctly ignores a pooled line, since there is no place to protect. SectionPoolBookable bounds it by the pool under the slot lock, counting both the pooled lines naming the area and the placed lines whose places sit inside it. That second half is what makes an area safe to pool after some of its places were sold assigned.

Remaining tasks

Both halves are in: the model with the booking path, and the picker. A pooled area is one block with a quantity beside the seats, and a venue selling only pools has a picker without a map.

User interface changes

A configuration gains an Areas tab listing the areas it decides about, one row per area with edit and delete, and an add button under them. Adding one asks for the area as a single choice, listing the sections of the venue and the subsections its places carry; an area the configuration already decides about is not offered. The mode is placed, pooled or closed, and the pool capacity and grade appear only for a pooled area.

On the picker, a pooled area is one block naming the area, saying how many units are left and stepping a quantity up and down; each step goes through the same endpoint a seat click uses, so the pool bound still applies under the slot lock.

API changes

A booking line for a pooled area carries a section reference and a subsection number instead of a place. Configuration::getClosedSectionIds(), getClosedSubsections(), isSectionOpen() and isSubsectionOpen() are gone; SectionSettings resolves an area's mode instead.

Data model changes

New yoyaku_configuration_section entity. Section: default_mode. Booking: section, subsection. Configuration: closed_sections and closed_subsections removed.

Issue fork yoyaku-3613507

Command icon 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

mably created an issue. See original summary.

mably’s picture

Status: Active » Needs review
mably’s picture

Issue summary: View changes

  • mably committed cb937422 on 1.x
    feat: #3613507 Sell a section as a pool: a per-event section mode (...
mably’s picture

Status: Needs review » Active

mably’s picture

Issue summary: View changes
mably’s picture

Status: Active » Needs review

  • mably committed 3e61cb5d on 1.x
    follow-up: #3613507 Sell a pooled area from the picker: one block with a...
mably’s picture

Status: Needs review » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.