Some venues need per-customer booking rules that the engine cannot express, because they key off the customer identity, and the engine has no notion of a customer: that lives at the order layer (the email on the transaction). Examples: one booking per person per slot, or a ticketing cap of N tickets per buyer per session.
Proposed resolution
Introduce an order-layer constraint system, the counterpart to the engine's hold-time BookingConstraint, and ship the first rule.
- An OrderConstraint plugin type in yoyaku_order: the #[OrderConstraint] attribute, OrderConstraintInterface (check(OrderInterface): ?string), a base class, and a tagged OrderConstraintManager with a public validate(OrderInterface): string[] that runs every registered rule. Adding a rule is adding a plugin.
- A per-resource policy field max_per_customer (integer, zero means no limit) on BookingResource, alongside refund_deadline and auto_confirm.
- The default rule, slot_per_customer_limit: self-gating per resource, it only bites on slots whose resource sets a limit, and counts the customer's active (held or confirmed) bookings for the slot across every order sharing the order's email, violating once the count exceeds the limit. A limit of one is "one booking per person per slot"; a higher limit is the ticketing cap.
- Enforcement: OrderManager::confirmOrder() validates before confirming and throws on a violation, and OrderManager::validateOrder() exposes the check so any consumer (a registration form, an API) can pre-check.
Tests
OrderConstraintTest covers the manager, the default rule, and the cases: no limit by default, one-per-slot refusing a second order, different emails not colliding, and a ticketing cap of N.
Follow-ups
A registration-form pre-check (calling validateOrder so the customer is stopped on the form before payment) and a resource-type exclusivity rule ("one refuge among all refuges") build on this and land separately.
Issue fork yoyaku-3609485
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 commentedMR !11 opened.
Comment #5
mably commented