Problem

A slot's offers are presented in a shape nobody chose. Two separate faults, both visible on one booking page.

1. The class panels render empty

Tariffs naming a tariff class should be offered in one collapsible panel per class. The page renders the panels, then renders every quantity field flat above them: seven offers in a list, followed by two empty accordions.

The cause is the mechanism, not the data. Each field carried #group pointing at its panel, and #group only relocates an element whose type carries core's processGroup(): that is details and its relatives. A number has neither processGroup() in its #process nor preRenderGroup() in its #pre_render, so it never registers with the group and the group never absorbs it. The property was set and did nothing, and it never worked. The test asserted that #group held the expected string, which stayed true the whole time the page was wrong.

2. The order is a tie-break, and the two pages break the tie differently

A resource's Tariffs tab lists them weight then label. The engine's own read, which the booking page follows, sorts by weight alone. Every tariff of a freshly priced production has weight 0, so the database returns them in an arbitrary order, in practice by id.

The same seven tariffs therefore appear in two different orders, and neither is the one an operator picked, because there is no way to pick one: the weight field exists on the entity and nothing offers it. On a hall priced Cat. 1 to Cat. 4 that is not cosmetic, since the offers are read top to bottom and the cheapest lands in the middle.

Proposed resolution

The panels

Render the field inside its panel and pin its value path, so the submitted tree is unchanged:

  • a field naming a class goes to $form['panels'][<class>][<tariff>] with #parents of ['quantity', <tariff>], so reconcile() keeps reading quantity][<tariff>;
  • a field naming no class stays under quantity, above the panels, as it already did.

The AJAX refresh has to learn the new shape: it walked the children of quantity to build one entry per offer, so a panelled offer would have gone silent, its card never told what it now holds. One accessor returns the offer fields from both places, rather than each caller walking them.

The order

  • The Tariffs tab becomes drag and drop, writing weight on each row, so the order is a decision. Weights are recalculated from the dropped positions rather than typed.
  • The engine's read takes the same deterministic tie-break as the list, so two tariffs of equal weight cannot appear in one order here and another there.

A class panel keeps ordering by the class weight; within a panel, the tariffs follow the order set on the tab. So an operator arranges the tariffs once and both pages agree.

Remaining tasks

  • Nest the classed fields, pin their parents, and teach the refresh to walk both places through one accessor.
  • Cover the panels so this cannot regress silently: the field is inside the panel and not under quantity, its parents still point at the value tree, and the rendered markup puts each input inside a details exactly once. That last assertion is the one the old test lacked. Build it through the form builder, not buildForm(), which returns an unprocessed array with no #name on anything and so renders no inputs at all.
  • Cover the refresh returning both a panelled and a non-panelled offer.
  • The drag-and-drop form, with its save, and its weights recalculated from the drop order.
  • The engine's tie-break, with a test that two tariffs of equal weight come out in the same order on the tab and in the availability map.
  • Docs, and a French translation, in the same commit.

User interface changes

The offers of a class are inside that class's panel, which is what the panels were for. The Tariffs tab gains drag handles, and the order set there is the order a booker reads.

Issue fork yoyaku-3615159

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 committed 4f644b10 on 1.x
    fix: #3615159 Present a slot's offers as configured: class panels that...
mably’s picture

Status: Active » 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.