Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/OCA/calendar/llms.txt

Use this file to discover all available pages before exploring further.

The resource_booking module is built around three core models. A booking type (resource.booking.type) defines the rules — duration, scheduling calendar, available resource combinations, and reminders — for a category of reservations. A booking (resource.booking) represents a single reservation request made by one or more attendees, optionally linked to an auto-managed calendar.event. A combination (resource.booking.combination) groups one or more resource.resource records that must all be free simultaneously for the booking to be schedulable. Four Odoo base models are also extended to integrate with the booking engine.

resource.booking

Technical name: resource.booking
Inherits: mail.thread, mail.activity.mixin, portal.mixin
Description: Resource Booking
Default ordering: start DESC

Key Fields

type_id
Many2one → resource.booking.type
required
The booking type that governs this booking’s duration, calendar, combinations, and reminders. Deletion of the type cascades to all its bookings (ondelete="cascade").
combination_id
Many2one → resource.booking.combination
The resource combination reserved for this booking. Computed and auto-assigned when combination_auto_assign is True and a start date is set. Can be set manually when combination_auto_assign is False.
combination_auto_assign
Boolean
When True (default), the system automatically selects the best available combination each time start changes. When False, the user picks a combination manually and the engine honours that choice.
partner_ids
Many2many → res.partner
required
People who will attend this booking. At least one partner is required. The first partner is surfaced as partner_id (computed, non-stored).
user_id
Many2one → res.users
The organizer of the booking. Defaults to the current user at creation time. Synced from the linked calendar.event when a meeting exists.
start
Datetime
Booking start date/time. Computed from meeting_id.start when a meeting exists; stored so it can be indexed and searched.
stop
Datetime
Booking end date/time. Derived from start + duration. Stored and indexed.
duration
Float
Length of the booking in hours. Defaults to type_id.duration. Synced from the linked calendar.event once a meeting exists.
meeting_id
Many2one → calendar.event
The calendar event linked to this booking. Lazy-created by _sync_meeting() the first time a start date is set; destroyed when the booking is unscheduled or canceled. Unique per booking (UNIQUE(meeting_id) SQL constraint).
state
Selection
Workflow state of the booking. Stored and tracked.
ValueLabelMeaning
pendingPendingNo meeting scheduled yet.
scheduledScheduledMeeting exists but attendee has not confirmed.
confirmedConfirmedMeeting exists and requester accepted the invite.
canceledCanceledBooking archived; meeting removed.
is_modifiable
Boolean (computed)
False when is_overdue is True and the current user is not in the resource_booking.group_manager security group (or is accessing via the portal). Managers can always modify overdue bookings.
is_overdue
Boolean (computed)
True when the current time has passed start − type_id.modifications_deadline hours. Always False when no start date is set.

Methods

_check_scheduling()

@api.constrains("combination_id", "meeting_id", "type_id")
def _check_scheduling(self):
Validates that every scheduled booking (one with a meeting_id) fits inside the work intervals of both its booking type’s resource_calendar_id and its combination_id. Raises ValidationError when:
  • A booking has a meeting but no combination with resources.
  • A booking’s (start, stop) window is not fully contained within any single contiguous available interval (as computed by _get_intervals()).
Already-elapsed bookings (stop < now) are exempt from this check.

Auto-assignment Algorithm

When combination_auto_assign is True and start changes, _compute_combination_id() calls _get_best_combination(), which:
  1. Puts the currently selected combination first in the candidate list (highest priority).
  2. Appends all other combinations linked to type_id, ordered by the type’s combination_assignment strategy (sorted by sequence, or random).
  3. Returns the first combination for which _get_intervals(start_dt, stop_dt, combination) returns an interval that fully contains the booking window.
When called from the portal (using_portal context key), the method raises a ValidationError if no combination is available, giving the end user immediate feedback.

_sync_meeting() (internal)

Lazy-creates or destroys the linked calendar.event whenever start, stop, duration, or related fields change. Called automatically from create() and write(). Uses syncing_booking_ids context to prevent recursion between the booking and the event.

resource.booking.type

Technical name: resource.booking.type
Inherits: mail.thread, mail.activity.mixin
Description: Resource Booking Type

Key Fields

name
Char
required
Display name of the booking type. Translatable and indexed.
duration
Float
required
Default booking duration in hours. Must be positive. Defaults to 0.5 (30 minutes).
slot_duration
Float
required
The step size in hours between consecutive available start slots shown to the requester. Defaults to 0.5 (30 minutes). A value of 1.0 with a duration of 0.5 means slots are offered every hour on the hour.
modifications_deadline
Float
required
Number of hours before start after which unconfirmed bookings can no longer be modified by non-managers. Defaults to 24. Also used to exclude near-future slots from the availability calendar shown to portal users.
resource_calendar_id
Many2one → resource.calendar
required
The work schedule that governs when bookings of this type may be placed. Defaults to the company’s default resource calendar. Used as the outer bound for availability calculations.
combination_assignment
Selection
required
Strategy for auto-assigning combinations.
ValueLabel
sortedSorted — always picks the combination with the lowest sequence number first.
randomRandomly — shuffles candidates on every evaluation; default.
alarm_ids
Many2many → calendar.alarm
Default reminders added to every calendar.event created for bookings of this type.
categ_ids
Many2many → calendar.event.type
Default event tags applied to meetings created for bookings of this type. Copied to resource.booking.categ_ids when the type changes.
requester_advice
Text
Free-text guidance shown to the requester in portal invitation emails and the scheduling calendar view. Translatable. Also copied as the default description of new calendar.event records.
company_id
Many2one → res.company
Company scope. Defaults to the current company.

resource.booking.combination

Technical name: resource.booking.combination
Description: Bookable resource combinations
A combination is a named grouping of one or more resource.resource records that must all be simultaneously available for a booking to succeed. A single resource (e.g. a meeting room) is a combination of one. Multiple resources (e.g. a doctor + an examination room) form a combination of two.

Key Fields

resource_ids
Many2many → resource.resource
required
The resources that must be free together. The combination is only schedulable in time windows where every one of its resources has a free work interval.
forced_calendar_id
Many2one → resource.calendar
When set, this calendar is used instead of each individual resource’s own calendar_id for availability calculations. Useful when resources belong to different schedules but must be treated as a single unit.
name
Char (computed, stored)
Auto-generated from resource names joined with " + ". When a forced_calendar_id is set, the calendar name is appended in parentheses: "Resource A + Resource B (using calendar Weekly 40h)".

Methods

_get_intervals(start_dt, end_dt, tz)

def _get_intervals(self, start_dt, end_dt, tz):
Computes the intersection of all resource work intervals within [start_dt, end_dt]. Steps:
  1. Starts with the full [start_dt, end_dt] interval as a base.
  2. For each resource.resource in resource_ids, fetches its work intervals via calendar._work_intervals_batch() (using forced_calendar_id if set, otherwise the resource’s own calendar_id).
  3. Converts intervals to the requested tz timezone if it differs from the calendar’s timezone.
  4. Intersects (&=) each resource’s intervals with the running result.
  5. Unions (|=) the final result for multi-combination recordsets.
The method runs with exclude_public_holidays=True context to honour the hr_holidays_public integration when that module is installed.
Pass analyzing_booking=<booking_id> in the context (done automatically by resource.booking._get_intervals()) to exclude the booking’s own existing meeting from the busy-time calculation, preventing false conflicts during reschedules.

Extended Models

The module extends four Odoo base models to integrate with the booking engine.

calendar.event

resource.calendar

resource.resource

res.partner

Build docs developers (and LLMs) love