Order constraints are pluggable, but each rule was turned on by a bespoke field: max_per_customer on the resource, exclusive_per_customer on the type. That does not scale: every new rule means another field and another checkbox, and the type flag was all-or-nothing (it could not say "these resources compete, those do not"). Constraints should instead be policies you select and configure where they apply.
Proposed resolution
Make each order constraint a configurable, attachable policy, and attach one or more of them to a resource or a resource type through a Policies tab, the same shape as the Categories tab.
- OrderConstraint plugins become configurable: each carries settings and renders its own settings form (ConfigurableInterface plus PluginFormInterface), and check() receives the host resource.
- Policies are stored on the host: a resource keeps them in a field, a type in its third_party_settings, read and merged by a ConstraintPolicyResolver. Type-level policies apply to every resource of the type; a resource adds its own on top.
- A Policies tab on the resource and on the resource type lists the attached policies and adds, edits or removes them, picking a plugin and filling its settings form.
- The manager runs the merged policies per order line, always counting within the order's tenant.
Shipped policies
- slot_per_customer_limit (max): at most max active bookings per customer for a single slot of the resource (1 is one per person, higher suits ticketing).
- single_active_per_group (group, max): at most max active bookings per customer across every resource sharing the group name. The group is a plain string, so competing resources share it and an exception omits it. This replaces the type exclusivity flag: "one refuge among all refuges" is this policy with group refuges and max 1 on the refuge type.
The bespoke max_per_customer and exclusive_per_customer are removed, replaced by configured policies. This builds on the resource type work in the preceding issue.
Tests
Kernel coverage for the slot limit and the group exclusivity (attached to a resource and to a type), per-customer isolation, cross-tenant isolation, and a non-member coexisting. A functional test drives the Policies tab: the overview renders, and adding a policy through its plugin form persists it. Docs and the French translation are updated.
Issue fork yoyaku-3609560
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 commentedOpened a merge request making order constraints configurable, attachable policies: each OrderConstraint plugin carries settings and its own form, and one or more are attached to a resource or a resource type on a Policies tab (stored in a resource field and the type third_party_settings, merged by ConstraintPolicyResolver and run per order line within the order tenant). Ships slot_per_customer_limit and single_active_per_group, removes the bespoke max_per_customer and exclusive_per_customer. Kernel and functional test coverage, docs and the French translation are included.
Comment #5
mably commented